forked from: Flickr Tricks For Aurora Crowley!!(パーティクル部分だけ抜粋)
http://wonderfl.kayac.com/code/448a0195da618461603cb61f9172fc6aff8420cf
↑のパーティクルが集まって絵になるやつをやってみたかったので、その部分だけ抜粋して勉強用に作ってみました。
ちょっと分かりにくいかもしれませんが、コメントも付けました。クリックで再描画です。
// forked from soundkitchen's Flickr Tricks For Aurora Crowley!!
package
{
import flash.system.LoaderContext;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.Security;
/**
* http://wonderfl.kayac.com/code/448a0195da618461603cb61f9172fc6aff8420cf
* ↑のパーティクルが集まって絵になるやつをやってみたかったので、その部分だけ抜粋して勉強用に作ってみました。
* ちょっと分かりにくいかもしれませんが、コメントも付けました。クリックで再描画です。
*
*/
[SWF(width = "465", height = "465", backgroundColor = "0x000000", frameRate = "30")]
public class ParticleKai extends Sprite
{
// 画像パス
private static const IMAGE_PATH:String = "http://yanbaka.com/wonderfl/kote2.jpg";
// ビットマップデータを走査するときのマージン(4ピクセルずつ)
private const POINT_MARGIN:Number = 4;
// 絵が形成される時のスピード
private const SPEED:Number = 10;
// 描画するところ
private var _canvas:BitmapData;
// 開始のポイントたち
private var sPoints:Array = [];
// 終了のポイントたち
private var ePoints:Array = [];
// 退避用のポイントたち
private var tPoints:Array = [];
public function ParticleKai()
{
// ステージサイズで描画ステージを作成
_canvas = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x0);
var bmp:Bitmap = new Bitmap(_canvas);
addChild(bmp);
// 画像をロード
loadImage();
}
private function loadImage():void
{
Security.loadPolicyFile("http://5ivestar.org/proxy/crossdomain.xml");
var context:LoaderContext = new LoaderContext(true);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest("http://5ivestar.org/proxy/"+IMAGE_PATH), context);
}
private function onComplete(e:Event):void
{
var loader:Loader = Loader(e.target.loader);
var bmd:BitmapData = Bitmap(loader.content).bitmapData;
// ロードしたビットマップデータをx,y軸共に4ピクセルずつ走査し、終了のポイントたちにxとyとカラーを格納
for (var i:int=0; i<bmd.width; i+=POINT_MARGIN)
{
for (var ii:int=0; ii<bmd.height; ii+=POINT_MARGIN)
{
pushPixel(bmd, i, ii);
}
}
// 開始のポイントたちに格納し、描画(開始位置)
setPixelImage();
// 移動スタート
addEventListener(Event.ENTER_FRAME, update);
// ステージがクリックされたら初めから
stage.addEventListener(MouseEvent.CLICK, restart);
}
private function restart(e:MouseEvent):void
{
// 初期化
sPoints = [];
removeEventListener(Event.ENTER_FRAME, update);
_canvas.fillRect(_canvas.rect, 0x0);
// 開始位置をランダムで配置し、それを開始のポイントたちに格納
setPixelImage();
// 移動スタート
addEventListener(Event.ENTER_FRAME, update);
}
private function update(evt:Event):void
{
// キャンバスをロック
_canvas.lock();
// キャンバスにブラーフィルタ適用
_canvas.applyFilter(_canvas, _canvas.rect, new Point(), new BlurFilter());
// 終了ポイントたちをスライスでコピー
tPoints = [];
tPoints = ePoints.slice(0);
// ポイント分移動
var i:int = tPoints.length;
while (i--)
{
var s:Particle = sPoints[i];
var e:Particle = ePoints[i];
// 徐々に終了ポイントに近づける
s.x += (e.x - s.x)/SPEED;
s.y += (e.y - s.y)/SPEED;
// 開始ポイントと終了ポイントの差が1未満の場合、終了ポイントを開始ポイントにしてしまう。で、そのポイントを消す。
if(Math.abs(e.x - s.x) < 1.0 || Math.abs(e.y - s.y) < 1.0)
{
s.x = e.x;
s.y = e.y;
tPoints.splice(i, 1);
}
_canvas.setPixel32(s.x, s.y, e.c);
}
// キャンバスのロック解除
_canvas.unlock();
// コピーしたポイント数が0になったらループを止める。
if(tPoints.length <= 0)
{
removeEventListener(Event.ENTER_FRAME, update);
}
}
private function pushPixel(bmd:BitmapData, x:Number, y:Number):void
{
// ピクセルのx,y,カラーを格納
var p:Particle = new Particle();
p.x = x;
p.y = y;
p.c = bmd.getPixel32(x, y);
ePoints.push(p);
}
private function setPixelImage():void
{
var l:int = ePoints.length;
for (var i:int=0; i<l; i++)
{
var p:Particle = new Particle();
// 画面内にランダムで配置
p.x = Math.random()*stage.stageWidth;
p.y = Math.random()*stage.stageHeight;
// スタート位置の描画
_canvas.setPixel32(p.x, p.y, ePoints[i].c);
sPoints.push(p);
}
}
}
}
// パーティクル情報保持クラス
class Particle
{
public var x:Number;
public var y:Number;
public var c:uint;
public function Particle() {}
}