forked from: forked from: HANABIをカラフルにしてみた
forked from forked from: HANABI(初級者がコードに注釈をつけてみた) (diff: 311)
↓ Start writing by masarizm 基本はおなじですが、構造を変えてみました。 オブジェクト指向っぽく、花火それぞれが消えるタイミングを持つ様にしました。 柳っぽい感じから丸い花火になりました。 消え方は良い感じなのではと思います。 Forkとよんでよいのか、失礼でしたらすぐに消します ↑ Ent writing by masarizm
ActionScript3 source code
/**
* Copyright masarizm ( http://wonderfl.net/user/masarizm )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xJFi
*/
// forked from Hiiragi's forked from: HANABI(初級者がコードに注釈をつけてみた)
package {
/*
↓ Start writing by masarizm
基本はおなじですが、構造を変えてみました。
オブジェクト指向っぽく、花火それぞれが消えるタイミングを持つ様にしました。
柳っぽい感じから丸い花火になりました。
消え方は良い感じなのではと思います。
Forkとよんでよいのか、失礼でしたらすぐに消します
↑ Ent writing by masarizm
*/
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.PixelSnapping;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.filters.BlurFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Timer;
[SWF(width = "465", height = "465", backgroundColor = "0x000000", frameRate = "20")]
public class Hanabitaikai extends Sprite {
// ステージの高さと幅
private const WIDTH:Number = 465;
private const HEIGHT:Number = 465;
// 打ち上げる間隔[ms]
private var interval:int =250;
// 打ち上げる花火を入れておく配列
private var fireWorks:Array = [];
// 表示エリア
private var canvas:BitmapData;
// フィルター適用用のBitmap
private var glow:BitmapData;
// 矩形情報
private var rect:Rectangle;
// timerオブジェクト
private var timer:Timer;
private var clrTrsFom:ColorTransform = new ColorTransform(.7, .7, .7, 1.0);
public function Hanabitaikai() {
initialize();
}
public function initialize():void {
canvas = new BitmapData(WIDTH, HEIGHT, false ,0x0);
addChild(new Bitmap(canvas)) as Bitmap;
//glowFilter
glow = new BitmapData(WIDTH/4, HEIGHT/4, false, 0x0);
var bm:Bitmap = addChild(new Bitmap(glow, PixelSnapping.NEVER, true)) as Bitmap;
// bitmapDataを4分の1で作成して、addChildした戻り値のスケールを4倍してる。
bm.scaleX = bm.scaleY = 4;
bm.blendMode = BlendMode.ADD;
// ステージサイズと同じ矩形
rect = new Rectangle(0, 0, WIDTH, HEIGHT);
//--- イベント ---
//framerateに依存し描画を繰り返すイベント
this.stage.addEventListener(Event.ENTER_FRAME, startFireWorks);
//花火の打ち上げを行う
timer = new Timer(interval);
timer.addEventListener(TimerEvent.TIMER, uchiage);
timer.start();
}
public function uchiage(e:TimerEvent):void {
fireWorks.push(new Hanabi(WIDTH, HEIGHT));
}
public function startFireWorks(e:Event):void {
update();
}
private function update():void {
canvas.lock();
//canvas.applyFilter(canvas, rect, new Point(), new BlurFilter(1, 1));
canvas.colorTransform(rect, clrTrsFom);
for (var i:int=0;i<fireWorks.length;i++) {
var hanabi:Hanabi = fireWorks[i] as Hanabi;
if (hanabi) {
for (var j:int=0;j<hanabi.particls.length;j++) {
var p:Particle = hanabi.particls[j];
// 落下速度をプラス
p.vy += 0.2;
// 速度に摩擦をかける
p.vx *= 0.98;
p.vy *= 0.98;
// 実際の移動
p.x += p.vx;
p.y += p.vy;
canvas.setPixel32(p.x, p.y, p.c);
}
// 花火の寿命が来たら消す
if (!hanabi.isLive()) {
this.fireWorks.splice(i,1);
}
// 花火の寿命を縮める
hanabi.shortenLifeSpan();
}
}
canvas.unlock();
glow.draw(canvas, new Matrix(0.25, 0, 0, 0.25));
}
}
}
class Hanabi
{
// 火花達
public var particls:Array = [];
// 火花の数
private var size:int = 200;
// 寿命
private var lifeSpan:int;
// 色情報
private var red:uint;
private var green:uint;
private var blue:uint;
private var color:uint = 0x000000FF;
private const MIN_COLOR:uint = 100;
private const MAX_COLOR:uint = 255-MIN_COLOR;
// 描画するcanvasのサイズをコンストラクタにて取得してるけど微妙。不細工
// いっそcanvasごとうけとってしまおうか、なんかいい方法があれば変更したい
private var width:Number;
private var height:Number;
// 花火の中心位置
private var sx:Number;
private var sy:Number;
public function Hanabi(width:Number, height:Number)
{
// 初期化処理
this.width = width;
this.height = height;
// 寿命決定(あんまり早く死なない様にゲタ履かせる)
this.lifeSpan = Math.random() * 10 + 3;
// 花火炸裂位置決定
sx = Math.random() * this.width;
sy = Math.random() * this.height/3;
// 花火の色を決める
// まず各色の重みを計算
red = Math.random() * 255;
green = Math.random() * 255;
blue = 255;
// 実際の値計算
color = color + (red << 24) + (green <<16) + (blue << 8);
// 火花を散らせ!
while(size--)createParticle();
}
// 花火の生死確認
public function isLive():Boolean {
return this.lifeSpan > 0;
}
// 寿命を縮める
public function shortenLifeSpan():void {
this.lifeSpan--;
}
private function createParticle():void {
var p:Particle = new Particle();
p.x = sx;
p.y = sy;
//半径と角度をランダムに決めて、x,y軸の速度に変換する
var radius:Number = Math.sqrt(Math.random()) * 10;
var angle:Number = Math.random() * (Math.PI) * 2;
p.vx = Math.cos(angle) * radius;
p.vy = Math.sin(angle) * radius;
// 色の決定
p.c = color;
//配列に追加
particls.push(p);
}
}
class Particle
{
public var x:Number;
public var y:Number;
public var vx:Number;
public var vy:Number;
public var c:uint = 0xFFFFFFFF;
public function Particle() {
}
}