forked from: flash on 2009-11-17
消え方が美しくなかったので
各Particleにライフを導入
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/sWMm
*/
// forked from littlepad's flash on 2009-11-17
package {
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.BlendMode;
import flash.geom.Rectangle;
import flash.geom.ColorTransform;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.geom.Point;
import flash.filters.BlurFilter;
import flash.geom.Matrix;
import flash.utils.Timer;
import flash.display.PixelSnapping;
// 消え方が美しくなかったので
// 各Particleにライフを導入
[SWF(width = "465", height = "465", backgroundColor = "0x000000", frameRate = "30")]
public class FlashTest extends Sprite {
//ステージの幅・高さ
private const WIDTH:Number = 465;
private const HEIGHT:Number = 465;
//パーティクルを管理するための配列
private var _particles:Array;
//キャンバス(エフェクトをかける前の元データ)
private var _canvas:BitmapData;
//キャンバスの上に置くBitmapData(エフェクト用)
private var _glow:BitmapData;
//矩形情報
private var _rect:Rectangle;
//色情報
private var _cTra:ColorTransform;
//Timerクラスオブジェクト
private var _timer:Timer;
//花火の中心位置を一時的に保持するための変数
private var _sx:Number;
private var _sy:Number;
public function FlashTest() {
init();
}
private function init():void {
_particles = new Array();
//キャンバスBitmapを作成
_canvas = new BitmapData(WIDTH, HEIGHT, false, 0x000000);
addChild(new Bitmap(_canvas));
//Glowエフェクト用Bitmapを作成
_glow = new BitmapData(WIDTH/4, HEIGHT/4, false, 0x000000);
var bm:Bitmap = new Bitmap(_glow, PixelSnapping.NEVER, true);
//var bm:Bitmap = new Bitmap(_glow);
bm.scaleX = bm.scaleY = 4;
bm.blendMode = BlendMode.ADD;
addChild(bm);
//ステージサイズの矩形範囲を設定
//blurFilter、colorTransformをかける時に使用
_rect = new Rectangle(0, 0, WIDTH, HEIGHT);
//色を全体に落とす
_cTra = new ColorTransform(.8, .8, .9, 1);
this.stage.addEventListener(Event.ENTER_FRAME, enterframeHandler);
_timer = new Timer(100);
_timer.addEventListener(TimerEvent.TIMER, resetFunc);
_timer.start();
}
private function resetFunc(e:TimerEvent):void {
(_cTra.redMultiplier > 0.9) ? _cTra.redMultiplier = 0.8 : _cTra.redMultiplier += 0.01;
hanabi();
}
private function hanabi():void {
//見えない花火を作る
//この花火の位置情報を元にupdate関数で_canvasに花火を描く
var i:int = 200;
_sx = Math.random() * WIDTH;
_sy = Math.random() * HEIGHT;
while(i--) createParticle();
}
private function createParticle():void {
//花火用のパーティクルを生成
var p:Particle = new Particle();
p.x = _sx;
p.y = _sy;
//var radius:Number = 30;
var radius:Number = 10 * Math.random();
var angle:Number = Math.random() * Math.PI * 2;
p.vx = Math.cos(angle) * radius;
p.vy = Math.sin(angle) * radius;
_particles.push(p);
}
private function enterframeHandler(e:Event):void {
update();
}
private function update():void {
_canvas.lock();
//_canvasにフィルターをかけた_canvasを渡す
_canvas.applyFilter(_canvas, _rect, new Point(), new BlurFilter(2, 2));
//_canvas の色を変える
_canvas.colorTransform(_rect, _cTra);
//_particls.length の数だけ処理
var i:int = _particles.length;
while(i--) {
var p:Particle = _particles[i];
//落下速度をプラス
p.vy += 0.2;
//速度に摩擦をかける
p.vx *= 0.9;
p.vy *= 0.9;
//実際に移動する
p.x += p.vx;
p.y += p.vy;
//_canvasのひとつのピクセルにパーティクルを描く
_canvas.setPixel32(p.x, p.y, p.c);
p.life--;
//パーティクルがステージ外に行ったり、速度が.01を切ったら
//_particles配列からそのパーティクルを除去する
if((p.x > stage.stageWidth || p.x < 0) || (p.y > stage.stageHeight) || p.life == 0) {
_particles.splice(i, 1);
}
}
//処理が完了したのでunlockで更新
_canvas.unlock();
//Glowエフェクト用Bitmapに描画
_glow.draw(_canvas, new Matrix(1/4, 0, 0, 1/4));
}
}
}
internal class Particle {
public var x:Number;
public var y:Number;
public var vx:Number;
public var vy:Number;
public var c:uint;
public var life:int;
public function Particle() {
x = 0;
y = 0;
vx = 0;
vy = 0;
c = 0xFFFFFFFF;
life = 20 + Math.random() * 40;
}
}