flash on 2013-2-24

by ohisama
♥0 | Line 253 | Modified 2013-02-24 18:21:45 | MIT License
play

ActionScript3 source code

/**
 * Copyright ohisama ( http://wonderfl.net/user/ohisama )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hyLr
 */

package
{
    import Box2D.Collision.Shapes.b2CircleDef;
    import Box2D.Collision.Shapes.b2PolygonDef;
    import Box2D.Collision.b2AABB;
    import Box2D.Common.Math.b2Vec2;
    import Box2D.Dynamics.b2Body;
    import Box2D.Dynamics.b2BodyDef;
    import Box2D.Dynamics.b2DebugDraw;
    import Box2D.Dynamics.b2World;
    import com.bit101.components.Label;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.Sprite;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    [SWF(backgroundColor="0x0", frameRate="60", width="475", height="475")]
    public class effect12 extends Sprite
    {
        private static const NUM_CIRCLES : int = 200;
        private static const DEBUG_DRAW : Boolean = true;
        private static const TO_PHYSICS_SCALE : Number = 1.0 / 30.0;
        private static const TO_DRAW_SCALE : Number = 1 / TO_PHYSICS_SCALE;
        private static const ITERATIONS : int = 5; 
        private static const TIME_STEP : Number = 1.0 / 30.0;
        private static const STEP1_SIMULATE : int = 0;
        private static const STEP2_WAIT_FOR_SLEEP : int = 1;
        private static const STEP3_RECONSTRUCTION : int = 2;
        private var _label : Label;
        private var _refImage : BitmapData;
        private var _world : b2World;
        private var _objects : Array = [];
        private var _frameCount : int = 0;
        private var _maxFrames : int; 
        private var _step : int = STEP1_SIMULATE;
        private var _enterFrameHandler : Function;
        public function effect12()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.BEST;
            _label = new Label(this, 10, 5, 'LOADING.....');
            var loader : Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onLoadComplete);
            loader.load(new URLRequest('http://yumekikaku.dip.jp/obj/boy_10.png'), new LoaderContext(true));
        } 
        private function _onLoadComplete(event : Event) : void
        {
            var loader : Loader = LoaderInfo(event.target).loader;
            _refImage = Bitmap(loader.content).bitmapData;
            var worldAABB : b2AABB = new b2AABB();
            worldAABB.lowerBound.Set(-1000.0, -1000.0);
            worldAABB.upperBound.Set(1000.0, 1000.0);
            _world = new b2World(worldAABB, new b2Vec2(0.0, 10.0), true);
            _world.SetWarmStarting(true);
            _buildStaticBox(5 - 50, 475 / 2, 100, 1000);
            _buildStaticBox(475 - 5 + 50, 475 / 2, 100, 1000);
            _buildStaticBox(475 / 2, 475 - 5 + 50, 1000, 100);
            _buildStaticBox(0, 0, 50, 5);
            if (DEBUG_DRAW)
            {
                var dbgDraw : b2DebugDraw = new b2DebugDraw();
                dbgDraw.m_sprite = this;
                dbgDraw.m_drawScale = 30.0;
                dbgDraw.m_fillAlpha = 0.0;
                dbgDraw.m_lineThickness = 1.0;
                dbgDraw.m_drawFlags = 0xFFFFFFFF;
                _world.SetDebugDraw(dbgDraw);
            }
            _enterFrameHandler = _step1;
            addEventListener(Event.ENTER_FRAME, _onEnterFrame, false, 0, true);
        }
        private function _buildStaticBox(centerX : Number, centerY : Number, width : Number, height : Number) : b2Body
        {
            var bodyDef : b2BodyDef = new b2BodyDef();
            bodyDef.position.Set(centerX * TO_PHYSICS_SCALE, centerY * TO_PHYSICS_SCALE);
            var boxDef : b2PolygonDef = new b2PolygonDef();
            boxDef.SetAsBox(width * TO_PHYSICS_SCALE / 2, height * TO_PHYSICS_SCALE / 2);
            boxDef.friction = 0.3;
            boxDef.density = 0;
            var body : b2Body = _world.CreateBody(bodyDef);
            body.CreateShape(boxDef);
            body.SetMassFromShapes();
            return body;
        }
        private function _buildDynamicCircle(centerX : Number, centerY : Number, radius : Number, graphic : DisplayObject = null) : b2Body
        {
            var bodyDef : b2BodyDef = new b2BodyDef();
            bodyDef.position.Set(centerX * TO_PHYSICS_SCALE, centerY * TO_PHYSICS_SCALE);
            var circleDef : b2CircleDef = new b2CircleDef();
            circleDef.radius = radius * TO_PHYSICS_SCALE;
            circleDef.density = 1.0;
            circleDef.friction = 0.3;
            circleDef.restitution = 0.5;
            var body : b2Body = _world.CreateBody(bodyDef);
            body.CreateShape(circleDef);
            body.SetMassFromShapes();
            return body;
        }
        private function _onEnterFrame(event : Event) : void
        {
            if (_enterFrameHandler is Function)
            {
                _enterFrameHandler();
            }
        }
        private function _step1() : void
        {
            if (_frameCount % 3 == 0)
            {
                var px : Number = Math.random() * 475;
                var py : Number = -30;
                var r : Number = Math.random() * Math.random() * 30 + 5;
                var b : b2Body = _buildDynamicCircle(px, py, r);
                var v : Number = (Math.random() - 0.5) * 50;
                b.ApplyImpulse(new b2Vec2(v, 0), new b2Vec2());
                var sp : Recorder = new Recorder();
                sp.frameOffset = _frameCount;

                b.SetUserData(sp);

                _objects.push(

                {

                    px :  px,

                    py :  py,

                    r :  r,

                    v :  v,

                    b :  b,

                    sp :  sp

                });

                if (_objects.length == NUM_CIRCLES)

                {

                    _step = STEP2_WAIT_FOR_SLEEP;

                    _enterFrameHandler = _step2;

                    _maxFrames = _frameCount;

                    _frameCount = 0;

                }

            }

            _step2();

        }

        private function _step2() : void

        {

            _world.Step(TIME_STEP, ITERATIONS);

            if (DEBUG_DRAW && _frameCount % 30 == 0)

            {

                _world.DrawDebugData();

            }

            for (var bb : b2Body = _world.GetBodyList(); bb; bb = bb.GetNext())

            {

                var rec : Recorder = bb.GetUserData() as Recorder;

                if (rec)

                {

                    var pos : b2Vec2 = bb.GetPosition();

                    rec.save(pos.x * TO_DRAW_SCALE, pos.y * TO_DRAW_SCALE);

                }

            }

            _frameCount++;

            if (_step == effect12.STEP2_WAIT_FOR_SLEEP && _frameCount > 300)

            {

                _enterFrameHandler = null;

                _step = STEP3_RECONSTRUCTION;

                graphics.clear();

                var n : int = _objects.length;

                for (var i : int = 0; i < n; ++i)

                {

                    var info : Object = _objects[i];

                    var b : b2Body = info.b;

                    var p : b2Vec2 = b.GetPosition();

                    var dx : Number = p.x * TO_DRAW_SCALE;

                    var dy : Number = p.y * TO_DRAW_SCALE;

                    var c : uint = _refImage.getPixel(dx / 475 * _refImage.width, dy / 475 * _refImage.height);

                    var sp : Recorder = info.sp;

                    sp.draw(c, info.r);

                    _objects[i] = sp;

                }

                _maxFrames += _frameCount;

                _frameCount = 0;

                _label.text = 'CLICK TO START';

                stage.addEventListener(MouseEvent.CLICK, _onClickStage);

            }

        }
        private function _step3() : void
        {
            var n : int = _objects.length;
            for (var i : int = 0; i < n; ++i)
            {
                var sp : Recorder = _objects[i];
                if (sp.frameOffset <= _frameCount)
                {
                    if (!sp.parent)
                    {
                        addChild(sp);
                    }
                    sp.restore(_frameCount - sp.frameOffset);
                }
            }
            _frameCount++;
        }
        private function _onClickStage(event : MouseEvent) : void
        {
            var n : int = numChildren;
            while (n--)
            {
                removeChildAt(n);
            }
            _frameCount = 0;
            _enterFrameHandler = _step3;
        }
    }
}
import flash.display.Sprite;
class Recorder extends Sprite
{
    public var frameOffset : int = 0;
    private var _px : Array;
    private var _py : Array;
    public function Recorder()
    {
        _px = new Array();
        _py = new Array();
    }
    public function save(rx : Number = NaN, ry : Number = NaN) : void
    {
        if (isNaN(rx))
        {
            _px.push(x);
            _py.push(y);
        }
        else
        {
            _px.push(rx);
            _py.push(ry);
        }
    }
    public function restore(frame : int) : void
    {
        if (frame < _px.length)
        {
            x = _px[frame];
            y = _py[frame];
        }
    }
    public function draw(color : uint, radius : Number) : void
    {
        graphics.beginFill(color);
        graphics.drawCircle(0, 0, radius);
        graphics.endFill();
    }
}