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

// forked from ll_koba_ll's Boid
package
{

    import flash.display.*;
    import flash.events.*;
    import flash.geom.*;
    import flash.filters.*;
    import com.flashdynamix.utils.SWFProfiler;

    [SWF(width="300", height="300", frameRate="30", backgroundColor="#000000")]    
    public class BoidSketch extends Sprite
    {
        private const FISH_NUM:int = 50;
        
        private var _canvas:BitmapData;
        private var _firstFish:Fish;
        private var _fishView:FishView = new FishView();
        private var _blurFilter:BlurFilter;

        private var _tmpPoint:Point = new Point();

        public function BoidSketch()
        {
            addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event):void
        {
            SWFProfiler.init(this);
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;

            removeEventListener(Event.ADDED_TO_STAGE, init);

            _canvas = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x00FFFFFF);
            addChild(new Bitmap(_canvas));
            
            var prevFish:Fish = new Fish();
            _firstFish = prevFish;
            // fishつくる
            for (var i:int=0; i<FISH_NUM; i++)
            {
                prevFish.next = new Fish();
                prevFish = prevFish.next;
                prevFish.firstFish = _firstFish;
                prevFish.stageWidth = _canvas.width;
                prevFish.stageHeight = _canvas.height;
                prevFish.x = Math.random()*_canvas.width;
                prevFish.y = Math.random()*_canvas.height;
                prevFish.vx = FishUtil.rangeRandom(-3, 3);
                prevFish.vy = FishUtil.rangeRandom(-3, 3);
            }

            addEventListener(Event.ENTER_FRAME, loop);

            _blurFilter = new BlurFilter(2,2);

        }


        private function loop(e:Event):void
        {
            var f:Fish = _firstFish;

            _canvas.lock();
            //_canvas.fillRect(_canvas.rect, 0x000000);

            while((f = f.next) != null)
            {
                f.update();
                var mtx:Matrix = new Matrix()
                mtx.translate(f.x, f.y);
                _canvas.draw(_fishView, mtx);
            }
            // ブラ-とってもおもろい
            _canvas.applyFilter(_canvas, _canvas.rect, _tmpPoint, _blurFilter);
            _canvas.unlock();
        }    


        
    }
}

import flash.display.*;
import flash.geom.*;
class Fish 
{
    
    private const DIST_THRESHOLD1:int = 10;
    private const DIST_THRESHOLD2:int = 20;
    private const DIST_THRESHOLD3:int = 30;
    private const FACTOR_CHOHESION:Number = 100;
    private const FACTOR_SEPARATION:Number = 10;
    private const FACTOR_ALINGMENT:Number = 10;
    private const VELOCITY_LIMIT:Number = 3;
    private var r1:Number = 1.0;
    private var r2:Number = 0.8;
    private var r3:Number = 0.1;

    public function Fish()
    {
    }

    public var next:Fish;

    public var vx:Number = 0;
    public var vy:Number = 0;
    public var x:Number = 0;
    public var y:Number = 0;
    public var rotation:Number;
    public var scale:Number;
    
    public var stageWidth:Number = 0;
    public var stageHeight:Number = 0;

    public var firstFish:Fish;
    
    private var p1:Point;
    private var p2:Point;
    private var p3:Point;
    private var _tmpPoint:Point = new Point();

    public function update():void
    {
        if (firstFish == null) return;

        p1 = _tmpPoint.clone(); 
        p2 =  _tmpPoint.clone(); 
        p3 = _tmpPoint.clone(); 
        
        cohesion();
        separation();
        alignment();

        vx += r1*p1.x + r2*p2.x + r3*p3.x;
        vy += r1*p1.y + r2*p2.y + r3*p3.y;

        limitVelocity();

        x += vx;
        y += vy;

        if (stageWidth != 0)
        {
            if (x < 0)
            {
                x = stageWidth;
            }
            else if (x > stageWidth)
            {
                x = 0;
            }
        }

        if (stageHeight != 0)
        {
            if (y < 0)
            {
                y = stageHeight;
            }
            else if (y > stageHeight)
            {
                y = 0;
            }
        }


            
    }


    private function limitVelocity():void
    {
        var v:Number = Math.sqrt(vx*vx + vy*vy);
        if (v > VELOCITY_LIMIT)
        {
            vx = (vx/v)*VELOCITY_LIMIT;
            vy = (vy/v)*VELOCITY_LIMIT;
        }
    }

    // 効率悪い気がするけどとりあえず分かりやすく

    // rule1 Cohesion
    private function cohesion():void
    {
        var f:Fish = firstFish;
        var len:Number = 0;
        var count:int = 0;
        while((f = f.next) != null)
        {
            if ( this != f)
            {
                len = FishUtil.dist(this, f);
                if (len > DIST_THRESHOLD2 && len < DIST_THRESHOLD3)
                {
                    p1.x += f.x;
                    p1.y += f.y;
                    count++;
                }
            }
        }
        if (count > 0)
        {
            p1.x /= count;
            p1.y /= count;
            p1.x = (p1.x - x) / FACTOR_CHOHESION;
            p1.y = (p1.y - y) / FACTOR_CHOHESION;
        }
    }

    // rule2 Separation
    private function separation():void
    {
        var len:Number = 0;
        var f:Fish = firstFish;
        while((f = f.next) != null)
        {
            if (this != f)
            {
                len = FishUtil.dist(this, f);
                if (len < DIST_THRESHOLD1)
                {
                    p2.x -= (f.x - x)/FACTOR_SEPARATION;
                    p2.y -= (f.y - y)/FACTOR_SEPARATION;
                }
            }
        }
    }

    // rule3 Alingment
    private function alignment():void
    {
        var f:Fish = firstFish;
        var len:Number = 0;
        var count:int = 0;
        while((f = f.next) != null)
        {
            if ( this != f)
            {
                len = FishUtil.dist(this, f);
                if (len > DIST_THRESHOLD1 && len < DIST_THRESHOLD1)
                {
                    p3.x += f.vx;
                    p3.y += f.vy;
                    count++;
                }
            }
        }

        if (count > 0)
        {
            p3.x /= count;
            p3.y /= count;
            p3.x = (p3.x - vx)/FACTOR_ALINGMENT;
            p3.y = (p3.y - vy)/FACTOR_ALINGMENT;
        }
    }
}

class FishView extends Sprite
{
    public function FishView()
    {
        var g:Graphics = graphics;
       
        g.lineStyle(1, 0xFFFFFF);
        g.drawRect(0,0,1,1);
        g.endFill();
        /*
        g.moveTo(0,0);
        g.lineTo(-15, 6);
        g.lineTo(-15, -6);
        g.lineTo(0,0);
        */
    }
}

class FishUtil
{
    public static function dist(f1:Fish, f2:Fish):Number
    {
        {
            var dx:Number = f1.x - f2.x;
            var dy:Number = f1.y - f2.y;
            return Math.sqrt(dx*dx + dy*dy);
        }
    }

    public static function rangeRandom(min:Number, max:Number):Number   {                                                          
        return Math.floor(Math.random()*(max-min+1))+min;
    }
}