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

Happy Birthday ;)

Spark 勉強会の Geoff Stearns 氏のハッピーバースデー企画
*  お誕生日おめでとーございまーす :-)
*
*  @see http://wiki.libspark.org/wiki/SparkStudy/09
/**
 * Copyright soundkitchen ( http://wonderfl.net/user/soundkitchen )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/289Z
 */

/**
 *  Spark 勉強会の Geoff Stearns 氏のハッピーバースデー企画
 *  お誕生日おめでとーございまーす :-)
 *
 *  @see http://wiki.libspark.org/wiki/SparkStudy/09
 */
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;

    import com.flashdynamix.utils.SWFProfiler;
    import org.libspark.thread.Thread;
    import org.libspark.thread.EnterFrameThreadExecutor;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.objects.DisplayObject3D;
    import org.papervision3d.render.LazyRenderEngine;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;

    [SWF(width=465, height=465, frameRate=60, backgroundColor=0x000000)]

    /**
     *  document class.
     */
    public class CodeBreak extends Sprite
    {
        /**
         *  constructor.
         */
        public function CodeBreak()
        {
            addEventListener(Event.ADDED_TO_STAGE, initialize);
        }

        /**
         *  initialize the object.
         */
        private function initialize(evt:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, initialize);

            if (!Thread.isReady)
            {
                stage.align = StageAlign.TOP_LEFT;
                stage.quality = StageQuality.HIGH;
                stage.scaleMode = StageScaleMode.NO_SCALE;

                SWFProfiler.init(this);

                Thread.initialize(new EnterFrameThreadExecutor());
            }

            var ctx:Context,
                camera:Camera3D,
                scene:Scene3D,
                viewport:Viewport3D,
                container:DisplayObject3D,
                renderer:LazyRenderEngine;

            //  camera.
            camera = new Camera3D();
            camera.z = 1000;
            //camera.focus = 20;
            //camera.zoom = 40;
            camera.lookAt(DisplayObject3D.ZERO);
            //  scene.
            scene = new Scene3D();
            //  container.
            container = new DisplayObject3D();
            scene.addChild(container);
            //  viewport.
            viewport = new Viewport3D(stage.stageWidth, stage.stageHeight, true);
            addChild(viewport);
            //  render engine.
            renderer = new LazyRenderEngine(scene, camera, viewport);

            //  context.
            ctx = new Context();
            ctx.layer = this;
            ctx.stage = stage;
            ctx.camera = camera;
            ctx.scene = scene;
            ctx.container = container;
            ctx.viewport = viewport;
            ctx.renderer = renderer;

            new MainThread(ctx).start();
        }
    }
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Stage;
import flash.display.StageDisplayState;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;

import frocessing.color.ColorHSV;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.targets.single.ISingleTweenTarget;
import org.libspark.betweenas3.easing.*;
import org.libspark.betweenas3.events.BetweenEvent;
import org.libspark.thread.Monitor;
import org.libspark.thread.Thread;
import org.libspark.thread.threads.net.URLLoaderThread;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.materials.special.Letter3DMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.render.LazyRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.typography.Font3D;
import org.papervision3d.typography.Text3D;
import org.papervision3d.typography.fonts.HelveticaBold;
import org.papervision3d.view.Viewport3D;

internal const SOURCE_URL:String = "http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject_src.js";
internal const TARGET_WORDS:String = "Happy Birthday ;)";

/**
 *  context object.
 */
internal class Context
{
    /**
     *  reference of document class object.
     */
    public var layer:DisplayObjectContainer;

    /**
     *  reference of stage object.
     */
    public var stage:Stage;

    /**
     *  reference of pv3d camera object.
     */
    public var camera:Camera3D;

    /**
     *  reference of pv3d container object.
     */
    public var container:DisplayObject3D;

    /**
     *  reference of pv3d scene object.
     */
    public var scene:Scene3D;

    /**
     *  reference of pv3d renderer object.
     */
    public var renderer:LazyRenderEngine;

    /**
     *  reference of pv3d viewport object.
     */
    public var viewport:Viewport3D;
}

/**
 *  main task of this applicaiton.
 */
internal class MainThread extends Thread
{
    private var context:Context;
    private var loader:URLLoaderThread;

    /**
     *  constructor.
     */
    public function MainThread(context:Context)
    {
        this.context = context;
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        var t:Thread;

        t = new WaitAnimationThread(context);
        t.start();
        t.join();

        new HandleScreenThread(context).start();

        next(startAnimation);
    }

    private function startAnimation():void
    {
        var req:URLRequest;

        req = new URLRequest(SOURCE_URL);

        loader = new URLLoaderThread(req);
        loader.start();
        loader.join();

        next(loadComplete);
        error(Error, loadFailure);
    }

    private function loadComplete():void
    {
        var data:String;
        
        data = String(loader.loader.data);

        new PV3DRenderThread(context).start();
        new MainAnimationThread(context, data).start();
    }

