Beautifl - Flash Gallery

Thumbnail : TwitterBird
TwitterBird
paq 2009-11-16 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

// forked from uwi's ふよふよ
// 元ネタはコレ http://www.whatisfailwhale.info/
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;
	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.tweens.ITween;
	import org.libspark.betweenas3.easing.Cubic;
	import frocessing.shape.FShapeSVG;
	
    [SWF(width=465, height=465, backgroundColor=0x000000, frameRate=60)]
    public class TwitterBird extends Sprite
	{
        private var _bullets : Array;
        private var _myx : Point;
        private var _myv : Point;
        private const R_BULLET : Number = 20.0;
        
        private var _tf : TextField;
        private var _space : BitmapData;
        
        private var _avs : Array; // <Avoider>
        
        private const P0 : Point = new Point(0, 0);
        
        public function TwitterBird()
		{
            Wonderfl.capture_delay(5);
            SWFProfiler.init(this);
            
            // 宇宙
            _space = new BitmapData(465, 465, false, 0x6CC5C3);
            var bmpspace : Bitmap = new Bitmap(_space);
            addChild(bmpspace);
			
			var svg:XML = <svg><g>	<path fill="#FFFFFF" d="M495.498,20.332c-13.752,0-28.352-9.762-33.87-19.307c-5.693,9.545-20.712,19.307-34.463,19.307		s-28.353-9.762-33.87-19.307c-5.693,9.545-20.711,19.307-34.463,19.307s-28.352-9.762-33.87-19.307		c-5.693,9.545-20.712,19.307-34.463,19.307s-28.353-9.762-33.87-19.307c-5.693,9.545-20.711,19.307-34.463,19.307		s-28.352-9.762-33.87-19.307c-5.693,9.545-20.712,19.307-34.463,19.307c-14.178,0-29.264-10.375-34.362-20.193		C114.207,9.957,98.678,20.332,84.5,20.332C70.255,20.332,55.097,9.859,50.069,0h-0.196c-5.189,9.859-20.795,20.332-35.04,20.332		c-4.99,0-10.092-1.289-14.833-3.383V56h531V0h-0.462C525.349,9.859,509.743,20.332,495.498,20.332z"/></g></svg>
			var fshape:FShapeSVG = new FShapeSVG(svg);
			var whitewave:Sprite = addChild(fshape.toSprite()) as Sprite;
			whitewave.x = -34
			whitewave.y = 410
			var t:ITween = BetweenAS3.serial(
				BetweenAS3.tween(whitewave, { y: 420 }, null, 3.0 , Cubic.easeInOut),
				BetweenAS3.tween(whitewave, { y: 400 }, null, 3.0 , Cubic.easeInOut),
				BetweenAS3.tween(whitewave, { y: 410 }, null, 3.0 , Cubic.easeInOut)
			);
			t.stopOnComplete = false;
			t.play();
			
			svg = <svg><g>	<path fill="#F15A22" d="M495.498,20.332c-13.752,0-28.352-9.762-33.87-19.307c-5.693,9.545-20.712,19.307-34.463,19.307		s-28.353-9.762-33.87-19.307c-5.693,9.545-20.711,19.307-34.463,19.307s-28.352-9.762-33.87-19.307		c-5.693,9.545-20.712,19.307-34.463,19.307s-28.353-9.762-33.87-19.307c-5.693,9.545-20.711,19.307-34.463,19.307		s-28.352-9.762-33.87-19.307c-5.693,9.545-20.712,19.307-34.463,19.307c-14.178,0-29.264-10.375-34.362-20.193		C114.207,9.957,98.678,20.332,84.5,20.332C70.255,20.332,55.097,9.859,50.069,0h-0.196c-5.189,9.859-20.795,20.332-35.04,20.332		c-4.99,0-10.092-1.289-14.833-3.383V56h531V0h-0.462C525.349,9.859,509.743,20.332,495.498,20.332z"/></g></svg>
			fshape = new FShapeSVG(svg);
			var wave:Sprite = addChild(fshape.toSprite()) as Sprite;
			wave.y = 410
			t = BetweenAS3.serial(
				BetweenAS3.tween(wave, { y: 420 }, null, 5.0 , Cubic.easeInOut),
				BetweenAS3.tween(wave, { y: 435 }, null, 5.0 , Cubic.easeInOut),
				BetweenAS3.tween(wave, { y: 410 }, null, 5.0 , Cubic.easeInOut)
			);
			t.stopOnComplete = false;
			t.play();
            
            _myx = new Point(465 / 2, 465 / 2);
            _myv = new Point(0, 0);
            _bullets = [];
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            
            _avs = [];
            for (var i : int = 0; i < 8; i++)
			{
                addBullet();
                _avs.push(new Avoider(_bullets, 465, 0, 465, 0, R_BULLET, 0.4, 0.4, 0.2, 0.2, _bullets[i]));
            }
        }
        
        private function onEnterFrame(e : Event) : void
        {
            var i : int = 0;
            for each(var b : Bullet in _bullets)
			{
                var a : Array = _avs[i].algo(b.x, b.y, b.v.x, b.v.y, 1);
                b.v.x += a[0];
                b.v.y += a[1];
                b.x += b.v.x;
                b.y += b.v.y;
				if (Math.ceil(Math.random() * 30) == 1)
				{
					if (b.scaleX == -1) 
					{
						BetweenAS3.tween(b, { scaleX:1 }, null, 1.0+Math.random(), Cubic.easeOut).play();
					}
					else if(b.scaleX == 1) 
					{
						BetweenAS3.tween(b, { scaleX: -1 }, null, 1.0+Math.random(), Cubic.easeOut).play();
					}
				}
                i++;
            }
        }
        
        // 弾追加
        private function addBullet() : void
        {
            var x : Point = new Point(65+Math.random() * 400, 65+Math.random() * 350);
//            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.x;
			b.y = x.y;
            b.v = v;
            b.r = R_BULLET;
            _bullets.push(b);
			addChild(b);
        }
        
    }
}

