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

ノスタルジック?な感じ?

ノスタルジックな雰囲気になった。かな?
*  またも ActionScript3 Thread Library 使って作りました :-)
*
*  コメントが壊れたカタコトの英語でごめんなさい :-(
/**
 *  ノスタルジックな雰囲気になった。かな?
 *  またも ActionScript3 Thread Library 使って作りました :-)
 *
 *  コメントが壊れたカタコトの英語でごめんなさい :-(
 */
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.EnterFrameThreadExecutor;
    import org.libspark.thread.Thread;

    [SWF(width=465, height=465, frameRate=30, backgroundColor=0xffffff)]

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

        /**
         *  initialize the object.
         */
        private function initialize(evt:Event):void
        {
            //  check is thread system already initialized?
            if (!Thread.isReady)
            {
                //  fixed stage settings.
                stage.align = StageAlign.TOP_LEFT;
                stage.quality = StageQuality.MEDIUM;
                stage.scaleMode = StageScaleMode.NO_SCALE;

                SWFProfiler.init(this);

                //  initialize the thread system.
                Thread.initialize(new EnterFrameThreadExecutor());
            }

            //  wake up main task thread.
            new MainThread(this).start();
        }
    }
}


import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.display.Stage;
import flash.errors.IOError;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BitmapFilter;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.system.LoaderContext;

import com.adobe.serialization.json.JSON;
import org.libspark.thread.Monitor;
import org.libspark.thread.Thread;
import org.libspark.thread.threads.display.LoaderThread;
import org.libspark.thread.threads.net.URLLoaderThread;
import org.libspark.thread.utils.ParallelExecutor;


/**
 *  main task thread.
 */
internal class MainThread extends Thread
{
    private var layer:DisplayObjectContainer;
    private var loader:LoadDataThread;

    /**
     *  constructor.
     */
    public function MainThread(layer:DisplayObjectContainer)
    {
        this.layer = layer;
    }

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

        //  wake up handle background task.
        new HandleBackgroundThread(layer).start();
        //  wake up wait animation task.
        waitor = new WaitAnimationThread(layer);
        waitor.start();
        waitor.join();
        //  stack next task(s).
        next(loadData);
    }

    /**
     *  load data from flickr.
     */
    private function loadData():void
    {
        loader = new LoadDataThread();
        loader.start();
        loader.join();
        //  stack next task(s).
        next(loadComplete);
    }

    /**
     *  laod and display images.
     */
    private function loadComplete():void
    {
        var data:Array,
            queue:FlickrImageQueue,
            container:Sprite;

        data = loader.data;
        //  create photo image queue.
        queue = new FlickrImageQueue();
        //  create images container.
        container = new Sprite();
        container.scaleX = 2;
        container.scaleY = 2;

        layer.addChild(container);
        //  wake up fix position task thread.
        new FollowMousePositionThread(container).start();
        //  wake up display image task thread.
        new DisplayImageThread(container, queue).start();
        //  wake up load image task thread(s).
        new LoadImageThread(data, queue).start();
        new LoadImageThread(data, queue).start();
        new LoadImageThread(data, queue).start();
    }

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


/**
 *  handle background noise task.
 */
internal class HandleBackgroundThread extends Thread
{
    public static const TICK_THRESHOLD:uint = 3;

    private var layer:DisplayObjectContainer;
    private var background:Bitmap;
    private var tick:uint;

    /**
     *  constructor.
     */
    public function HandleBackgroundThread(layer:DisplayObjectContainer)
    {
        this.layer = layer;
        this.tick = 0;
    }

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

        s = layer.stage;

