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

BulletHeaven forked from: copyPixelsを使用(追記あり) - forked from: 弾幕 -

draw→copyPixelsに変えてみました。
僕の環境では120fpsくらいで違いがでました。気のせいかもしれない

追記
弾を増やし,赤いテキストフィールドをクリックすれば描画メソッドを切り替えられるようにしました!
テキストフィールド内の文字列は現在のメソッドを表しています。
/**
 * Copyright onedayitwillmake ( http://wonderfl.net/user/onedayitwillmake )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7qEG
 */

// forked from coppieeee's 弾幕 - パーティクルの応用で弾幕

/*
draw→copyPixelsに変えてみました。
僕の環境では120fpsくらいで違いがでました。気のせいかもしれない
*/

//追記
//弾を増やし,赤いテキストフィールドをクリックすれば描画メソッドを切り替えられるようにしました!
//テキストフィールド内の文字列は現在のメソッドを表しています。


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.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import frocessing.color.ColorHSV;
	import net.hires.debug.Stats;

	[SWF(width="512",height="512", frameRate="60")]
	public class BulletHeaven 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 _bulletBitmapData:Vector.<Particle>;
		//敵。というか弾の再生位置。
		private var _enemy:Particle;
		
		public var bulletBD:BitmapData;
		public var drawMode:String = "copyPixels";
		
		public static var staticBD:BitmapData;
		public static var halfPI	:Number = Math.PI / 2;
		public static var TWO_PI	:Number = Math.PI * 2;
		public function BulletHeaven()
		{
			Wonderfl.capture_delay( 6 );
			colorHSV = new ColorHSV(360, 1, 1);
			//キャンバスの生成
			_canvas = new BitmapData(WIDTH, HEIGHT, false, 0x000000);
			var cb:Bitmap = new Bitmap(_canvas);
			addChild(cb);
			
			_particles = new Vector.<Particle>();
			
			
			//弾のBitmapの生成
			//Shapeに円を書く。
			var shape:Shape = new Shape();
			var g:Graphics = shape.graphics;
			g.beginFill(0xfffff, 0.5);
			g.drawCircle(16, 16, 16);
			g.beginFill(0xffffff);
			g.drawCircle(16, 16, 8);
			g.endFill();
			//BitmapDataにdraw()
			var data:BitmapData = new BitmapData(shape.width, shape.height, true, 0xFFFFFF);
				data.draw(shape);
			staticBD = bulletBD = data;
			_enemy = new Particle(0,0,0,0)//bulletBD.width, bulletBD.height);

			//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 = 0;
			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;
			});

                        //現在の描画方法
                        var tf2:TextField = new TextField();
                        tf2.y = 120;
                        tf2.textColor = 0xFFFFFF;
                        tf2.background = true;
                        tf2.backgroundColor = 0xFF0000;
                        tf2.autoSize = TextFieldAutoSize.LEFT;
                        addChild(tf2);
                        //tf2.text = drawMode;
                        addEventListener(MouseEvent.CLICK, onClick);

                        function onClick(e:MouseEvent):void{
                            if(drawMode=="copyPixels"){
                                drawMode = "draw";
                            }else{
                                drawMode = "copyPixels";
                            }
                            tf2.text = drawMode;  
                        }
                }
		private var _radius:Number = 0;
		private var colorHSV:ColorHSV;

		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.ax 
			_enemy.vx = (stage.mouseX - _enemy.x) * 0.1;
			_enemy.vy = (stage.mouseY - _enemy.y) * 0.1;
			_enemy.x += _enemy.vx;
			_enemy.y += _enemy.vy;
			
			//弾の生成
			for (var i:int = 0; i < 10; i++ )
			{
				colorHSV.h -= 0.1
				_radius += (TWO_PI / 180) * 11.1;
				var sign :int = 5;
				
				if ((i & 1) == 0) // is even
					sign = ~sign + 1; // turn 3, into -3
					
				var vx:Number = Math.cos(_radius) * sign;
				var vy:Number = Math.sin(_radius) * sign;
				var newP:Particle = new Particle(_enemy.x, _enemy.y, vx, vy, colorHSV.value);
				_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 > 0)
				{
					//弾の角度変更
					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 + halfPI) * 0.1;
					p.ay = Math.sin(radius + halfPI) * 0.1;
				}
				
				var matrix:Matrix = new Matrix();
				matrix.tx = p.x - _bulletImg.width * 0.5;
				matrix.ty = p.y - _bulletImg.height * 0.5;
				//弾の描画。一番のボトルネック!(どうしようもないがな)
                                if(drawMode=="draw"){
                                    //drawを使用
									_canvas.draw(_bulletImg,matrix);
                                }else{
                                //copyPixelsを使用
                                _canvas.copyPixels(p.image, bulletBD.rect, new Point(p.x-16, p.y-16));
                                }
			}
			
			//いらない弾を_particlesから消す。
			for each(var removedP:Particle in removedParticles)
			{
				var index:int = _particles.indexOf(removedP);
				if (index != -1)
					_particles.splice(index, 1);
			}
			_canvas.unlock();
		}
	}
}
import flash.display.BitmapData
import flash.filters.ColorMatrixFilter;
import flash.geom.Point;
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 var image:BitmapData;
	
	public function Particle(x:Number,y:Number,vx:Number,vy:Number, rgb:int = 0xFFFFFF)
	{
		this.x = x ;
		this.y = y;
		this.vx = vx;
		this.vy = vy;
		image = BulletHeaven.staticBD.clone();
		image.applyFilter(image, image.rect, new Point(), new ColorMatrixFilter(ColorHelper.colorize(rgb)))
		
	}
}


