首页 > 代码库 > 绳子算法

绳子算法

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();
        }
    };

}

 

绳子算法