        //  create background noise canvas.
        var bmd:BitmapData = new BitmapData(s.stageWidth / 2, s.stageHeight / 2, true, 0);
        //  create bitmap for background.
        background = new Bitmap(bmd);
        background.scaleX = 2;
        background.scaleY = 2;
        background.alpha = .15;
        //  add background to layer.
        layer.addChild(background);
        //  update background immediately.
        update();
    }

    /**
     *  update background.
     */
    private function update():void
    {
        var s:Stage;

        s = background.stage;

        //  if removed background from stage or interrupted, halt process.
        if (!s || checkInterrupted()) return;
        //  check triggerable?
        if (tick % TICK_THRESHOLD == 0)
        {
            //  regenerate noise.
            background.bitmapData.noise(Math.random() * 100);
        }
        //  increment tick in range.
        tick = ++tick % TICK_THRESHOLD;

        //  stack next task(s).
        next(update);
        event(s, Event.RESIZE, resized);
    }

    private function resized(evt:Event):void
    {
        var s:Stage,
            pb:BitmapData,
            nb:BitmapData;

        //  cast target as stage object.
        s = evt.target as Stage;
        //  if missing target or interrupted, halt process.
        if (!s || checkInterrupted()) return;

        //  recreate noise bitmap data.
        pb = background.bitmapData;
        nb = new BitmapData(s.stageWidth / 2, s.stageHeight / 2, true, 0);
        background.bitmapData = nb;
        //  release old data resource.
        pb.dispose();
        //  reset tick counter.
        tick = 0;
        //  update background noise immediately.
        update();
    }

    /**
     *  finalize the object.
     */
    override protected function finalize():void
    {
        if (layer.contains(background))
        {
            layer.removeChild(background);
        }
        layer = null;
        background.bitmapData.dispose();
        background = null;
    }
}


/**
 *  wait animation to til user's first action.
 */
internal class WaitAnimationThread extends Thread
{
    private var layer:DisplayObjectContainer;
    private var message:DisplayObject;
    private var handlers:ParallelExecutor;

    /**
     *  constructor.
     */
    public function WaitAnimationThread(layer:DisplayObjectContainer)
    {
        this.layer = layer;
    }

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

        //  create format for message text.
        fmt = new TextFormat();
        fmt.color = 0x000000;
        fmt.size = 48;
        fmt.font = 'sans-serif';

        //  create message text.
        txt = new TextField();
        txt.autoSize = TextFieldAutoSize.LEFT;
        txt.defaultTextFormat = fmt;
        txt.text = 'click to start.';

        //  create message data.
        bmd = new BitmapData(txt.textWidth, txt.textHeight, true, 0);
        //  draw text to bitmap data.
        bmd.draw(txt);
        //  create message.
        message = new Sprite();
        //  add bitmap to message layer.
        Sprite(message).addChild(new Bitmap(bmd));
        //  hide message. will disappear later.
        message.visible = false;
        //  add message to layer.
        layer.addChild(message);

        //  create sub processes handler.
        handlers = new ParallelExecutor();
        //  stack fixed position task.
        handlers.addThread(new FixCenterPositionThread(message));
        //  wake up handling focus/blur task.
        handlers.addThread(new HandleFocusThread(message));
        //  start each sub processes.
        handlers.start();

        //  stack next task(s).
        event(message, MouseEvent.CLICK, hideMessage);
    }

    /**
     *  hide message.
     *  will execute when message is clicked.
     */
    private function hideMessage(evt:MouseEvent):void
    {
        //  interrupt sub processes.
        handlers.interrupt();
        handlers = null;

        //  wake up hide message task.
        new HideMessageThread(message).start();
    }

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


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

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

    /**
     *  first executable.
     */
    override protected function run():void
    {
        message.alpha *= .95;

        if (message.alpha < .02)
        {
            message.alpha = 0;
        }
        else
        {
            next(run);
        }
    }

    /**
     *  finalize the object.
     */
    override protected function finalize():void
    {
        var p:DisplayObjectContainer;

        p = message.parent;

        if (p)
        {
            p.removeChild(message);
        }
        message = null;
    }
}


/**
 *  fix center position task thread.
 */
internal class FixCenterPositionThread extends Thread
{
    private var target:DisplayObject;

    /**
     *  constructor.
     */
    public function FixCenterPositionThread(target:DisplayObject)
    {
        this.target = target;
    }

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

        s = target.stage;
        //  if missing stage, halt process.
        if (!s) return;
        //  fix target position.
        target.x = (s.stageWidth - target.width) / 2;
        target.y = (s.stageHeight - target.height) / 2;
        //  if hide object yet, disappear.
        if (!target.visible)
        {
            target.visible = true;
        }
        //  stack next task(s).
        event(s, Event.RESIZE, resized);
        interrupted(shutdown);
    }

    /**
     *  will execute when stage is resized.
     */
    private function resized(evt:Event):void
    {
        var s:Stage;

        s = target.stage;
        //  if missing stage, halt process.
        if (!s) return;
        //  fix target position.
        target.x = (s.stageWidth - target.width) / 2;
        target.y = (s.stageHeight - target.height) / 2;
        //  stack next task(s).
        event(s, Event.RESIZE, resized);
        interrupted(shutdown);
    }

    /**
     *  default interrupted handler.
     */
    private function shutdown(...args):void
    {
        //  do nothing.
    }

    override protected function finalize():void
    {
        target = null;
    }
}


