TwitterBird
元ネタはコレ http://www.whatisfailwhale.info/
/**
* Copyright paq ( http://wonderfl.net/user/paq )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jHOq
*/
// 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;
}
}
}