// 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() { } } forked from: forked from: HANABIをカラフルにしてみた