誘爆させて遊ぶ
/**
* Copyright buccchi ( http://wonderfl.net/user/buccchi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jZIT
*/
package {
/*
*
*/
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import net.hires.debug.Stats;
[SWF(width = "465", height = "465", frameRate = "30")]
public class ParticleBomb extends Sprite {
private const WIDTH:Number = 465;
private const HEIGHT:Number = 465;
private var _canvas:BitmapData;
//爆弾を管理
private var _bombs:Vector.<Particle>;
//破片を管理
private var _fragments:Vector.<Particle>;
private var _blastCanvas:Sprite;
private var _cTra:ColorTransform;
private var _burstCountTf:TextField;
private var _burstCount:Number = 0;
private var _bombCount:Number = 50;
private var _normaCount:Number = 50;
public function ParticleBomb()
{
init();
}
private function init():void
{
//particle描画用キャンバスを作成
_canvas = new BitmapData(WIDTH, HEIGHT,false,0x000000);
addChild(new Bitmap(_canvas));
//爆風表示用キャンバスを作成
_blastCanvas = new Sprite();
addChild(_blastCanvas);
//破片を管理
_fragments = new Vector.<Particle>();
//ボールを管理
_bombs = new Vector.<Particle>();
//メモリ使用量表示
//var stats:Stats = new Stats();
//addChild(stats);
_cTra = new ColorTransform(.95, .8, .95);
//スコア表示
_burstCountTf = new TextField();
var format:TextFormat = new TextFormat('Arial', 10, 0xFFFFFF, true);
_burstCountTf.defaultTextFormat = format;
_burstCountTf.autoSize="right";
_burstCountTf.x = WIDTH - _burstCountTf.width - 4;
_burstCountTf.y = 4;
addChild(_burstCountTf);
addEventListener(Event.ENTER_FRAME, update);
gameStart();
}
private function onClick(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.CLICK, onClick);
createBlast(mouseX, mouseY);
}
private function createBlast(x:Number, y:Number):void
{
var b:Sprite = new Blast();
b.x = x;
b.y = y;
_blastCanvas.addChild(b);
b.addEventListener(Event.COMPLETE, removeBlast);
}
private function removeBlast(e:Event):void
{
var b:Sprite = Sprite(e.target);
_blastCanvas.removeChild(b);
b.removeEventListener(Event.COMPLETE, removeBlast);
if(_blastCanvas.numChildren <= 0)
{
if(_burstCount >= _normaCount)
{
_burstCountTf.text = "おめでと! CLICK TO RETRY. "+_burstCount+"/"+_normaCount;
}else{
_burstCountTf.text = "残念! CLICK TO RETRY. "+_burstCount+"/"+_normaCount;
}
stage.addEventListener(MouseEvent.CLICK, restart);
}
}
private function gameStart():void
{
_burstCountTf.text = "クリックすると爆発するーよ! "+_burstCount+"/"+_normaCount;
//爆弾を生成
var i:uint = _bombCount;
while (i--)
{
var bomb:Particle = new Particle(WIDTH/2, HEIGHT/2);
bomb.vx = Math.random() *6 -3;
bomb.vy = Math.random() *6 -3;
bomb.x = Math.random() *WIDTH;
bomb.y = Math.random() *HEIGHT;
bomb.color = 0xFFFFFF;
_bombs.push(bomb);
}
stage.addEventListener(MouseEvent.CLICK, onClick);
}
private function restart(e:Event):void
{
stage.removeEventListener(MouseEvent.CLICK, restart);
var removeBombs:Vector.<Particle> = new Vector.<Particle>();
for each(var b:Particle in _bombs)
{
removeBombs.push(b);
}
removeBombs.forEach(function(b:Particle, ...args):void
{
var index:int = _bombs.indexOf(b);
if (index != -1)
{
_bombs.splice(index, 1);
}
});
_burstCount = 0;
_burstCountTf.text = _burstCount+"/"+_normaCount;
gameStart();
}
private function update(e:Event):void
{
_canvas.lock();
//ビットマップイメージの特定領域のカラー値を調整(だんだん暗く)
_canvas.colorTransform(_canvas.rect, _cTra);
//爆弾動作算出
//削除するパーティクルを管理
var removeBombs:Vector.<Particle> = new Vector.<Particle>();
for each(var bomb:Particle in _bombs)
{
var bvx:Number = bomb.vx;
var bvy:Number = bomb.vy;
var bspeed:Number = Math.sqrt(bvx * bvx + bvy * bvy);
var bradius:Number = Math.atan2(bvy, bvx);
//速度分だけ描画と当たり判定処理を行う
for (var i:int=0; i < bspeed; i++)
{
bomb.x += bomb.vx/bspeed;
bomb.y += bomb.vy/bspeed;
//上下左右の壁との当たり判定
if ((bomb.x < 0 && bomb.vx < 0) || (bomb.x > WIDTH && bomb.vx > 0))
{
bomb.vx = -bomb.vx;
}
if ((bomb.y < 0 && bomb.vy < 0) || (bomb.y > HEIGHT && bomb.vy > 0))
{
bomb.vy = -bomb.vy;
}
//爆風との当たり判定
if (_blastCanvas.hitTestPoint(bomb.x, bomb.y, true))
{
removeBombs.push(bomb);
//スコア加算
_burstCountTf.text = ++_burstCount +"/"+_normaCount;
//爆風生成
createBlast(bomb.x, bomb.y);
//破片生成
for(var j:uint=0; i<30; i++)
{
var fragmentP:Particle = new Particle(bomb.x, bomb.y);
//角度のブレ
var eRadius:Number = Math.random()*1-.5;
//速度
var eSpeed:Number = bspeed - (Math.random()*bspeed - .2);
fragmentP.vx = Math.cos(bradius+eRadius)*eSpeed;
fragmentP.vy = Math.sin(bradius+eRadius)*eSpeed;
fragmentP.color = 0x339999;
fragmentP.life = Math.random()*120 +10;
_fragments.push(fragmentP);
}
}
_canvas.setPixel(bomb.x, bomb.y, bomb.color);
}
}
removeBombs.forEach(function(b:Particle, ...args):void
{
var index:int = _bombs.indexOf(b);
if (index != -1)
{
_bombs.splice(index, 1);
}
});
//破片動作算出
var removeFragments:Vector.<Particle> = new Vector.<Particle>();
_fragments.forEach(function(fragmentP:Particle, ...args):void
{
fragmentP.x += fragmentP.vx;
fragmentP.y += fragmentP.vy;
_canvas.setPixel(fragmentP.x, fragmentP.y, fragmentP.color);
if (fragmentP.x > WIDTH || fragmentP.y < 0 || fragmentP.y > HEIGHT || fragmentP.y < 0 || fragmentP.life-- < 0)
{
removeFragments.push(fragmentP);
}
});
removeFragments.forEach(function(b:Particle,...args):void
{
var index:int = _fragments.indexOf(b);
if (index != -1)
{
_fragments.splice(index, 1);
}
});
_canvas.unlock();
}
}
}
class Particle {
public var x:Number;
public var y:Number;
//速度
public var vx:Number = 0;
public var vy:Number = 0;
public var color:uint;
public var life:Number;
public function Particle(x:Number=0, y:Number=0 )
{
this.x = x;
this.y = y;
}
}
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.display.GradientType;
import caurina.transitions.Tweener;
import flash.events.Event;
class Blast extends Sprite
{
private var _h:uint = 50;
public function Blast()
{
blendMode = "add";
var fillType:String = GradientType.RADIAL;
var color:Number = 0x339999;
var colors:Array = [color, color, color];
var alphas:Array = [.2, .6, .7];
var ratios:Array = [0x00, 0xAA, 0xFF];
var mat:Matrix = new Matrix();
mat.createGradientBox(_h*2, _h*2, 0, -_h, -_h);
graphics.clear();
//graphics.lineStyle(0, 0x669999); //重くなる...
graphics.beginGradientFill(fillType, colors, alphas, ratios, mat);
graphics.drawCircle(0, 0, _h);
graphics.endFill();
//graphics.lineStyle(0, color);
//graphics.moveTo(0, -_h);
//graphics.lineTo(0, 0);
graphics.beginFill(color, 1);
graphics.drawRect(-.5, -_h, .5 , _h);
this.scaleX = this.scaleY = 0;
Tweener.addTween(this, {
time: 1,
scaleX: 1,
scaleY: 1,
transition: "easeOutSine",
onComplete: function():void{
Tweener.addTween(this, {
time: 2,
rotation: 360,
transition: "linear",
onComplete: function():void{
Tweener.addTween(this, {
time: 1,
scaleX: 0,
scaleY: 0,
alpha: 0,
transition: "easeOutSine",
onComplete: function():void{
dispatchEvent(new Event(Event.COMPLETE));
}
});
}
});
}
});
}
}