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

forked from: forked from: forked from: 弾幕 - パーティクルの応用で弾幕

Get Adobe Flash player
by onedayitwillmake 24 Jun 2009
/**
 * Copyright onedayitwillmake ( http://wonderfl.net/user/onedayitwillmake )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/fwA1
 */

// forked from onedayitwillmake's forked from: forked from: 弾幕 - パーティクルの応用で弾幕
// forked from onedayitwillmake's forked from: 弾幕 - パーティクルの応用で弾幕
// forked from coppieeee's ?? - ????????????
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.filters.BlurFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.filters.ColorMatrixFilter
	import flash.text.TextFieldAutoSize;
	import flash.utils.Dictionary;
	import frocessing.color.ColorRGB;
	import net.hires.debug.Stats;
	import frocessing.color.ColorHSV
	
	[SWF(width="465",height="465" )]
	public class PShooting extends Sprite 
	{
		public static const WIDTH:Number = 465;
		public static const HEIGHT:Number = 465;
		
		//?????????????
		private var _bulletImg:Bitmap;
		//?????
		private var _canvas:BitmapData;
		//?????????
		private var _particles	:Dictionary = new Dictionary(true);
		//?????????????
		private var _enemy:Particle;
		private var totalcount:Number = 0;
		public var _particlePool	:ObjectPool
		public function PShooting()
		{
			Wonderfl.capture_delay( 4);
			_particlePool = new ObjectPool(false);
			_particlePool.allocate(100, Particle); 
			MAX_PARTICLES =  _particlePool.size * 2
			//trace(_particlePool.
			stage.frameRate = 30;
			stage.quality = 'low';
			//????????
			_canvas = new BitmapData(WIDTH, HEIGHT,false,0x000000);
			var cb:Bitmap = new Bitmap(_canvas);
			addChild(cb);
			
			//_particles = new Vector.<Particle>();
			_enemy = new Particle();
			
			//??Bitmap???
			//Shape??????
			var shape:Shape = new Shape();
			var g:Graphics = shape.graphics;
			g.beginFill(0xffffff, 0.2);
			g.drawCircle(16, 16, 16);
			g.beginFill(0xffffff, 0.3);
			g.drawCircle(16, 16, 6);
			//g.beginFill(0xffffff, 0.4);
			g.endFill();
			//BitmapData?draw()
			data = new BitmapData(shape.width, shape.height, true, 0xFFFFFF);
			data.draw(shape);
			//Bitmap??
			_bulletImg = new Bitmap(data.clone());
			//???(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:"+_particlePool.usageCount
			});
		}
		private var _radius:Number = 0;
		private var data:BitmapData;
		private var MAX_PARTICLES:int;
		private var color:ColorMatrixFilter = new ColorMatrixFilter()
		private function onEnterFrame(e:Event):void
		{
			var rs:Number = 0, gs:Number = 0, bs:Number = 0;
			var colorRGB:ColorRGB, vx: Number, vy:Number
			var i:int;
			
			_canvas.lock();
			var cr:Rectangle = new Rectangle(0, 0, _canvas.width, _canvas.height);
			var ct:ColorTransform = new ColorTransform (0.95, 0.9, 1, 1, 0, 0, 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.y = 232

			//????
			//var count:int = _particles.length;
			//_radius = 0;
			
			
			for (i = 0; i < 3; i++ )
			{
				var newP:Particle = _particlePool.object;
				_radius += 100
				if (newP == null) break;
				var variance:Number = Math.random() * 0
				colorRGB = new ColorHSV((totalcount % MAX_PARTICLES) / MAX_PARTICLES * 360,  Math.random() * 0.2 + 0.8, 1).toRGB();
				vx = Math.cos(_radius) * 3 + variance 
				vy = Math.sin(_radius) * 3 + variance
				newP.init(_enemy.x, _enemy.y, vx, vy, colorRGB.value);
                                newP.time = -4
				_particles[newP] = newP;
				totalcount--
			}
			//trace(_radius)
			
			//_radius += 11;
			
			
			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++;
				
				//var dx :int = (stage.stageWidth * 0.5) - p.x;
					//dx *= dx;
				//var dy	:int = (stage.stageHeight * 0.5) - p.y;
					//dy *= dy;
					//
				// 102602 sqrt = 232 
				if (p.time >= 0)
				{
					//??????
					p.time = 0
					var radius:Number = Math.atan2(p.vy, p.vx);
					p.ax = Math.cos(radius + Math.PI / 2) * 2;
					p.ay = Math.sin(radius + Math.PI / 2) * 0.5;
				}
				
				if (p.x < 0 || p.x > WIDTH || p.y < 0 || p.y > HEIGHT)
				{
					colorRGB = new ColorHSV((totalcount % MAX_PARTICLES) / MAX_PARTICLES * 360, Math.random() * 0.2 + 0.8, 1).toRGB();
					_radius += 100
                                        variance= Math.random() * 0
					vx = Math.cos(_radius) * 3 + variance
					vy = Math.sin(_radius) * 3 + variance
					p.init(_enemy.x, _enemy.y, vx, vy, colorRGB.value);
					totalcount--;
					
					//_particlePool.ne = p;
					continue;
				}
				
					var matrix:Matrix = new Matrix();
					matrix.tx = p.x - _bulletImg.width  * .5;
					matrix.ty = p.y - _bulletImg.height * .5;
					
					color.matrix = ColorHelper.colorize(p.color,  1);
					_bulletImg.bitmapData.applyFilter(data, new Rectangle(0, 0, _bulletImg.width, _bulletImg.height), new Point(), color);
					_canvas.draw(_bulletImg, matrix);
				
				
			}
			trace(".");
			
			_canvas.unlock();
		}
	}
}
import flash.filters.ColorMatrixFilter;
import frocessing.color.ColorHSV;
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 color	:uint

	public function Particle():void { };
	public function init(x:Number, y:Number, vx:Number, vy:Number, color:uint):void
	{
		if(color != uint.MAX_VALUE ) this.color = color;	
			
		this.x = x ;
		this.y = y;
		this.vx = vx;
		this.vy = vy;
		this.ax = 0; 
		this.ay = 0;
		this.time = 0;
	}
}


