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

みんなでふよふよ

互いに互いを回避
これが現代社会の縮図
Get Adobe Flash player
by uwi 14 Nov 2009
/**
 * Copyright uwi ( http://wonderfl.net/user/uwi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/oAnj
 */

// forked from uwi's ふよふよ
// 互いに互いを回避
// これが現代社会の縮図
package {
    import com.flashdynamix.utils.SWFProfiler;
    
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.Graphics;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.filters.BitmapFilter;
    import flash.filters.GradientBevelFilter;
    import flash.filters.BlurFilter;
    import flash.utils.Timer;
    import flash.utils.getTimer;
    import flash.geom.Point;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.display.BlendMode;
    [SWF(width=465, height=465, backgroundColor=0x000000, frameRate=60)]
    public class Hirari extends Sprite {
        private var _bullets : Array;
        private var _ct : int;
        private var _myx : Point;
        private var _myv : Point;
        private var _nhit : int;
        private const R_BULLET : Number = 10.0;
        
        private var _tf : TextField;
        private var _space : BitmapData;
        private var _bgspace : BitmapData;
        private var _shapeself : Shape;
        
        private var _bmdbullet : BitmapData;
        private var _avs : Array; // <Avoider>
        
        private const P0 : Point = new Point(0, 0);
        private const WEAKBLUR : BitmapFilter = new BlurFilter(2.0, 2.0);
        
        public function Hirari() {
            Wonderfl.capture_delay(5);
            SWFProfiler.init(this);
            
            // 宇宙
            _space = new BitmapData(465, 465, false, 0x000000);
            var bmpspace : Bitmap = new Bitmap(_space);
            addChild(bmpspace);
            
            var shs : Shape = new Shape();
            var mat : Matrix = new Matrix();
            mat.createGradientBox(465, 465, 0, 0, 0);
            shs.graphics.beginGradientFill(
                "linear",
                [0x333377, 0x000000],
                [1, 1],
                [0, 255],
                mat
                );
            shs.graphics.drawRect(0, 0, 465, 465);
            shs.graphics.endFill();
            _bgspace = new BitmapData(465, 465, false, 0x000000);
            _bgspace.draw(shs);
                            
            _shapeself = new Shape();
            
            // 弾描画
            var bevel : BitmapFilter = new GradientBevelFilter(4.0, 45, [0xffffff, 0x0000ff], [1.0, 1.0], [70, 255], 4.0, 4.0, 1, 2, "inner");
            var sh : Shape = new Shape();
            var g : Graphics = sh.graphics;
            g.lineStyle(1.0, 0x999999);
            g.beginFill(0xeeeeee);
            g.drawCircle(R_BULLET, R_BULLET, R_BULLET);
            g.endFill();
            _bmdbullet = new BitmapData(R_BULLET * 2, R_BULLET * 2, true, 0x00000000);
            _bmdbullet.draw(sh);
            _bmdbullet.applyFilter(_bmdbullet, _bmdbullet.rect, P0, bevel);
            _bmdbullet.applyFilter(_bmdbullet, _bmdbullet.rect, P0, WEAKBLUR);
            
            _myx = new Point(465 / 2, 465 / 2);
            _myv = new Point(0, 0);
            _bullets = [];
            _ct = 0;
            _nhit = 0;
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            
            _avs = [];
            for(var i : int = 0;i < 12;i++){
                addBullet();
                _avs.push(new Avoider(_bullets, 465, 0, 465, 0, R_BULLET, 0.4, 0.4, 0.2, 0.2, _bullets[i]));
            }
            
            // デバッグ用
            _tf = new TextField();
            _tf.autoSize = "left";
//            _tf.text = "" + _bmd.width + "\t" + _bmd.height;
            _tf.textColor = 0xffffff;
            _tf.borderColor = 0xffffff;
            _tf.border = true;
            addChild(_tf);
        }
        
        private function onEnterFrame(e : Event) : void
        {
            draw();
            judge();
            
            _ct++;
            
            var i : int = 0;
            for each(var b : Bullet in _bullets){
                var a : Array = _avs[i].algo(b.x.x, b.x.y, b.v.x, b.v.y, 1);
                b.v.x += a[0];
                b.v.y += a[1];
                b.x.x += b.v.x;
                b.x.y += b.v.y;
                i++;
            }
            _tf.text = 
                "time : " + _ct; 
                /* + 
                "\nhit : " + _nhit + 
                "\nbullets : " + _bullets.length +
                "\nval : " + _av._val;
                */
//                "\n" + a;
        }
        
        // 弾削除
        private function removeBullet(i : int) : void
        {
            if(i < _bullets.length - 1){
                _bullets[i] = _bullets.pop();
            }else{
                _bullets.pop();
            }
        }
        
        // 当たり判定
        private function judge() : void
        {
            for(var i : int = _bullets.length - 1;i >= 0;i--){
                var b : Bullet = _bullets[i];
                if(b.x.x < 0 || b.x.x > 465.0 || b.x.y < 0 || b.x.y > 465.0){
                    var x : Point = new Point(Math.random() * 465, Math.random() * 465);
                    var v : Point = new Point(Math.random() * 0.2 - 0.1, Math.random() * 0.2 - 0.1);
                    b.x = x;
                    b.v = v;
                }
            }
        }
        
        // 描画
        private function draw() : void
        {
            _space.lock();
//            _space.fillRect(_space.rect, 0x000000);
            _space.copyPixels(_bgspace, _bgspace.rect, P0);
            
            /*
            var g : Graphics = _shapeself.graphics;
            g.clear();
            
            // self
            g.lineStyle(1.0, 0x333399);
            g.beginFill(0x3333ff);
            g.drawCircle(_myx.x, _myx.y, 5);
            g.endFill();
            _space.draw(_shapeself, null, null, BlendMode.ADD);
            */
            
            // bullets
            for each(var b : Bullet in _bullets){
                _space.copyPixels(_bmdbullet, _bmdbullet.rect,
                    new Point(b.x.x - R_BULLET, b.x.y - R_BULLET));
            }
            
            _space.unlock();
        }
        
        // 弾追加
        private function addBullet() : void
        {
            var x : Point = new Point(Math.random() * 465, Math.random() * 465);
//            var v : Point = new Point(Math.random() * 5 + 2, Math.random() * 4 - 2);
            var v : Point = new Point(Math.random() * 0.2 - 0.1, Math.random() * 0.2 - 0.1);
            var b : Bullet = new Bullet();
            b.x = x;
            b.v = v;
            b.r = R_BULLET;
            _bullets.push(b);
        }
        
    }
}

