Forked from: onedayitwillmake's forked from: 弾幕 - パーティクルの応用で弾幕 diff:27 forked from: forked from: 弾幕 - パーティクルの応用で弾幕 onedayitwill.. forked:1favorite:2lines:404license : MIT License modified : 2009-06-24 23:34:10 Embed Tweet // 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.92, 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 < 1; i++ ) { var newP:Particle = _particlePool.object; _radius += 20 if (newP == null) break; var variance:Number = Math.random() * 0.25 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); _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 >= 1) { //?????? 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 + Math.PI / 2) * 0.4; p.ay = Math.sin(radius + Math.PI / 2) * 0.4; } 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 += 20 variance= Math.random() * 0.25 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 } Code Fullscreen Preview Fullscreen teruyastar coppieeee : BitmapData弾幕なんかものすごい綺麗な弾幕! BitmapData 弾幕 rgb toRGB Dictionary value concat ColorHSV ColorMatrixFilter Stats uint.MAX_VALUE Rectangle time matrix clone apply Math.cos Error graphics addChild addEventListener size sort new page view favorite forked pv487 forked from: forked from: fork.. onedayitwillmake forked:2 favorite:4lines:405 (diff:12) tag: 背景