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

forked from: forked from: Dynamic verlet collision with mc?

one way to do that, not necessary the best
/**
 * Copyright monpu ( http://wonderfl.net/user/monpu )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/97G8
 */

// forked from makc3d's forked from: Dynamic verlet collision with mc?
// forked from bahngoura's Dynamic verlet collision with mc?
// forked from fakestar0826's Verlet Triangle
// forked from fakestar0826's Verlet Method

// one way to do that, not necessary the best

package {
    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.display.StageScaleMode;
    import flash.display.StageAlign;
    import flash.display.Sprite;
    import flash.display.MovieClip;
    
    
    public class FlashTest extends Sprite {
        
        private var _pointA:VerletPoint;
        private var _pointB:VerletPoint;
        private var _pointC:VerletPoint;
        private var _stickA:VerletStick;
        private var _stickB:VerletStick;
        private var _stickC:VerletStick;
        private var _stageRect:BitmapData;
        public  var ground:MovieClip = new MovieClip();
        
        public function FlashTest() {
            // write as3 code here..
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            
            
            ground.graphics.beginFill(0xFF0000);
            ground.graphics.drawRect(0, 0, 300, 40);
            ground.graphics.endFill();
            addChild(ground);
            ground.x = 100;
            ground.y = 300;
            ground.rotation = -10;
            
            
            _stageRect = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0);
            _stageRect.draw (ground, ground.transform.matrix);
            
            _pointA = new VerletPoint(100, 100);
            _pointB = new VerletPoint(200, 100);
            _pointC = new VerletPoint(150, 200);
            _stickA = new VerletStick(_pointA, _pointB);
            _stickB = new VerletStick(_pointB, _pointC);
            _stickC = new VerletStick(_pointC, _pointA);
            
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function onEnterFrame(e:Event):void
        {
            _pointA.y += 0.5;
            //_pointA.update();
            
            _pointB.y += 0.5;
            //_pointB.update();
            
            _pointC.y += 0.5;
            //_pointC.update();
            
            //繰り返しを増やすと剛体に近づく。stickのupdateメソッドにより、点同士の斥力?が働くため
            for(var i:int = 0;i < 5;i++)
            {
                _pointA.constrain(_stageRect);
                _pointB.constrain(_stageRect);
                _pointC.constrain(_stageRect);
 //               _stickA.update();
 //               _stickB.update();
 //               _stickC.update();
            }

            graphics.clear();
            _pointA.render(graphics);
            _pointB.render(graphics);
            _pointC.render(graphics);
            _stickA.render(graphics);
            _stickB.render(graphics);
            _stickC.render(graphics);
        }

    }
}
import flash.display.MovieClip;
import flash.display.Graphics;
import flash.display.BitmapData;
import flash.geom.Rectangle;

class VerletPoint
{
    public var x:Number;
    public var y:Number;
    
    private var _oldX:Number;
    private var _oldY:Number;
    
    public var movieclip:String = new String;
    
    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 setPosition(x:Number, y:Number):void
    {
        this.x = _oldX = x;
        this.y = _oldY = y;
    }
    
   public function constrain(bd:BitmapData):void
   {
       var rect:Rectangle = bd.rect;
       x = Math.max(rect.left, Math.min(rect.right, x));
       y = Math.max(rect.top, Math.min(rect.bottom, y));

        if (hitTestXY (bd, x, y)) {
            // now we spiral away from x, y to find unoccupied pixel
            for (var i:int = 1; i < 123; i++) {
                var j:int;
                for (j = -i; j < i; j++) {
                    if (!hitTestXY (bd, x + j, y - i)) {
                        x += j; y -= i; return;
                    }
                    if (!hitTestXY (bd, x + i, y - j)) {
                        x += i; y -= j; return;
                    }
                    if (!hitTestXY (bd, x - j, y + i)) {
                        x -= j; y += i; return;
                    }
                    if (!hitTestXY (bd, x - i, y + j)) {
                        x -= i; y += j; return;
                    }
                }
            }
        }
    }

    private function hitTestXY (bd:BitmapData, X:int, Y:int):Boolean {
        return ((bd.getPixel32 (X, Y) / 0x1000000) > 127);
    }

    public function set vx(value:Number):void
    {
        _oldX = x - value;
    }
    
    public function get vx():Number
    {
        return x - _oldX;
    }
    
    public function set vy(value:Number):void
    {
        _oldY = y - value;
    }
    
    public function get vy():Number
    {
       return y - _oldY;
    }
    
    public function render(g:Graphics):void
    {
        g.beginFill(0);
        g.drawCircle(x, y, 4);
        g.endFill();
    }
}

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 = _pointA.x - _pointB.x;
            var dy:Number = _pointA.y - _pointB.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)/* it means diff * cos(θ)*/ / 2;
        var offsetY:Number = (diff * dy / dist)/* it means diff * sin(θ)*/ / 2;
        
        _pointA.x -= offsetX;
        _pointA.y -= offsetY;
        _pointB.x += offsetX;
        _pointB.y += offsetY;
    }
    
    public function render(g:Graphics):void
    {
        g.lineStyle(0);
        g.moveTo(_pointA.x, _pointA.y);
        g.lineTo(_pointB.x, _pointB.y);
    }



}