绳子算法
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(); } }; }