import flash.geom.Point;
class Bullet
{
    public var x : Point;
    public var v : Point;
    public var r : Number;
}

class Avoider
{
    private var _bullets : Array;
    private var MAXXX : Number;
    private var MINXX : Number;
    private var MAXXY : Number;
    private var MINXY : Number;
    private var MYR : Number;
    private var LIMAX : Number;
    private var LIMAY : Number;
    private var STEPAX : Number;
    private var STEPAY : Number;
    
    public var _val : Number;
    private var _self : Bullet;
    
    public function Avoider(
        bullets : Array,
        maxxx : Number, minxx : Number,
        maxxy : Number, minxy : Number,
        myr : Number,
        limax : Number, limay : Number,
        stepax : Number, stepay : Number,
        self : Bullet
    ) : void
    {
        _bullets = bullets;
        MAXXX = maxxx; MINXX = minxx;
        MAXXY = maxxy; MINXY = minxy;
        MYR = myr;
        LIMAX = limax; LIMAY = limay;
        STEPAX = stepax; STEPAY = stepay;
        _self = self;
    }
    
    // もっとも長い時間生き残れる加速度の組を返す
    public function algo(xx : Number, xy : Number, vx : Number, vy : Number, depth : int) : Array
    {
        var ret : Array = [0.0, 0.0];
        var maxval : Number = 0;
        for(var ax : Number = -LIMAX;ax <= LIMAX;ax += STEPAX){
            for(var ay : Number = -LIMAY;ay <= LIMAY;ay += STEPAY){
                // 最低速度を設ける
                if((vx + ax) * (vx + ax) + (vy + ay) * (vy + ay) < 0.3)continue;
                var val : Number = algoCore(xx, xy, vx, vy, ax, ay, 0, depth);
                if(maxval < val){
                    maxval = val;
                    ret[0] = ax;
                    ret[1] = ay;
                }
            }
        }
        _val = maxval;
        return ret;
    }
    
    private function algoCore(xx : Number, xy : Number, vx : Number, vy : Number, ax : Number, ay : Number, dt : int, depth : int) : Number
    {
        var mint : Number = 50;
        
        // wall
        var t : Number;
        t = solveQPositive(ax, vx, xx - (MAXXX - MYR)); if(!isNaN(t) && t < mint)mint = t;
        t = solveQPositive(ax, vx, xx - (MINXX + MYR)); if(!isNaN(t) && t < mint)mint = t;
        t = solveQPositive(ay, vy, xy - (MAXXY - MYR)); if(!isNaN(t) && t < mint)mint = t;
        t = solveQPositive(ay, vy, xy - (MINXY + MYR)); if(!isNaN(t) && t < mint)mint = t;
        
        // bullet
        for each(var b : Bullet in _bullets){
            if(b == _self)continue;
            
            var mybr2 : Number = (MYR + b.r) * (MYR + b.r);
            var rxx : Number = xx - (b.x.x + b.v.x * dt);
            var rxy : Number = xy - (b.x.y + b.v.y * dt);
            var rvx : Number = vx - b.v.x;
            var rvy : Number = vy - b.v.y;
            for(t = 0;t < mint;t++){
                if(rxx * rxx + rxy * rxy <= mybr2)break;
                rvx += ax;
                rvy += ay;
                rxx += rvx;
                rxy += rvy;
            }
            mint = t;
        }
        
        if(mint >= 1 && depth >= 1){
            // recursion
            var maxval : Number = 0;
            var tt : int = mint - 1;
            var newxx : Number = (ax * (tt + 1) / 2 + vx) * tt + xx;
            var newxy : Number = (ay * (tt + 1) / 2 + vy) * tt + xy;
            var newvx : Number = ax * tt + vx;
            var newvy : Number = ay * tt + vy;
            for(var newax : Number = -LIMAX;newax <= LIMAX;newax += STEPAX){
                for(var neway : Number = -LIMAY;neway <= LIMAY;neway += STEPAY){
                    var val : Number = algoCore(newxx, newxy, newvx, newvy, newax, neway, dt + tt, depth - 1);
                    if(maxval < val){
                        maxval = val;
                    }
                }
            }
            mint += maxval;
        }
        
        return mint;
    }
    
    // 0以上の最小解を求める
    private static function solveQPositive(a : Number, b : Number, c : Number) : Number
    {
        if(a > -0.0001 && a < 0.0001){
            return -c / b;
        }else{
            var D : Number = b * b - 4 * a * c;
            if(D < 0)return Number.NaN;
            var sqd : Number = Math.sqrt(D);
            var a1 : Number = (-b - sqd) / (2 * a);
            var a2 : Number = (-b + sqd) / (2 * a);
            if(a < 0){
                var d : Number = a1; a1 = a2; a2 = d;
            }
            if(a1 >= 0)return a1;
            if(a2 >= 0)return a2;
            return Number.NaN;
        }
    }
}