In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

パーティクルの応用で弾幕2 - 早くなったよ~

コードのリファクタリング & 最適化
Nicolasが最適化してくれました。
http://wonderfl.net/code/63f88f2189846bdc7275a01d5d228b1607344e51
BitmapData#draw() を BitmapData#coloyPixces() に変えるだけ!
めっちゃ早いよ!これ!
/**
 * Copyright coppieeee ( http://wonderfl.net/user/coppieeee )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/31Mp
 */

// 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;

	[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;
		
		
		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(0x00AAFF,0.5);
			g.drawCircle(16, 16, 16);
			g.beginFill(0x55FFFF);
			g.drawCircle(16, 16, 8);
			g.endFill();
			
			//BitmapDataにdraw()
			_bulletImg = new BitmapData(shape.width, shape.height, true, 0xFFFFFF);
			_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.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;
			
			
			//回転
			_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;
	}
}