In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

[study] - VERLET

詳解ActionScript3.0アニメーション
ベレ法
Get Adobe Flash player
by gaina 13 Nov 2010
    Embed
/**
 * Copyright gaina ( http://wonderfl.net/user/gaina )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/N1Ea
 */

package  
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;
    /**
     * 詳解ActionScript3.0アニメーション
     * ベレ法
     * @author gaina
     */
    public class Square extends Sprite
    {
        private var _points:Array = [];
        private var _sticks:Array = [];
        private var _rect:Rectangle;
        
        private var SIDE:int = 24;
        private var VERTICAL:int = 12;
        
        private var offsetX:Number;
        
        public function Square() 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            _rect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight - 15);
            offsetX = stage.stageWidth / SIDE / 2;
            
            //点
            for (var i:int = 0; i < SIDE * VERTICAL; i++)
            {
                var p:VerletPoint = makePoint( (i % SIDE) * stage.stageWidth / SIDE + offsetX, Math.floor(i / SIDE) * stage.stageHeight / VERTICAL);
            }
            
            var stick_side:int = (SIDE - 1) * VERTICAL;
            var stick_vertical:int = (VERTICAL - 1) * SIDE;
            var stick_num:int = stick_side + stick_vertical;
            
            //構造物
            for (var j:int = 0; j < stick_num; j++)
            {
                if (j < stick_side) {
                    //横の棒
                    var sw:VerletStick = makeStick(_points[j + (Math.floor(j / (SIDE - 1)))], _points[j + 1 + (Math.floor(j / (SIDE - 1)))]);
                }else {
                    //縦の棒
                    var sv:VerletStick = makeStick(_points[j - stick_side], _points[j - stick_side + SIDE]);
                }
            }
            
            addEventListener(Event.ENTER_FRAME, loop);
            stage.addEventListener(MouseEvent.CLICK, 崩壊);
        }
        
        private function 崩壊(e:MouseEvent):void 
        {
            _points[SIDE * VERTICAL / 2].vy = 10;
        }
        
        private function loop(e:Event):void 
        {
            updatePoint();
            updateContrain();
            updateStick();
            graphics.clear();
            renderPoint();
            renderStick()
        }
        
        private function makePoint(posx:Number, posy:Number):VerletPoint
        {
            var p:VerletPoint = new VerletPoint(posx, posy);
            _points.push(p);
            return p;
        }
        
        private function makeStick(pointA:VerletPoint, pointB:VerletPoint, length:int = -1):VerletStick
        {
            var s:VerletStick = new VerletStick(pointA, pointB, length);
            _sticks.push(s);
            return s;
        }
        
        private function updatePoint():void
        {
            for (var i:int = 0; i < _points.length; i++)
            {
                var p:VerletPoint = _points[i] as VerletPoint;
                p.y += 0.5;
                p.update();
            }
        }
        
        private function updateContrain():void
        {
            for (var i:int = 0; i < _points.length; i++)
            {
                var p:VerletPoint = _points[i] as VerletPoint;
                p.constrain(_rect);
            }
        }
        
        private function updateStick():void
        {
            for (var i:int = 0; i < _sticks.length; i++)
            {
                var s:VerletStick = _sticks[i] as VerletStick;
                s.update();
            }
        }
    
        private function renderPoint():void
        {
            for (var i:int = 0; i < _points.length; i++)
            {
                var p:VerletPoint = _points[i] as VerletPoint;
                p.render(graphics);
            }
        }
        
        private function renderStick():void
        {
            for (var i:int = 0; i < _sticks.length; i++)
            {
                var s:VerletStick = _sticks[i] as VerletStick;
                s.render(graphics);
            }
        }
        
    }

}
    
    import flash.display.Graphics;
    import flash.geom.Rectangle;
    /**
     * ...
     * @author gaina
     */
    class VerletPoint
    {
        
        public var x:Number;
        public var y:Number;
        
        private var _oldx:Number;
        private var _oldy:Number;
        
        public function VerletPoint(x:Number,y:Number) 
        {
            setPosition(x, y);
        }
        
        public function update():void
        {
            var _tempX:Number = x;
            var _tempY:Number = y;
            x += vx;
            y += vy;
            _oldx = _tempX;
            _oldy = _tempY;
        }
        
        public function constrain(rect:Rectangle):void
        {
            x = Math.max(rect.left, Math.min(rect.right, x));
            y = Math.max(rect.top, Math.min(rect.bottom, y));
        }
        
        private function setPosition(x:Number, y:Number):void
        {
            this.x = _oldx = x;
            this.y = _oldy = y;
        }
        
        public function get vx():Number { return x - _oldx; }
        
        public function set vx(value:Number):void 
        {
            _oldx = x - value;
        }
        
        public function get vy():Number { return y - _oldy; }
        
        public function set vy(value:Number):void 
        {
            _oldy = y - value;
            
        }
        
        public function render(g:Graphics):void
        {
            g.beginFill(0);
            g.drawCircle(x, y, 5);
            g.endFill();
        }
        
    }
    
    
    import flash.display.Graphics;
    /**
     * ...
     * @author gaina
     */
    class VerletStick
    {
        private var _pointA:VerletPoint;
        private var _pointB:VerletPoint;
        private var _length:Number;
        
        public function VerletStick(pointA:VerletPoint, pointB:VerletPoint, length:Number = -1) 
        {
            _pointA = pointA;
            _pointB = pointB;
            if (length == -1) {
                var dx:Number = _pointB.x - _pointA.x;
                var dy:Number = _pointB.y - _pointA.y;
                _length = Math.sqrt(dx * dx + dy * dy);
            }else {
                _length = length;
            }
        }
        
        public function update():void
        {
            var dx:Number = _pointB.x - _pointA.x;
            var dy:Number = _pointB.y - _pointA.y;
            var dist:Number = Math.sqrt(dx * dx + dy * dy);
            var diff:Number = _length - dist;
            
            var offsetX:Number = (diff * dx / dist) / 2;
            var offsetY:Number = (diff * dy / dist) / 2;
            
            _pointA.x -= offsetX;
            _pointA.y -= offsetY;
            _pointB.x += offsetX;
            _pointB.y += offsetY;
        }
        
        public function render(g:Graphics):void
        {
            g.lineStyle(1);
            g.moveTo(_pointA.x, _pointA.y);
            g.lineTo(_pointB.x, _pointB.y);
        }
        
    }