    private function loadFailure(e:Error, t:Thread):void
    {
        trace(e.getStackTrace());
    }

    /**
     *  finalize the object.
     */
    override protected function finalize():void
    {
        context = null;
    }
}

/**
 *  wait user's action.
 */
internal class WaitAnimationThread extends Thread
{
    private var context:Context;
    private var message:Bitmap;

    /**
     *  constructor.
     */
    public function WaitAnimationThread(context:Context)
    {
        this.context = context;
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        var txt:TextField,
            fmt:TextFormat,
            bmd:BitmapData;

        fmt = new TextFormat();
        fmt.font = 'Lucida Grande';
        fmt.size = 64;
        fmt.color = 0x000000;

        txt = new TextField();
        txt.autoSize = TextFieldAutoSize.LEFT;
        txt.defaultTextFormat = fmt;
        txt.text = "click to start";

        bmd = new BitmapData(txt.width, txt.height, true, 0);
        bmd.draw(txt);
        message = new Bitmap(bmd);
        message.x = (context.stage.stageWidth - message.width) >> 1;
        message.y = (context.stage.stageHeight - message.height) >> 1;
        message.blendMode = BlendMode.INVERT;

        context.layer.addChild(message);

        event(context.stage, MouseEvent.CLICK, clicked);
        event(context.stage, Event.RESIZE, resized);
    }

    /**
     *  will execute when clicked stage.
     */
    private function clicked(evt:MouseEvent):void
    {
        message.x = (context.stage.stageWidth - message.width) >> 1;
        message.y = (context.stage.stageHeight - message.height) >> 1;

        new HideMessageThread(message).start();
    }

    /**
     *  will execute when resized stage size.
     */
    private function resized(evt:Event):void
    {
        message.x = (context.stage.stageWidth - message.width) >> 1;
        message.y = (context.stage.stageHeight - message.height) >> 1;

        event(context.stage, MouseEvent.CLICK, clicked);
        event(context.stage, Event.RESIZE, resized);
    }

    /**
     *  finalize the object.
     */
    override protected function finalize():void
    {
        message = null;
        context = null;
    }
}

/**
 *  hide splash message.
 */
internal class HideMessageThread extends Thread
{
    private var message:DisplayObject;
    private var monitor:Monitor;

    /**
     *  constructor.
     */
    public function HideMessageThread(message:DisplayObject)
    {
        this.message = message;
        this.monitor = new Monitor();
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        var b:ITween,
            from:Object,
            to:Object;

        to = {
            'alpha': 0,
            //'y': message.stage.stageHeight,
            '_blurFilter': {
                'blurX': 128,
                'blurY': 128
            }
        };
        b = BetweenAS3.tween(message, to, from, 2, Quadratic.easeIn);
        b.onComplete = monitor.notifyAll;
        b.play();

        monitor.wait();
    }

    /**
     *  finalize the object.
     */
    override protected function finalize():void
    {
        message.parent.removeChild(message);
        message = null;
        monitor = null;
    }
}

/**
 *  handle full screen.
 */
internal class HandleScreenThread extends Thread
{
    private var context:Context;

    /**
     *  constructor.
     */
    public function HandleScreenThread(context:Context)
    {
        this.context = context;
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        event(context.stage, MouseEvent.CLICK, toggleDisplayState, false, int.MAX_VALUE);
    }

    /**
     *  toggle full screen and normal.
     */
    private function toggleDisplayState(evt:MouseEvent):void
    {
        var s:Stage;

        s = context.stage;

        s.displayState = s.displayState == StageDisplayState.NORMAL
                       ? StageDisplayState.FULL_SCREEN
                       : StageDisplayState.NORMAL;

        event(s, MouseEvent.CLICK, toggleDisplayState, false, int.MAX_VALUE);
    }

    /**
     *  finalize the object.
     */
    override protected function finalize():void
    {
        context = null;
    }
}

/**
 *  main animation.
 */
internal class MainAnimationThread extends Thread
{
    private var context:Context;
    private var monitor:Monitor;
    private var data:String;
    private var hsv:ColorHSV;
    private var dataIndex:uint;
    private var targetIndex:uint;

    /**
     *  constructor.
     */
    public function MainAnimationThread(context:Context, data:String)
    {
        this.context = context;
        this.data = data.replace(/\r+|\n+|\s+/g, ' ');
        hsv = new ColorHSV(0, 1, 1, 1);
        dataIndex = 0;
        targetIndex = 0;
        monitor = new Monitor();
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        if (targetIndex >= TARGET_WORDS.length)
        {
            showFullMessage();
        }
        else if (dataIndex >= data.length)
        {
            //  todo: logic implement.
        }
        else
        {
            var t:String,
                c:String;

            t = TARGET_WORDS.charAt(targetIndex);
            c = data.charAt(dataIndex);
            if (t == c)
            {
                addTargetCharacter(t);
            }
            else
            {
                addDefaultCharacter(c);
            }
            next(run);
        }
    }