import flash.display.Sprite;
import flash.geom.Point;
import frocessing.shape.FShapeSVG;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.easing.Cubic;
class Bullet extends Sprite
{
    public var p : Point;
    public var v : Point;
    public var r : Number;
	
	public function Bullet():void
	{
		super();
		var svg:XML = <svg><path fill="#F15A22" d="M0,16.609c0,0,2.959-2.25,3.084-2.791c0.125-0.543,2.459-4.709,6.375-4.709s7.916,6.25,9.833,6.25	s-1.5-2.833,2.25-7.25c5.493-6.469,13-4,14.083-8c0.263-0.972,2.584,4.75,2.584,9.083c0,4.333-3.417,9.917-3.417,9.917	s0.417,0.666,2.5,0.666s5.75-3.5,5.75-3.5s2.834,19.417-19.584,19.417c-6.481,0-14.372-5.372-16.811-11.433	c-0.988-2.455-0.428-4.499-2.781-6.188C3.394,17.732,0.621,16.137,0,16.609z"/><path fill="#FFFFFF" d="M24.542,16.359c2.931,3.35,13-1.75,8-11C32.542,5.359,19.292,10.359,24.542,16.359z"/><circle fill="#FFFFFF" cx="8.126" cy="13.86" r="1.777"/></svg>
		var fshape:FShapeSVG = new FShapeSVG(svg);
		var sprite:Sprite = addChild(fshape.toSprite()) as Sprite;
		sprite.x = -21.5;
		
		var t:ITween = BetweenAS3.serial(
			BetweenAS3.tween(sprite, { rotation: 20 }, null, 1.0+Math.random()*2 , Cubic.easeInOut),
			BetweenAS3.tween(sprite, { rotation: 0 }, null, 1.0+Math.random()*2 , Cubic.easeInOut),
			BetweenAS3.tween(sprite, { rotation: -30 }, null, 1.0+Math.random()*2 , Cubic.easeInOut),
			BetweenAS3.tween(sprite, { rotation: 0 }, null, 1.0+Math.random()*2 , Cubic.easeInOut)
		);
		t.stopOnComplete = false;
		t.play();
	}
}

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 + b.v.x * dt);
            var rxy : Number = xy - (b.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;
        }
    }
}