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

100,000 Particles Screw Effect

@author Lee
@see http://webnoon.net/entry/플레시-Actionscript-30-10만개-파티클-테스트-mouseX의-비용-체험
// forked from jidolstar's 10만개 입자를 이용한 유체 시뮬레이션 실험 
// forked from nulldesign's Liquid10000
package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.ColorTransform;

    import net.hires.debug.Stats;

    /**
     * @author Lee
     * @see http://webnoon.net/entry/플레시-Actionscript-30-10만개-파티클-테스트-mouseX의-비용-체험
     */
    [SWF(width="465", height="465", backgroundColor="0x000000")];
    public class bitmap_screw extends Sprite {
        private var _positions:Vector.<Particle>;
        private var _bmd:BitmapData;
        private var _len:int=100000;
        private var _colT:ColorTransform;

        public function bitmap_screw() {

            stage.scaleMode=StageScaleMode.NO_SCALE;
            stage.align=StageAlign.TOP_LEFT;
            stage.frameRate=110;

            _positions=new Vector.<Particle>();
            var i:int;
            for (i=0; i < _len; i++) {
                var pt:Particle=new Particle(stage.stageWidth * Math.random(), stage.stageHeight * Math.random());
                _positions.push(pt);
            }

            for (i=0; i < _len - 1; i++) {
                _positions[i].next=_positions[i + 1];
            }

            _colT=new ColorTransform(.9, .9, .8);

            _bmd=new BitmapData(stage.stageWidth, stage.stageHeight, false, 0);
            addChild(new Bitmap(_bmd));

            addEventListener(Event.ENTER_FRAME, loop);
            stage.addEventListener(MouseEvent.CLICK, ch);

            addChild(new Stats());
        }

        private function ch(event:MouseEvent):void {
            var pt:Particle=_positions[0];
            while (pt.next) {
                pt.x=stage.stageWidth * Math.random();
                pt.y=stage.stageHeight * Math.random();
                pt=pt.next;
            }
        }

        private function loop(event:Event):void {

            var pt:Particle=_positions[0];
            var mx:Number, my:Number;
            mx=mouseX;
            my=mouseY;

            _bmd.lock();
            _bmd.colorTransform(_bmd.rect, _colT);
            while (pt.next) {

                //perp 벡터 구해서 force 등록
                var dx:Number=pt.x - mx;
                var dy:Number=pt.y - my;
                //var dx : Number = pt.x - mouseX; //이런식으로 하면 느려서 안된다.
                //var dy : Number = pt.y - mouseY;

                var perpX:Number=-dy;
                var perpY:Number=dx;

                var f:Number=7.0 / (dx * dx + dy * dy);
                perpX*=f;
                perpY*=f;
                dx*=-f;
                dy*=-f;

                pt.vx+=dx + perpX;
                pt.vy+=dy + perpY;

                pt.x+=pt.vx;
                pt.y+=pt.vy;

                pt.vx*=.9;
                pt.vy*=.9;

                _bmd.setPixel(pt.x, pt.y, 0xffffff);
                pt=pt.next;
            }
            _bmd.unlock();
        }
    }
}

final class Particle {
    public var next:Particle;

    public var x:Number, y:Number, vx:Number, vy:Number, ax:Number, ay:Number;


    public function Particle($x:Number, $y:Number) {

        x=$x;
        y=$y;
        vx=vy=ax=ay=0.0;
    }
}