package app{
import flash.display.Shape;
import flash.geom.Point;
import framework.Game;
import framework.objs.GameObject;
public class ThrowSceneRope extends GameObject{
public static function create():void{
var game:Game=Game.getInstance();
var info:*={};
game.createGameObj(new ThrowSceneRope(),info);
}
public function ThrowSceneRope(){
super();
}
private const ptm_ratio:Number=100;//像素/米
private const gravity:Point=new Point(0,9.81);
private const dt:Number=1/30;
private const lenNode:Number=4/ptm_ratio;//绳节长度,单位:米
private const nodeCount:int=20; //节数
private const ropeInitAngle:Number=0*0.01745;//绳子初始朝向角度 单位:弧度
private var _origin:Point;//绳子悬挂点,单位:米
private var _oldPosList:Vector.<Point>;
private var _posList:Vector.<Point>;
override protected function init(info:* = null):void{
super.init(info);
_origin=new Point(473.7/ptm_ratio,257.6/ptm_ratio);
_posList=new Vector.<Point>(nodeCount,true);
_oldPosList=new Vector.<Point>(nodeCount,true);
for(var i:uint=0;i<nodeCount;i++){
var x:Number=_origin.x+Math.cos(ropeInitAngle)*lenNode*i;
var y:Number=_origin.y+Math.sin(ropeInitAngle)*lenNode*i;
_oldPosList[i]=new Point(x,y);
_posList[i]=new Point(x,y);
}
}
override protected function update():void{
step();
}
private function step():void{
verlet();
setConstraints();
_posList[0].x=_origin.x;
_posList[0].y=_origin.y;
drawRope();
}
/**重力加速度模拟*/
private function verlet():void{
for(var i:uint=0;i<nodeCount;i++){
var tmpx:Number=_posList[i].x;
_posList[i].x+=(_posList[i].x-_oldPosList[i].x)+(gravity.x*dt*dt);
var tmpy:Number=_posList[i].y;
_posList[i].y+=(_posList[i].y-_oldPosList[i].y)+(gravity.y*dt*dt);
_oldPosList[i].x=tmpx;
_oldPosList[i].y=tmpy;
}
}
/**约束绳节间的距离*/
private function setConstraints():void{
for(var c:uint=0;c<nodeCount;c++){
for(var i:uint=1;i<nodeCount;i++){
//Distance of two rope node
var dx:Number=_posList[i].x-_posList[i-1].x;
var dy:Number=_posList[i].y-_posList[i-1].y;
var d:Number=Math.sqrt(dx * dx + dy * dy);
var diff:Number=d-lenNode;
var f:Number=0.5;
_posList[i].x-=(dx/d)*diff*f;
_posList[i].y-=(dy/d)*diff*f;
_posList[i-1].x+=(dx/d)*diff*f;
_posList[i-1].y+=(dy/d)*diff*f;
}}
}
private var _shape:Shape;
private function drawRope():void{
if(_shape==null){
_shape=new Shape();
_game.global.layerMan.items2Layer.addChild(_shape);
}
_shape.graphics.clear();
_shape.graphics.lineStyle(1, 0xff0000, 2);
_shape.graphics.moveTo(_posList[0].x*ptm_ratio, _posList[0].y*ptm_ratio);
for(var i:uint=1;i<nodeCount;i++){
_shape.graphics.lineTo(_posList[i].x*ptm_ratio, _posList[i].y*ptm_ratio);
}
}
override public function destroy():void{
if(_shape && _shape.parent){
_shape.parent.removeChild(_shape);
_shape=null;
}
super.destroy();
}
};
}