2009-2-26 爆発エフェクト
package {
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
[SWF(width="320", height="240", backgroundColor="0x000000", frameRate="60")]
public class FlashTest extends Sprite {
private var particles:Array;
private var output:BitmapData;
private var blur:BlurFilter;
private var mouseDownFlag:Boolean;
public function FlashTest() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
particles = new Array();
output = new BitmapData(320, 240, false, 0);
blur = new BlurFilter(2, 2, 1);
mouseDownFlag = false;
addChild(new Bitmap(output));
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onMouseDown(event:Event):void
{
mouseDownFlag = true;
}
private function onMouseUp(event:Event):void
{
mouseDownFlag = false;
}
private function onEnterFrame(event:Event):void
{
// マウスが押されている時は、新しく爆発描画オブジェクトを作成する
if (mouseDownFlag == true) {
addParticle(mouseX, mouseY);
}
render(output);
if (particles.length > 0)
{
// 画面平滑化フィルターを適用
output.applyFilter(output, output.rect, new Point(), blur);
}
}
public function addParticle(x: Number, y: Number):void
{
// 30 個分作成
for (var i:int = 0; i < 30; i++)
{
var particle:Object;
var a: Number;
var s: Number;
a = Math.random() * Math.PI * 2;
s = Math.random() * 10;
particle = new Object;
particle.x = x;
particle.y = y;
particle.sx = Math.cos(a) * s;
particle.sy = Math.sin(a) * s;
particle.energy = 1;
particle.frames = 0;
particles.push(particle);
}
}
public function render(buffer:BitmapData):void
{
var newArray:Array = new Array();
for each (var particle:Object in particles)
{
// ピクセルの色の決定
// 16 ビット分左にシフトすることで赤色を作る
var color:int;
color = int((particle.energy * 0xff) << 16);
// ピクセルのセット
buffer.setPixel(
particle.x,
particle.y,
color);
// 座標の更新
particle.x += particle.sx;
particle.y += particle.sy;
// 爆発速度の減衰
particle.sx *= 0.98;
particle.sy *= 0.98;
// 色の減衰
particle.energy *= 0.98;
// 描画回数の更新
particle.frames++;
// 描画開始から 180 フレーム経過した粒を消去
if (particle.frames < 180) {
newArray.push(particle);
}
}
particles = newArray;
}
}
}