/**
 * 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
 * @author Mario Gonzalez
 * @link Method discused with example @ http://onedayitwillmake.com/thesethingswork/obey/
 * @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;
	}
}



internal class ObjectPool
	{
		private var _factory:ObjectPoolFactory;
		
		private var _initSize:int;
		private var _currSize:int;
		private var _usageCount:int;
		
		private var _grow:Boolean = true;
		
		private var _head:ObjNode;
		private var _tail:ObjNode;
		
		private var _emptyNode:ObjNode;
		private var _allocNode:ObjNode;
		
		/**
		 * Creates a new object pool.
		 *
		 * @param grow If true, the pool grows the first time it becomes empty.
		 */
		public function ObjectPool(grow:Boolean = false)
		{
			_grow = grow;
		}

		/**
		 * Unlock all ressources for the garbage collector.
		 */
		public function deconstruct():void
		{
			var node:ObjNode = _head;
			var t:ObjNode;
			while (node)
			{
				t = node.next;
				node.next = null;
				node = t;
			}
			
			_head = _tail = _emptyNode = _allocNode = null;
		}
		
		/**
		 * The pool size.
		 */
		public function get size():int
		{
			return _currSize;
		}
		
		/**
		 * The total number of 'checked out' objects currently in use.
		 */
		public function get usageCount():int
		{
			return _usageCount;
		}
		
		/**
		 * The total number of unused thus wasted objects. Use the purge()
		 * method to compact the pool.
		 *
		 * @see #purge
		 */
		public function get wasteCount():int
		{
			return _currSize - _usageCount;
		}
		
		/**
		 * Get the next available object from the pool or put it back for the
		 * next use. If the pool is empty and resizable, an error is thrown.
		 */
		public function get object():Particle
		{
			if (_usageCount == _currSize)
			{
				if (_grow)
				{
					_currSize += _initSize;
					
					var n:ObjNode = _tail;
					var t:ObjNode = _tail;
					
					var node:ObjNode;
					for (var i:int = 0; i < _initSize; i++)
					{
						node = new ObjNode();
						node.data = _factory.create();
						
						t.next = node;
						t = node;
					}
					
					_tail = t;
					
					_tail.next = _emptyNode = _head;
					_allocNode = n.next;
					return object;
				}
 				else
					return null;
			}
			else
			{
				var o:Particle = _allocNode.data;
				_allocNode.data = null;
				_allocNode = _allocNode.next;
				_usageCount++;
				return o;
			}
		}
		
		/**
		 * @private
		 */
		public function set object(o:Particle):void
		{
			if (_usageCount > 0)
			{
				_usageCount--;
				_emptyNode.data = o;
				_emptyNode = _emptyNode.next;
			}
		}
		
		/**
		 * Define the factory responsible for creating all pool objects.
		 * If you don't want to use a factory, you must provide a class to the
		 * allocate method instead.
		 *
		 * @see #allocate
		 */
		public function setFactory(factory:ObjectPoolFactory):void
		{
			_factory = factory;
		}

		/**
		 * Allocate the pool by creating all objects from the factory.
		 *
		 * @param size The number of objects to create.
		 * @param C    The class to create for each object node in the pool.
		 *             This overwrites the current factory.
		 */
		public function allocate(size:uint, C:Class = null):void
		{
			deconstruct();
			
			if (C)
				_factory = new SimpleFactory(C);
			else
				if (!_factory)
					throw new Error("nothing to instantiate.");
			
			_initSize = _currSize = size;
			
			_head = _tail = new ObjNode();
			_head.data = _factory.create();
			
			var n:ObjNode;
			
			for (var i:int = 1; i < _initSize; i++)
			{
				n = new ObjNode();
				n.data = _factory.create();
				n.next = _head;
				_head = n;
			}
			
			_emptyNode = _allocNode = _head;
			_tail.next = _head;
		}
		
		/**
		 * Helper method for applying a function to all objects in the pool.
		 *
		 * @param func The function's name.
		 * @param args The function's arguments.
		 */
		public function initialze(func:String, args:Array):void
		{
			var n:ObjNode = _head;
			while (n)
			{
				n.data[func].apply(n.data, args);
				if (n == _tail) break;
				n = n.next;
			}
		}
		
		/**
		 * Remove all unused objects from the pool. If the number of remaining
		 * used objects is smaller than the initial capacity defined by the
		 * allocate() method, new objects are created to refill the pool.
		 */
		public function purge():void
		{
			var i:int;
			var node:ObjNode;
			
			if (_usageCount == 0)
			{
				if (_currSize == _initSize)
					return;
					
				if (_currSize > _initSize)
				{
					i = 0;
					node = _head;
					while (++i < _initSize)
						node = node.next;
					
					_tail = node;
					_allocNode = _emptyNode = _head;
					
					_currSize = _initSize;
					return;
				}
			}
			else
			{
				var a:Array = [];
				node =_head;
				while (node)
				{
					if (!node.data) a[int(i++)] = node;
					if (node == _tail) break;
					node = node.next;
				}
				
				_currSize = a.length;
				_usageCount = _currSize;
				
				_head = _tail = a[0];
				for (i = 1; i < _currSize; i++)
				{
					node = a[i];
					node.next = _head;
					_head = node;
				}
				
				_emptyNode = _allocNode = _head;
				_tail.next = _head;
				
				if (_usageCount < _initSize)
				{
					_currSize = _initSize;
					
					var n:ObjNode = _tail;
					var t:ObjNode = _tail;
					var k:int = _initSize - _usageCount;
					for (i = 0; i < k; i++)
					{
						node = new ObjNode();
						node.data = _factory.create();
						
						t.next = node;
						t = node;
					}
					
					_tail = t;
					
					_tail.next = _emptyNode = _head;
					_allocNode = n.next;
					
				}
			}
		}
}

internal class ObjNode
{
	public var next:ObjNode;
	public var data:Particle;
}



internal class SimpleFactory implements ObjectPoolFactory
{
	private var _class:Class;
	
	public function SimpleFactory(C:Class)
	{
		_class = C;
	}

	public function create():Particle
	{
		return new _class();
	}
}

interface ObjectPoolFactory
	{
		function create():Particle
	}