/**
 *  handling focus/blur task thread.
 */
internal class HandleFocusThread extends Thread
{
    private var target:DisplayObject;

    /**
     *  constructor.
     */
    public function HandleFocusThread(target:DisplayObject)
    {
        this.target = target;
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        //  reset filters.
        target.filters = [
            new BlurFilter(8, 8, BitmapFilterQuality.LOW),
        ];
        //  bind each events.
        events();
    }

    /**
     *  bind each events.
     */
    private function events():void
    {
        //  stack next task(s).
        event(target, MouseEvent.ROLL_OVER, focus);
        event(target, MouseEvent.ROLL_OUT, blur);
        interrupted(shutdown);
    }

    /**
     *  will execute when target is focused.
     */
    private function focus(evt:MouseEvent):void
    {
        //  reset filters.
        target.filters = [
            new BlurFilter(2, 2, BitmapFilterQuality.LOW),
        ];
        //  bind each events.
        events();
    }

    /**
     *  will execute when target is unfocused.
     */
    private function blur(evt:MouseEvent):void
    {
        //  reset filters.
        target.filters = [
            new BlurFilter(8, 8, BitmapFilterQuality.LOW),
        ];
        //  bind each events.
        events();
    }

    /**
     *  default shutdown handler.
     */
    private function shutdown(...args):void
    {
        //  do nothing.
    }

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


/**
 *  load data from flickr task thread.
 */
internal class LoadDataThread extends Thread
{
    public static const YQL_URL:String = 'http://query.yahooapis.com/v1/public/yql';

    private var loader:URLLoaderThread;
    private var _data:Array;
    public function get data():Array
    {
        return _data.concat();
    }

    /**
     *  constructor.
     */
    public function LoadDataThread()
    {
        _data = [];
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        var req:URLRequest,
            data:URLVariables;

        data = new URLVariables();
        data['q'] = 'select * from flickr.photos.recent(64)';
        data['format'] = 'json';

        req = new URLRequest();
        req.url = YQL_URL;
        req.data = data;

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

        next(loadComplete);
        error(IOError, loadFailure);
        error(SecurityError, loadFailure);
    }

    /**
     *  will execute when load data complete.
     */
    private function loadComplete():void
    {
        var json:Object,
            row:Object;

        json = JSON.decode(loader.loader.data);

        if (!json.query || !json.query.results) return;

        for each (row in json.query.results.photo)
        {
            _data.push(new FlickrPhoto(row));
        }
    }

    /**
     *  will execute when load data failure.
     */
    private function loadFailure(e:Error, t:Thread):void
    {
        trace("CAUGHT EXCEPTION: ", e);
        //trace(e.getStackTrace());
    }
}


/**
 *
 */
internal class DisplayImageThread extends Thread
{
    private var layer:DisplayObjectContainer;
    private var queue:FlickrImageQueue;

    /**
     *  constructor.
     */
    public function DisplayImageThread(layer:DisplayObjectContainer, queue:FlickrImageQueue)
    {
        this.layer = layer;
        this.queue = queue;
    }

    /**
     *  first executable.
     */
    override protected function run():void
    {
        if (queue.checkPoll())
        {
            var i:uint,
                wrapper:Sprite;

            i = layer.numChildren;

            wrapper = new Sprite();
            wrapper.addChild(queue.poll());
            wrapper.x = Math.floor(i % 8) * 80;
            wrapper.y = Math.floor(i / 8) * 80;
            wrapper.blendMode = BlendMode.HARDLIGHT;

            new HandleFocusThread(wrapper).start();

            layer.addChild(wrapper);
        }
        //  stack next task(s).
        next(run);
    }

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


/**
 *  load each image task thread.
 */
internal class LoadImageThread extends Thread
{
    private var data:Array;
    private var queue:FlickrImageQueue;
    private var loader:LoaderThread;

    /**
     *  constructor.
     */
    public function LoadImageThread(data:Array, queue:FlickrImageQueue)
    {
        this.data = data;
        this.queue = queue;
    }

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

