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

Mosaic

@author hiko
Get Adobe Flash player
by Saqoosha 29 Nov 2010
/**
 * Copyright Saqoosha ( http://wonderfl.net/user/Saqoosha )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/vhTF
 */

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="#ffffff", frameRate="60", width="475", height="475")]

    
    public class Mosaic extends Sprite {
        
        private static const NUM_CIRCLES:int = 200;
        private static const DEBUG_DRAW:Boolean = false;
        
        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 Mosaic(){
            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://saqoo.sh/a/labs/wonderfl/color.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 == Mosaic.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:Vector.<Number>;
    private var _py:Vector.<Number>;


    public function Recorder() {
        _px = new Vector.<Number>();
        _py = new Vector.<Number>();
    }
    
    
    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();
    }
}