/**
* 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
}