package { import flash.display.Shape; import flash.display.Sprite; import flash.display.BlendMode; import flash.display.Bitmap; import flash.display.BitmapData; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.BlurFilter; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Vector3D; /** * ... * @author tatsuhisa */ [SWF(backgroundColor="0x000000")] public class Main extends Sprite { private var emitter:Emitter; private var gr:Shape; private var numParticle:uint = 5; private var output:Bitmap; private var black:BitmapData; private var m:Matrix private var p:Point private var blur:BlurFilter; private var DRAW_SCALE:int = 2; public function Main() { initBitmap(); emitter = new Emitter(); this.addEventListener( Event.ENTER_FRAME, update ); stage.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDownHandler ); stage.addEventListener( MouseEvent.MOUSE_UP, onMouseUpHandler ); } private function initBitmap():void { output = new Bitmap( new BitmapData( stage.stageWidth, stage.stageHeight, false, 0xFF000000 ) ); output.smoothing = true; output.scaleX = output.scaleY = DRAW_SCALE; this.addChild(output); black = new BitmapData( stage.stageWidth, stage.stageHeight, false, 0xFF000000); m = new Matrix(); m.translate( -output.x, -output.y ); m.scale( 1 / DRAW_SCALE, 1/ DRAW_SCALE); gr = new Shape(); p = new Point( 0, 0 ); blur = new BlurFilter( 4, 4, 1 ); } private function drawBitmap( ):void { var b:BitmapData = output.bitmapData; b.lock(); b.merge( black, b.rect, p, 2, 2, 2, 0 ); b.applyFilter( b, b.rect, p, blur); b.draw( gr, m, null, BlendMode.ADD ); b.unlock(); } private function update( event:Event ):void { updateEmitter(); draw(); drawBitmap( ); } private function updateEmitter():void { emitter.x += ( stage.mouseX - emitter.x ) * 0.35; emitter.y += ( stage.mouseY - emitter.y ) * 0.35; emitter.run(); emitter.addParticle( numParticle ); } private function draw():void { gr.graphics.clear(); var index:uint = 0; for each( var particle:Particle in emitter.particles ) { var d:Number = Vector3D.distance( emitter, particle ); var dx:Number = (emitter.x - particle.x); var dy:Number = (emitter.y - particle.y); var r:uint = uint( ( 255 - dx )/((index)/10) ); var g:uint = uint( ( 255 - d )/((index)/10) ); var b:uint = uint( ( 255 - dy )/((index)/10) ); particle.color = r << 16 | g << 8 | b; gr.graphics.beginFill( particle.color, particle.lifetime ); gr.graphics.drawCircle( particle.x, particle.y, particle.vel.length ); gr.graphics.endFill(); index ++; } } private function onMouseDownHandler( event:MouseEvent ):void { numParticle = 10; } private function onMouseUpHandler( event:MouseEvent ):void { numParticle = 3; } } } import flash.geom.Vector3D; class Emitter extends Vector3D { private var _particles:Vector.<Particle>; public function get particles():Vector.<Particle> { return _particles; } private var vel:Vector3D = new Vector3D(); private var acc:Vector3D = new Vector3D(); private var px:Number = 0; private var py:Number = 0; private var pz:Number = 0; public function Emitter( x:Number = 0, y:Number = 0, z:Number = 0 ) { super( x, y, z ); _particles = new Vector.<Particle>(); } public function run():void { setVelocity(); update(); } private function setVelocity():void { vel.x = this.x - px; vel.y = this.y - py; vel.z = this.z - pz; px = this.x; py = this.y; pz = this.z; } private function update():void { for each( var particle:Particle in _particles ) { if( particle.isAlive ) { particle.run(); } else { var index:int = particles.indexOf( particle ); if( index != -1 ) { _particles.splice( index, 1 ); } } } } public function addParticle( num:int = 2 ):void { for( var i:uint = 0; i < num; i++ ) { _particles[ particles.length ] = new Particle( this, vel ); } } } class Particle extends Vector3D { private var _vel:Vector3D; public function get vel():Vector3D { return _vel; } private var _acc:Vector3D; public function get acc():Vector3D { return _acc; } private var gravity:Vector3D = new Vector3D( 0, 0.7, 0 ); private var _lifetime:Number; public function get lifetime():Number { return _lifetime; } private var _color:uint = 0xFFFFFF; public function get color():uint { return _color; } public function set color( value:uint ):void { if( _color != value ) _color = value; } private var _isAlive:Boolean = true; public function get isAlive():Boolean { return _isAlive; } public function Particle( loc:Vector3D, vel:Vector3D ) { super( loc.x, loc.y, loc.z ); _vel = new Vector3D(); _vel.x = vel.x * 0.5 + Math.random() * 20 - 10; _vel.y = vel.y * 0.5 + Math.random() * 20 - 10; _vel.z = vel.z * 0.5 + Math.random() * 20 - 10; _acc = new Vector3D(); _lifetime = Math.random() * 0.7 + 0.2; } public function run():void { setVelocity(); updatePosition(); setLifetime(); } private function setVelocity():void { _vel.incrementBy(gravity); } private function updatePosition():void { this.x += _vel.x; this.y += _vel.y; this.z += _vel.z; } private function setLifetime():void { _lifetime -= 0.05; if( lifetime <= 0 ) { this._isAlive = false; } } } ちょいと改造 forked from: Particle1