弾幕 - パーティクルの応用で弾幕
最新版(リファクタリング & 最適化)↓
http://wonderfl.net/code/153a0eec809ebf16f35dd6f3a0b4bbb046c856a7
/**
* Copyright coppieeee ( http://wonderfl.net/user/coppieeee )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/tq1s
*/
//最新版(リファクタリング & 最適化)↓
//http://wonderfl.net/code/153a0eec809ebf16f35dd6f3a0b4bbb046c856a7
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import net.hires.debug.Stats;
public class PShooting extends Sprite
{
public static const WIDTH:Number = 512;
public static const HEIGHT:Number = 512;
//弾のビットマップキャッシュ
private var _bulletImg:Bitmap;
//キャンバス
private var _canvas:BitmapData;
//パーティクルリスト
private var _particles:Vector.<Particle>;
//敵。というか弾の再生位置。
private var _enemy:Particle;
[SWF(width="512",height="512" )]
public function PShooting()
{
Wonderfl.capture_delay( 6 );
//キャンバスの生成
_canvas = new BitmapData(WIDTH, HEIGHT,false,0x000000);
var cb:Bitmap = new Bitmap(_canvas);
addChild(cb);
_particles = new Vector.<Particle>();
_enemy = new Particle(0,0,0,0);
//弾のBitmapの生成
//Shapeに円を書く。
var shape:Shape = new Shape();
var g:Graphics = shape.graphics;
g.beginFill(0x00FFFF,0.5);
g.drawCircle(16, 16, 16);
g.beginFill(0x99FFFF);
g.drawCircle(16, 16, 8);
g.endFill();
//BitmapDataにdraw()
var data:BitmapData = new BitmapData(shape.width, shape.height, true, 0xFFFFFF);
data.draw(shape);
//Bitmap生成
_bulletImg = new Bitmap(data);
//中心を(0,0)に置く。
_bulletImg.x = _bulletImg.width / 2;
_bulletImg.y = _bulletImg.height / 2;
//Statsの生成
var stats:Stats = new Stats();
addChild(stats);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
//particlsの個数表示用のTextField生成
var tf:TextField = new TextField();
tf.y = 100;
tf.textColor = 0xFFFFFF;
tf.background = true;
tf.backgroundColor = 0x000000;
tf.autoSize = TextFieldAutoSize.LEFT;
addChild(tf);
addEventListener(Event.ENTER_FRAME, function(e:Event):void {
tf.text = "bullets:"+_particles.length;
});
}
private var _radius:Number = 0;
private function onEnterFrame(e:Event):void
{
_canvas.lock();
var cr:Rectangle = new Rectangle(0, 0, _canvas.width, _canvas.height);
var ct:ColorTransform = new ColorTransform (0.8, 0.8, 0.9);
_canvas.colorTransform(cr, ct);
//弾の生成場所をマウスのところへ移動
_enemy.vx = (stage.mouseX - _enemy.x) * 0.05;
_enemy.vy = (stage.mouseY - _enemy.y)*0.05;
_enemy.x += _enemy.vx;
_enemy.y += _enemy.vy;
//弾の生成
for (var i:int = 0; i < 3; i++ )
{
_radius += (Math.PI * 2 / 180) * 11.1;
var vx:Number = Math.cos(_radius) * 3;
var vy:Number = Math.sin(_radius) * 3;
var newP:Particle = new Particle(_enemy.x, _enemy.y, vx, vy);
_particles.push(newP);
}
var removedParticles:Vector.<Particle> = new Vector.<Particle>();
//弾の移動
for each(var p:Particle in _particles)
{
p.x += p.vx;
p.y += p.vy;
p.vx += p.ax;
p.vy += p.ay;
p.time ++;
//画面外に出たらremovedParticlesに登録
if (p.x < 0 || p.x > WIDTH || p.y < 0 || p.y > HEIGHT)
{
removedParticles.push(p);
continue;
}
else if (p.time > 30)
{
//弾の角度変更
p.time = 0;
var radius:Number = Math.atan2(p.vy, p.vx);
var speed:Number = Math.sqrt(p.vx * p.vx + p.vy * p.vy );
p.ax = Math.cos(radius + Math.PI / 2) * 0.08;
p.ay = Math.sin(radius + Math.PI / 2) * 0.08;
}
var matrix:Matrix = new Matrix();
matrix.tx = p.x - _bulletImg.width/2;
matrix.ty = p.y - _bulletImg.height / 2;
//弾の描画。一番のボトルネック!(どうしようもないがな)
_canvas.draw(_bulletImg,matrix);
}
//いらない弾を_particlesから消す。
for each(var removedP:Particle in removedParticles)
{
var index:int = _particles.indexOf(removedP);
if (index != -1)
{
_particles.splice(index, 1);
}
}
_canvas.unlock();
}
}
}
class Particle
{
public var x:Number;
public var y:Number;
public var vx:Number;
public var vy:Number;
public var ax:Number = 0;
public var ay:Number = 0;
public var time:Number = 0;
public function Particle(x:Number,y:Number,vx:Number,vy:Number)
{
this.x = x ;
this.y = y;
this.vx = vx;
this.vy = vy;
}
}