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: tornado

左上の数字はfpsと, パーティクル処理時間の最近60フレームの合計(ms)です.
(60fpsを維持しているなら, 1秒の内この合計値の分だけ, パーティクル処理に時間が割かれています)
Get Adobe Flash player
by matacat 11 Feb 2011
/**
 * Copyright matacat ( http://wonderfl.net/user/matacat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/rTdd
 */

// forked from okoi's tornado
package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.ColorTransform;
    import flash.geom.Rectangle;
    
    [SWF(frameRate=60)]
    public class Main extends Sprite
    {
        private const W:int    = stage.stageWidth;
        private const H:int    = stage.stageHeight;
        private const S:Number = 4 / H;
        
        private var head:Particle;
        private var count:int;
        
        private var cvs:BitmapData;
        private var rect:Rectangle;
        private var ct:ColorTransform;
        
        private var debug:Debug;
        
        public function Main():void
        {
            if (stage) init();
            else       addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            Particle.initArea   = new Rectangle(W / 2, H / 2, W / 4, H / 4);
            Particle.initHeight = H;
            
            head  = new Particle();
            count = 0;
            
            cvs  = new BitmapData(W, H, false);
            rect = new Rectangle();
            ct   = new ColorTransform(1.1, 1.1, 1.1);
            
            addChild(new Bitmap(cvs));
            
            debug = new Debug();
            stage.addChild(debug);
            
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        
        private function enterFrameHandler(e:Event):void
        {
            debug.startSample();
            
            cvs.lock();
            cvs.colorTransform(cvs.rect, ct);
            
            var p:Particle = head,
                tx:Number  = mouseX,
                tz:Number  = H / 2,
                size:int;
            
            Particle.initArea.x = tx;
            
            while (true) {
                if (p.life > 0) {
                    p.move(tx, tz);
                    
                    size = p.z * S + 1;
                    if (size < 2) {
                        cvs.setPixel(p.x >> 0, p.y >> 0, 0x333333);
                    } else {
                        rect.x      = p.x * 2 - size >> 1;
                        rect.y      = p.y * 2 - size >> 1;
                        rect.width  = size;
                        rect.height = size;
                        cvs.fillRect(rect, 0x333333);
                    }
                } else {
                    p.init();
                }
                
                if (p.next) p = p.next;
                else        break;
            }
            
            if (++count < Particle.LIFE_DEF) p.next = new Particle();
            
            cvs.unlock();
            
            debug.endSample();
        }
    }
}

import flash.geom.Rectangle;
import flash.text.TextField;
import flash.utils.getTimer;

class Particle
{
    public static var initArea:Rectangle;
    public static var initHeight:Number;
    
    public  static const LIFE_DEF:int    = 2000;
    private static const ROL_DEF:Number  = 6 / 360 * 2 * Math.PI;
    private static const ROL_SLOW:Number = 511 / 512;
    private static const DIFFUSE:Number  = 257 / 256;
    private static const UPDRAFT:Number  = -7 / 8;
    private static const V_SCALE:Number  = 8;
    
    public var life:Number;
    public var rol:Number;
    public var x:Number;
    public var y:Number;
    public var z:Number;
    public var next:Particle;
    
    public function Particle()
    {
        init();
    }
    
    public function init():void
    {
        life = LIFE_DEF;
        rol  = ROL_DEF;
        x    = (Math.random() - 0.5) * initArea.width + initArea.x;
        y    = initHeight;
        z    = (Math.random() - 0.5) * initArea.height + initArea.y;
    }
    
    public function move(tx:Number, tz:Number):void
    {
        var sin:Number = Math.sin(rol) * DIFFUSE,
            cos:Number = Math.cos(rol) * DIFFUSE,
            vx:Number  = x * (cos - 1) + z * sin       + tx * (1 - cos) + tz * -sin,
            vz:Number  = x * -sin      + z * (cos - 1) + tx * sin       + tz * (1 - cos),
            vy:Number  = UPDRAFT,
            v:Number   = Math.sqrt(vx * vx + vy * vy + vz * vz) / V_SCALE;
        
        x += vx / v;
        y += vy / v;
        z += vz / v;
        
        life--;
        rol *= ROL_SLOW;
    }
}

class Debug extends TextField
{
    private static const NUM_SAMPLE:int = 60;
    
    private var cCnt:int;
    private var cPre:int;
    
    private var sVec:Vector.<int>;
    private var sCnt:int;
    private var sPre:int;
    
    private var output:Boolean;
    
    public function Debug()
    {
        autoSize   = "left";
        border     = true;
        background = true;
        sVec       = new Vector.<int>(NUM_SAMPLE, true);
    }
    
    public function startSample():void
    {
        var cur:int = getTimer();
        cCnt++;
        if (cur - cPre >= 1000) {
            cPre = cur;
            output = true;
        }
        sPre = cur;
    }
    
    public function endSample():void
    {
        var cur:int = getTimer();
        sVec[sCnt]  = cur - sPre;
        sCnt = (sCnt + 1) % NUM_SAMPLE;
        if (output) {
            for (var i:int, sum:int; i < NUM_SAMPLE; i++) sum += sVec[i];
            text = String(cCnt) + "\n" + String(sum);
            cCnt = 0;
            output = false;
        }
    }
}