Particle Emitter from Touch Down Events
After scouring Google for a while I finally found something promising that I could convert to multi-touch. A simple particle emitter. Nice and simple, click on the stage - BOOM - particles. The emit, they fade out, done.
You can see the original code from this post at Free Actionscript titled Dynamic Bitmap Particle Explosion.
I opened up the FLA and behold, Actionscript 2. So I was a little dissappointed at first. But then looking at the code, not too much needed to be changed.
- The are using a bitmap from the library to create the particle, we can simply use a shape. Even apply a filter to it to soften it up
- createEmptyMovieClip[s] need to be changed to addChild[s]
- take of _ for attributes like x, y and alpha
- change particle_mc.onEnterFrame = function():Void to be it's own function and access it using and addEventListener attached to the particle
- instead of the mouse listener, it'll be the good old TouchEvent.MOUSE_DOWN
And I found one more thing, an ability to track memory usage to see if the test movie is hording memory without garbage collecting anything. This will help a LOT making sure you flash is doing well or not with memory management.
To get up and running, its like it has been for this site. Make your new FLA and AS file. I put my AS files in a similar folder structure to Touchlib's (app/demo/MyTouchApp). For this app I'm using the name TouchExplosion.as and the Document Class in the properties of the FLA is app.demo.MyTouchApp.TouchExplosion.
The Code
package app.demo.MyTouchApp{ import flash.events.TUIO;// allows to connect to touchlib/tbeta import flash.events.TouchEvent; import flash.events.Event;// allows to connect to touchlib/tbeta import flash.display.*; import flash.net.*; import flash.geom.*; import flash.filters.BitmapFilter; import flash.filters.BitmapFilterQuality; import flash.filters.BlurFilter; import flash.system.*; public class TouchExplosion extends Sprite { private var particleMaxSpeed:Number = 5; private var particleFadeSpeed:Number = 5; private var particleTotal:Number = 20; private var particleRange:Number = 100; public function TouchExplosion():void { //--------connect to TUIO----------------- TUIO.init(this,'127.0.0.1',3000,'',true); trace("TouchExplosion Initialized"); //---------------------------------------- addEventListener(TouchEvent.MOUSE_DOWN, touchDown); } public function touchDown(e:TouchEvent):void { createExplosion(e.localX, e.localY); } private function getBitmapFilter():BitmapFilter { var blurX:Number = 5; var blurY:Number = 5; return new BlurFilter(blurX,blurY,BitmapFilterQuality.HIGH); } public function createExplosion(targetX:Number, targetY:Number):void { trace("new at: "+targetX+" : "+targetY); //run for loop based on particleTotal for (var i:Number = 0; i < particleTotal; i++) { var myBmp:MovieClip = new MovieClip();// holds particle for animation, fading and scaling var bmd:BitmapData = new BitmapData(40, 40, false, 0xFF0000); var rect:Rectangle = new Rectangle(0, 0, 40, 40); bmd.fillRect(rect, 0xFF0000); var bm:Bitmap = new Bitmap(bmd); myBmp.addChild(bm);//this is the particle in the end myBmp var particle_mc = new MovieClip();//create the 'main holder' movieclip that will hold our particle addChild(particle_mc);//adds it to stage var filter:BitmapFilter = getBitmapFilter(); var myFilters:Array = new Array(); myFilters.push(filter); particle_mc.filters = myFilters;//this only applies a blur filter to softed the rectangles (optional) particle_mc.x = -myBmp.width/2;//set particle x and y position in center of the touch point based on size particle_mc.y = -myBmp.height/2; particle_mc.addChild(myBmp);//finally, attach the bitmapData "myBmp" to the movieclip "particle_mc" which is already on the stage //set position & rotation, alpha. targetX and targetY come from the touch points data. particle_mc.x = targetX; particle_mc.y = targetY; particle_mc.rotation = Math.random()*360; particle_mc.alpha = Math.random()*1; //set speed/direction of fragment - speed randomizer particle_mc.speedX = Math.random()*particleMaxSpeed-Math.random()*particleMaxSpeed; particle_mc.speedY = Math.random()*particleMaxSpeed-Math.random()*particleMaxSpeed; particle_mc.speedX *= particleMaxSpeed; particle_mc.speedY *= particleMaxSpeed ; particle_mc.addEventListener(Event.ENTER_FRAME, moveFragment); } trace("System memory used by this program: " + System.totalMemory);// i finally found something to track memory in tracing //on my computer, garbage collecting seems to keep the flash around 7-10Megs of memory usage. //without garbage collecting, memmory usage would just keep increasing till the flash halted the computer. } public function moveFragment(e:Event):void { //e.target means that item is using the listener code, in this case it's particle_mc. e.target.alpha -= .05; e.target.x += e.target.speedX; e.target.y += e.target.speedY; e.target.scaleX -= .1; e.target.scaleY -= .1; if (e.target.alpha <= 0) { e.target.removeEventListener(Event.ENTER_FRAME, moveFragment); removeChild(e.target as DisplayObject);//removeChild makes sure this MovieClip can be garbage collected, e.target as DisplayObject is particle_mc } } } }
So here's the quick rundown. The stage is listening for Touch Down events. Each time it hears one, it finds out the x and y of the new blob and passes that along to the particle generator [createExplosion]. Each particle shrinks, moves out at a random speed and fade out, once the alpha reaches 0 it is removed from the stage to be garbage collected.
Newer items to point out
import flash.filters.BitmapFilter; import flash.filters.BitmapFilterQuality; import flash.filters.BlurFilter;
I'm applying a blur filter to the particles to kind of soften up the look of them.
var filter:BitmapFilter = getBitmapFilter(); var myFilters:Array = new Array(); myFilters.push(filter); particle_mc.filters = myFilters;//this only applies a blur filter to softed the rectangles (optional)
at first i just had filters running without applying them to anything specific. That made it also effect the shape on the stage used for touch detection. So then particle_mc was added to it so only the particles emitters were effected.
import flash.system.*; trace("System memory used by this program: " + System.totalMemory);//
These are kind of awesome to me. I can see how much memory is being used in the flash test movie and make sure that the items i intend to be removed are actually being removed. At one point I had a typo and messed up the removeChild. I noticed that the memory was growing and never being reduced. I found my typo and then the flash made sure the memory stated in a certian range.
private var particleFadeSpeed:Number = 5;
At first use, I forgot that in AS3, the alpha range is no longer 0-100, it's 0-1. And originally the fading out value was pulled from a variable outside the function, but it assumed that the alpha started at 100, and the random starting point would begin at 100 as well. That just needed to be changed to randomly start between 0 and 1, and I changed the fade out increment to .05.
The rest of it is really up to you. Play around with the numbers, see what you can change. Maybe try adding some more filters or even a ConvolutionFilter if you feel daring.
Good luck. And Enjoy Experimenting.
You can see my experiment collection at: http://code.google.com/p/multitouchas3experiments/
Be sure to check the NUIGroup Wiki's Documents and Tutorials.
Tags: Actionscript 3.0, Flash, Multi-Touch, Touchlib, Tutorial