/**
 * Modify the color of an asset without destroying color contrast / shading in the asset.
 * Uses hue/saturation/brightness/contrast to modify a color keeping contrast between colors in the asset intact
 * @version 1.3
 */
internal class ColorHelper
{
	/**
	 * Colorize an asset based on an RGB value
	 * @param	rgb		Hex color value
	 * @param	amount	How much of the original color to keep. [0.0-1.0], 1.0 means none. Range can exceed 1.0 for experimental results
	 */
	public static function colorize(rgb:Number, amount:Number=1):Array
	{
		var r:Number;
		var g:Number;
		var b:Number;
		var inv_amount:Number;
		
		// Found after some googling - @ http://www.faqs.org/faqs/graphics/colorspace-faq/ (ctrl+f luminance)
		var LUMA_R:Number = 0.4086;
		var LUMA_G:Number = 0.7094;
		var LUMA_B:Number = 0.0920;
		
		r = (((rgb >> 16) & 0xFF) / 0xFF);
		g = (((rgb >> 8) & 0xFF) / 0xFF);
		b = ((rgb & 0xFF) / 0xFF);
		
		inv_amount = (1 - amount);
		
		return concat([(inv_amount + ((amount * r) * LUMA_R)), ((amount * r) * LUMA_G), ((amount * r) * LUMA_B), 0, 0,
				((amount * g) * LUMA_R), (inv_amount + ((amount * g) * LUMA_G)), ((amount * g) * LUMA_B), 0, 0, 
				((amount * b) * LUMA_R), ((amount * b) * LUMA_G), (inv_amount + ((amount * b) * LUMA_B)), 0, 0, 
				0, 0, 0, 1, 0]);
	}
	
	/**
	 * Concat two matrices
	 * Could be used to mix colors, but for now it only concacts with an identy matrix
	 * @param	mat	Matrix we want to concact
	 */
	public static function concat( mat:Array ):Array
	{
		// Identity matrix
		var matrix:Array = [1, 0, 0, 0, 0, // RED
							0, 1, 0, 0, 0, // GREEN
							0, 0, 1, 0, 0, // BLUE
							0, 0, 0, 1, 0]; // ALPHA
							
		var temp:Array = new Array();
		
		var i:int = 0;
		var x:int, y:int;
		
		
		// Loop through the matrice
		for (y = 0; y < 4; y++ )
		{
			
			for (x = 0; x < 5; x++ )
			{
				temp[ int( i + x) ] =  Number(mat[i])      * Number(matrix[x]) + 
									   Number(mat[int(i + 1)]) * Number(matrix[int(x +  5)]) + 
									   Number(mat[int(i + 2)]) * Number(matrix[int(x + 10)]) + 
									   Number(mat[int(i + 3)]) * Number(matrix[int(x + 15)]) +
									   (x == 4 ? Number(mat[int(i + 4)]) : 0);
			}
			i+=5;
		}
		
		return temp;
	}
}