// forked from adkOHTAH's forked from: パーティクルの応用で弾幕2 - 早くなったよ~ // forked from coppieeee's パーティクルの応用で弾幕2 - 早くなったよ~ // forked from coppieeee's 弾幕 - パーティクルの応用で弾幕 //コードのリファクタリング & 最適化 // // Nicolasが最適化してくれました。 // http://wonderfl.net/code/63f88f2189846bdc7275a01d5d228b1607344e51 // BitmapData#draw() を BitmapData#coloyPixces() に変えるだけ! // めっちゃ早いよ!これ! 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.Point; import flash.geom.Rectangle; import flash.text.TextField; import flash.text.TextFieldAutoSize; import net.hires.debug.Stats; import flash.filters.*; [SWF(frameRate="60",width="512",height="512" )] public class PShooting extends Sprite { public static const WIDTH:Number = 512; public static const HEIGHT:Number = 512; //弾のビットマップキャッシュ private var _bulletImg:BitmapData; //キャンバス private var _canvas:BitmapData; //パーティクルリスト private var _particles:Vector.<Particle>; //敵。というか弾の再生位置。 private var _enemy:Particle; //Random Color private var ranCol:Number = Math.random()*0xFFFFFF; public function PShooting() { //Wonderfl.capture_delay( 7 ); //キャンバスの生成 _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(0x333333,0.5); g.drawCircle(1, 1, 1); g.beginFill(0xCCCCCC); g.drawCircle(1, 1, 1); g.endFill(); //BitmapDataにdraw() _bulletImg = new BitmapData(shape.width, shape.height, true, ranCol); _bulletImg.draw(shape); //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.4, 0.4, 0.4); _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; //回転 _radius += (Math.PI * 2 / 180) * 62.1; //一フレームあたりの弾の生成数 var bCount:int = 10; var bRadius:Number = _radius; for (var i:int = 0; i <bCount; i++ ) { var vx:Number = Math.cos(bRadius) * 3; var vy:Number = Math.sin(bRadius) * 3; var newP:Particle = new Particle(_enemy.x, _enemy.y, vx, vy); _particles.push(newP); bRadius += Math.PI *2 / bCount; } 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; 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 / 180 * 80) * 0.08; p.ay = Math.sin(radius + Math.PI / 180*80) * 0.08; //画面外に出たらremovedParticlesに登録 if (p.x < 0 || p.x > WIDTH || p.y < 0 || p.y > HEIGHT) { removedParticles.push(p); continue; } //弾の描画。一番のボトルネック!(どうしようもないがな) //_canvas.draw(_bulletImg,matrix); //最適化! //draw()じゃなくてcopyPixels()使った方がめっちゃ早いよ!! //早くなったがボトルネックであることは変わらない。 var bulletPoint:Point = new Point(p.x - _bulletImg.width/2, p.y - _bulletImg.height/2); _canvas.copyPixels(_bulletImg, _bulletImg.rect, bulletPoint); } //いらない弾を_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 function Particle(x:Number,y:Number,vx:Number,vy:Number) { this.x = x ; this.y = y; this.vx = vx; this.vy = vy; } } forked from: forked from: パーティクルの応用で弾幕2 - 早くなったよ~