package {
import gs.TweenMax;
import gs.easing.*;
import gs.events.TweenEvent;
import flash.display.*;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.geom.Rectangle;
import flash.geom.Point;
public class ReconstructionImage extends MovieClip {
//表示オブジェクト
public var obj:DisplayObject;
//放出位置
public var beginX:Number;
public var beginY:Number;
//まとめて放出する際の個数
public var flocks:uint;
//参照を残すための配列群
private var rects:Array = new Array();
private var coords:Array = new Array();
private var tws:Array = new Array();
//コンストラクタ
public function ReconstructionImage(_o:DisplayObject, _bx:Number = 0, _by:Number = 0, _fl:uint = 4)
{
obj = _o;
beginX = _bx;
beginY = _by;
flocks = _fl;
init(obj)
}
//初期化
private function init(o:DisplayObject):void
{
//与えられたオブジェクトをBitmapDataに変換
var bd:BitmapData = new BitmapData(o.width,o.height,true,0x00000000)
bd.draw(o);
//BitmapDataを(0,0)から枚挙
for (var _x:uint = 0; _x < bd.width; _x++) {
for (var _y:uint = 0; _y < bd.height; _y++) {
var color:uint = bd.getPixel(_x, _y);
//Spriteを作り、該当位置の色の四角形を作成する。
var tbd:BitmapData = new BitmapData(1, 1 , true , bd.getPixel32(_x, _y));
var dot:Bitmap = new Bitmap(tbd);
//目標位置を記録するオブジェクトを作成
var d:Object = new Object();
d._x = _x*1;
d._y = _y * 1;
//それぞれ保管する
rects.push(dot);
coords.push(d);
//ドットを表示しておく
dot.x = beginX;
dot.y = beginY;
}
}
}
//実行
public function start() {
var timer:Timer = new Timer(1, Math.ceil(rects.length/flocks));
timer.addEventListener(TimerEvent.TIMER, moveRects);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, finishReconstruction);
timer.start();
}
//ドットを移動させる関数
private function moveRects(e:TimerEvent):void
{
for (var i:uint = 0; i < flocks;i++){
var count:uint = (e.target.currentCount - 1) * flocks + i;
if (rects[count]) {
var s:DisplayObject = rects[count];
s.x = beginX;
s.y = beginY;
addChild(s);
var ep:Object = coords[count];
var sec:Number = Math.random()/4 + 0.25;
var twx:TweenMax = new TweenMax(s, sec, { x:ep._x, ease:Linear.easeOut ,runBackwards:false});
var twy:TweenMax = new TweenMax(s, sec, { y:ep._y, ease:originEase ,runBackwards:false});
tws.push(twx,twy);
}
}
}
//TIMER_COMPLETEしたら実行
private function finishReconstruction(e:TimerEvent):void
{
//一応1000ミリ秒待ってから
var timer:Timer = new Timer(1000,1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, finishReconstructionHandler);
timer.start();
}
//イメージの再構成が終わったら実行
private function finishReconstructionHandler(e:TimerEvent):void
{
//全てのドットを削除
for each (var rect in rects) {
removeChild(rect)
}
//保持配列をクリア
rects = new Array();
coords = new Array();
tws = new Array();
//分解前の画像を表示
addChild(obj);
}
//イージング関数
private function originEase(t:Number, b:Number, c:Number, d:Number):Number {
var ts:Number=(t/=d)*t;
var tc:Number=ts*t;
return b+c*(42.29629629629623*tc*ts + -198.76543209876544*ts*ts + 259.13580246913585*tc + -122.96296296296296*ts + 21.296296296296298*t);
}
}
}
カタマリのとは大分違った感じですが、まぁそれなりなハズ(w
使い方は
obj1 = new ReconstructionImage(DisplayObject,x,y,n);
addChild(obj1);
obj1.start()
といった感じで。xとyは砂が飛び出す位置、nは一度に舞う砂の数。
プログラムの流れは
- 引数で渡されたDisplayObjectをBitmapDataに変換
- (0,0)から1pxごとに分解し、配列に格納(同時に元の座標も格納)
- 配列を枚挙してTweenで飛ばす
- 完了したら元のDisplayObjectと差し替える
FlashのTweenライブラリではちょっと動作がもたつくので、TweenMaxを使ってみた。速い速いと聞くけど、そんなに大差ないと思っていましたが、使ってみてその速度に驚きました。ただ精度が標準と比べて落ちるようで、飛び方が荒くなりましたが、今回のようなケースでは、精度より速さ。今後もケースに応じて使ってみたいと思います。
It seems that you've put a good amount of effort into your article and I demand a lot more of these on the World Wide Web these days. I truly got a kick out of your post. I do not have a bunch to to say in response, I only wanted to register to say exceptional work.