    /**
     *  add target character.
     */
    private function addTargetCharacter(str:String):void
    {
        var b:ITween,
            mat:Letter3DMaterial,
            fnt:Font3D,
            txt:Text3D,
            rot:Number3D;

        targetIndex++;
        dataIndex++;

        rot = Matrix3D.matrix2euler(context.camera.transform);
        fnt = new HelveticaBold();
        mat = new Letter3DMaterial(0xffffff);

        try
        {
            txt = new Text3D(str, fnt, mat);
        }
        catch (e:Error)
        {
            return;
        }
        txt.z = 950;
        txt.rotationX = rot.x;
        txt.rotationY = rot.y;
        txt.rotationZ = rot.z;
        txt.filters = [
            new GlowFilter(0xffffff, 1, 8, 8)
        ];
        txt.useOwnContainer = true;

        context.container.addChild(txt);

        b = BetweenAS3.tween(txt, {
            'z': 0,
            'alpha': 0,
            'rotationX': 360 * Math.random(),
            'rotationY': 360 * Math.random(),
            'rotationZ': 360 * Math.random()
        }, null, 1, Expo.easeIn);
        b.addEventListener(BetweenEvent.COMPLETE, completeHandler);
        if (targetIndex >= TARGET_WORDS.length)
        {
            b.onComplete = monitor.notifyAll;
            monitor.wait();
        }
        else
        {
            sleep(200);
        }
        b.play();
    }

    /**
     *  add character.
     */
    private function addDefaultCharacter(str:String):void
    {
        var b:ITween,
            to:Object, from:Object,
            mat:Letter3DMaterial,
            fnt:Font3D,
            txt:Text3D,
            rot:Number3D;

        dataIndex++;

        hsv.h += 5;
        rot = Matrix3D.matrix2euler(context.camera.transform);
        fnt = new HelveticaBold();
        mat = new Letter3DMaterial(hsv.value, .25);

        try
        {
            txt = new Text3D(str, fnt, mat);
        }
        catch (e:Error)
        {
            return;
        }
        txt.z = 950;
        txt.rotationX = rot.x;
        txt.rotationY = rot.y;
        txt.rotationZ = rot.z;
        txt.filters = [
            new GlowFilter(0xffffff, 1, 8, 8)
        ];
        txt.useOwnContainer = true;

        context.container.addChild(txt);

        b = BetweenAS3.tween(txt, {
            'z': 0,
            'alpha': 0,
            'rotationX': 360 * Math.random(),
            'rotationY': 360 * Math.random(),
            'rotationZ': 360 * Math.random()
        }, null, .75, Quadratic.easeIn);
        b.addEventListener(BetweenEvent.COMPLETE, completeHandler);
        if (dataIndex >= data.length)
        {
            b.onComplete = monitor.notifyAll;
            monitor.wait();
        }
        else
        {
            sleep(50);
        }
        b.play();
    }

    /**
     *  show complete message.
     */
    private function showFullMessage():void
    {
        var b:ITween,
            mat:Letter3DMaterial,
            fnt:Font3D,
            txt:Text3D,
            rot:Number3D;

        rot = Matrix3D.matrix2euler(context.camera.transform);
        mat = new Letter3DMaterial(0xffffff);
        fnt = new HelveticaBold();
        txt = new Text3D(TARGET_WORDS, fnt, mat);

        txt.z = -1000;
        txt.rotationX = Math.random() * 360;
        txt.rotationY = Math.random() * 360;
        txt.rotationZ = Math.random() * 360;
        txt.alpha = 0;
        txt.useOwnContainer = true;

        context.container.addChild(txt);

        b = BetweenAS3.tween(txt, {
            'z': 500,
            'alpha': 1,
            'rotationX': rot.x,
            'rotationY': rot.y,
            'rotationZ': rot.z
        }, null, 5, Elastic.easeOut);
        b.play();
    }

    /**
     *  will execute when tween complete betweenas3.
     */
    private function completeHandler(evt:BetweenEvent):void
    {
        var b:ITween,
            t:ISingleTweenTarget,
            obj:DisplayObject3D;

        b = ITween(evt.target);
        t = ISingleTweenTarget(b.tweenTarget);
        obj = DisplayObject3D(t.target);
        obj.parent.removeChild(obj);
    }

    /**
     *  finalize the object.
     */
    override protected function finalize():void
    {
        context = null;
        data = null;
    }
}

/**
 *  rendering pv3d.
 */
internal class PV3DRenderThread extends Thread
{
    private var context:Context;

    /**
     *  constructor.
     */
    public function PV3DRenderThread(context:Context)
    {
        this.context = context;
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        if (checkInterrupted()) return;

        context.renderer.render();

        next(run);
    }

    /**
     *  finalize the object.
     */
    override protected function finalize():void
    {
        context = null;
    }
}