        var row:FlickrPhoto,
            req:URLRequest,
            ctx:LoaderContext;

        row = data.shift() as FlickrPhoto;
        req = new URLRequest(row.thumbnailURL);
        ctx = new LoaderContext(true);

        loader = new LoaderThread(req, ctx);
        loader.start();
        loader.join();

        next(loadComplete);
        error(IOError, loadFailure);
        error(SecurityError, loadFailure);
        interrupted(shutdown);
    }

    /**
     *  will execute when load data complete.
     */
    private function loadComplete():void
    {
        //  push new task into queue.
        queue.offer(Bitmap(loader.loader.content));
        //  stack next task(s).
        next(run);
    }

    /**
     *  will execute when load data failure.
     */
    private function loadFailure(e:Error, t:Thread):void
    {
        loader = null;
        //  stack next task(s).
        next(run);
    }

    /**
     *  default interrupted handler.
     */
    private function shutdown(...args):void
    {
        //  do nothing.
    }

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


/**
 *  follow the mouse point
 */
internal class FollowMousePositionThread extends Thread
{
    public static const MARGIN:Number = 150;

    private var target:DisplayObject;

    /**
     *  constructor.
     */
    public function FollowMousePositionThread(target:DisplayObject)
    {
        this.target = target;
    }

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

        s = target.stage;

        if (!s) return;

        target.x = MARGIN;
        target.y = MARGIN;

        event(s, MouseEvent.MOUSE_MOVE, moved);
        interrupted(shutdown);
    }

    /**
     *  will execute when mouse moved.
     */
    private function moved(evt:MouseEvent):void
    {
        update();
    }

    /**
     *  update target position.
     */
    private function update():void
    {
        var s:Stage,
            ax:Number, ay:Number,
            dx:Number, dy:Number;

        s = target.stage;
        //  if missing stage, halt process.
        if (!s) return;

        ax = s.mouseX / s.stageWidth;
        ay = s.mouseY / s.stageHeight;

        dx = MARGIN - (target.width - s.stageWidth + MARGIN * 2) * ax;
        dy = MARGIN - (target.height - s.stageHeight + MARGIN * 2) * ay;

        target.x += (dx - target.x) / 20;
        target.y += (dy - target.y) / 20;

        if (Math.abs(dx - target.x) < 1 && Math.abs(dy - target.y) < 1)
        {
            target.x = dx;
            target.y = dy;

            event(s, MouseEvent.MOUSE_MOVE, moved);
            interrupted(shutdown);
        }
        else
        {
            next(update);
        }
    }

    /**
     *  default interrupted handler.
     */
    private function shutdown(...args):void
    {
        // do nothing.
    }

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


/**
 *  stack flickr image queue.
 */
internal class FlickrImageQueue
{
    private var queue:Array;
    private var monitor:Monitor;

    /**
     *  checking is task empty in queue.
     */
    public function get isEmpty():Boolean
    {
        return queue.length <= 0;
    }

    /**
     *  constructor.
     */
    public function FlickrImageQueue()
    {
        queue = [];
        monitor = new Monitor();
    }

    /**
     *  checking already stack new task into queue.
     */
    public function checkPoll():Boolean
    {
        var f:Boolean = true;

        if (isEmpty)
        {
            f = false;
            monitor.wait();
        }
        return f;
    }

    /**
     *  shift stack task.
     */
    public function poll():Bitmap
    {
        return queue.shift();
    }

    /**
     *
     */
    public function offer(v:Bitmap):void
    {
        //  push new data into queue.
        queue.push(v);
        //  notify all wait task.
        monitor.notifyAll();
    }
}


internal class FlickrPhoto
{
    private var _id:String;
    public function get id():String
    {
        return _id;
    }

    private var _secret:String;
    public function get secret():String
    {
        return _secret;
    }

    private var _server:String;
    public function get server():String
    {
        return _server;
    }

    private var _farm:String;
    public function get farm():String
    {
        return _farm;
    }

    public function get thumbnailURL():String
    {
        return ['http://farm', farm, '.static.flickr.com/', server, '/', id, '_', secret, '_s.jpg'].join('');
    }

    public function FlickrPhoto(data:Object)
    {
        this._id = data['id'] || '';
        this._secret = data['secret'] || '';
        this._server = data['server'] || '';
        this._farm = data['farm'] || '';
    }

    public function toString():String
    {
        return thumbnailURL;
    }
}