ActionScript 3.0 Particle Systems #1: Random Motion
r3dux | January 12, 2010I’ve been working on getting my ActionScript 3 up to speed by going through a stack of videos purchased from learnflash.com, and fair play, I’m really quite enjoying it all.
Expect a couple of these kinds of things over the coming days and weeks
That Craig chap off learnflash really knows his stuff – top bloke.
Also, source code and flash files after the jump if you’re that way inclined…
Update I’ve updated all the code to make it start paused, and the animation can be toggled on and off with the space bar. Also, all Particle objects are now instantiated to a vector instead of just called by the same instance name over and over in a loop (which was just horrid code) so now we can access each particle individually through it’s unique element number should we so wish. I guess I was just really tired yesterday after doing like 13 hours of flash and I wanted to post something before I went to bed. Kinda rushed it – oh wells!
Flash File (ActionScript 3.0) Code:
import flash.events.KeyboardEvent; import Particle; // Define our vector (just a dynamic array with a specied type in AS3!) var particleVect:Vector.<Particle> = new Vector.<Particle>; // Define our number of particles to display on the screen and a start/stop animation flag var numberOfParticles:uint = 200; var toggleAnimation = false; // Create our controls message, center it and add it to the screen var msg:ControlsMessage = new ControlsMessage(); msg.x = stage.stageWidth / 2; msg.y = stage.stageHeight / 2; addChild(msg); // Create a flag to only show our controls message once var showMsg:Boolean = true; function addParticles():void { // Create however many particles we've entered into our numberOfParticles variable for (var loop:uint = 0; loop < numberOfParticles; loop++) { // Create a new instance of Particle and add it to our Vector of Particles particleVect.push(new Particle()); // Randomise the x (horizontal) and y (vertical) locations on stage particleVect[loop].x = Math.random() * stage.stageWidth; particleVect[loop].y = Math.random() * stage.stageHeight; // Randomise alpha particleVect[loop].alpha = Math.random(); // Randomise size between 0% and 100% (i.e. between 0.0 and 1.0) var sizeScale:Number = Math.random(); particleVect[loop].scaleX = sizeScale; particleVect[loop].scaleY = sizeScale; // Add the particle to the stage addChild(particleVect[loop]); } // End of for loop } // End of addParticles function function removeParticles():void { // Remove however many particles we're working with from the stage for (var loop:uint = 0; loop < numberOfParticles; loop++) { // Call our custom destructor to unbind any particle eventListeners particleVect[loop].ParticleDestructor(); // Remove the particle from the stage removeChild(particleVect[loop]); } // Remove all particles the vector. // We can't just use "particleVect = null;" or we'll lose our global instance of the vector! while(particleVect.length > 0) { particleVect.pop(); } } // End of removeParticles function function particleController(e:KeyboardEvent):void { // If the animation is stopped, add the particles and flip the flag if (toggleAnimation == false) { addParticles(); toggleAnimation = true; // Only remove message after first display, as it'll only be on stage once if (showMsg == true) { showMsg = false; removeChild(msg); } } else { // Otherwise animation must be running and we want it to stop, so remove the // particles and flip the flag removeParticles(); toggleAnimation = false; } } // End of particleController function // With all our functions in place, bind the particle controller function to a keypress stage.addEventListener(KeyboardEvent.KEY_DOWN, particleController); |
ActionScript 3.0 Particle Class Code:
package { // Import the MovieClip and Event classes import flash.display.MovieClip; import flash.events.Event; public class Particle extends MovieClip { // Define our class properties var xSpeed:Number; var ySpeed:Number; var alphaDecay:Number; var fadeBack:Boolean; // Class Constructor function Particle():void { // Add an event listener to each instance of a particle so that it's updated every // time there's a new frame (default: 24 times a second, i.e. 24fps) this.addEventListener(Event.ENTER_FRAME, updateParticle); // Randomise the x and y speed of the particle between -5 and 5 on instantiation // and set a random alpha (transparency) decay speed this.xSpeed = (Math.random() * 10) - 5; this.ySpeed = (Math.random() * 10) - 5; this.alphaDecay = Math.random() / 100; // Initially, our particle is not fading back in this.fadeBack = false; } // Unbind the particle's ENTER_FRAME event listener when we destroy it // I can't believe AS3 doesn't support destructors... extra weak sauce =/ public function ParticleDestructor():void { this.removeEventListener(Event.ENTER_FRAME, updateParticle); } // Function to update a particle, bound to Event.ENTER_FRAME, so called once per frame private function updateParticle(e:Event):void { // Add our randomised x and y speeds to our particle position this.x += xSpeed; this.y += ySpeed; // Subtract a small amount from our object's alpha so it fades out this.alpha -= this.alphaDecay; // Reset particle properties when it's faded out so much it's completely transparent if (this.alpha <= 0) { // Re-randomise the x and y locations of our particles this.x = Math.random() * stage.stageWidth; this.y = Math.random() * stage.stageHeight; // Re-randomise our x and y speeds this.xSpeed = (Math.random() * 10) - 5; this.ySpeed = (Math.random() * 10) - 5; // Set out fadeBack flag to true this.fadeBack = true; } // When a particle has completely faded out (fadeBack == true), fade it back in quickly if (this.fadeBack == true) { this.alpha += 0.15; // When we're fully opaque again stop making any further fadeBack alpha changes if (this.alpha >= 1) { this.fadeBack = false; } } } // End of updateParticle function } // End of Particle class } // End of package |
Adobe Flash CS4 files for the above can be found: here.











[...] ActionScript, much like the previous one in [...]
hello,
i just discovered your site and find it really great. i am learning flash/actionscript now and want to program some interesting animations but i think to accomplish this i have to gain more knowledge about particle moving math and stuff. so I’m hoping this particle series of yours help me on this a little bit.
if you’re interested how my particles look like you can check it here:
http://kelemen.webs.com/myparticles/particles.html
i have a question to ask: in performance’s point of view which is better: instantiating a circle movie clip or generating circles at runtime?
Hey oxid – glad you found some of the ActionScript posts of use!
As for your question – I had no idea, so I coded something up to find out…
As I’m trying to do a post-per-day I’ve written it all up and scheduled it to post tomorrow (Saturday the 13th of Feb, 00:01
GMTGMT+11) – and I think it’ll answer your question quite comprehensively!P.S. Like your particle stuff – keep up the good work!
[...] got a comment about ActionScript 3 the other day which asked a simple and fair question (paraphrased as): If [...]
hi… I am working as a flash trainee programmer in Chennai, and actioscript volunteer too. Your animations are simply great…….. thanks..
Thanks, man – glad you like.
hello
this is great! i just love it but it’s giving me a error
ERROR 1084: Syntax error: expecting identifier before lessthan.
SOURCE:
how do i make it work right?
thanks in advance
edit: Modified source line to show the Particle part within angle brackets -r3dux
Hi akira_lee,
The problem sounds like Flash doesn’t know about the Particle class somehow.. If you’ve copied and pasted the code, did you paste the second lot of code (Particle.as) into a file called Particle.as? If not, try that. Also, both files (the Particle.as -and- the RandomMotion.fla file) have to be in the same directory for it to work.
Another option is to just grab the provided source code from the link at the bottom of the article (this one) and have a play with the code from that.
Hope you get it sorted!
r3dux
Hello r3dux
It’s working, my flash was “weird”
thank you for your quick reply
keep up your amazing work
kiss
Thanks for sending me a link to what you’ve done with the source – looks great!
The only thing I might add is that the flash CPU usage is a little high because of the large stage size, so to try to deal with that a little it might be worth adding the following to your .fla file near the top, either:
or
This will trade-off visual fidelity for lower CPU/GPU usage, and you might be surprised to see that the results aren’t really that noticeable! It’s certainly worth a shot! Another possibility is to lower the frame rate and compensate for any jerkyness of the particles by lowering the movement speed.
Oh, and when you’re embedding your flash into the page, if you haven’t already – have a bit of an experiment with the the wmode=”gpu” and wmode=”direct” attributes of the embedding code! This can strongly affect CPU usage, too!
Best wishes & again, great work on the site – it looks superb!
r3dux
Ok so this works great but I want to remove the keystroke and have the particles start automatically. I’ve tried adjusting the code but have had no luck. What do I remove to make this happen?
Hi Lindsay,
Instead of me trying to outline all the changes you need to make I’ve done two alternate versions of the .fla code for you:
- No Key To Start – which will start the animation on execution, but still allows you to toggle the particles on/off via a keypress, and
- Non-Interactive – which just kicks off the animation and never stops or allows the user to stop it.
Just replace the code in your .fla file with the code from your link of choice above, and you should be hot to trot =D
Thanks!
Is there any way to get the particles to stay behind objects?
Either draw the objects you want on top last, or place the objects on top on a layer which is above the layer with the particles in the timeline.
i’m using the non-interactive script and it works great.
is there any way to control when it starts and stops either in the timeline or in action script??
thanks! beautiful animation!
Mike
nevermind! figured it out. just copied and pasted the removeParticles function and that worked perfectly.
ok, what about tweening the alpha of the animation so that it fades in?
thanks!
Hi Michael,
To tween the alpha of the entire animation, the easiest way I can think of to do it is to add the particles to a MovieClip (instead of adding them directly to the stage) and fade the MovieClip in/out as you please.
So instead of having this in the addParticles function:
You might have:
You can then twiddle the particleMC.alpha property to fade it in/out as you like, which should in turn fade in/out all the particles drawn in it!
Actually, I wanted to make sure that it worked before commenting, and it does – here’s what I used:
Hope this helps!
Hello!
I think I did it right, but I get an error, something like 1172: The definition __AS3__.vec:Vector not found. on Particle.as, Line 1.
Do you know what the problem may be?
Thanks!
Oh, I found it. For somewhat reason I was using an older version of Flash Player when compiling. Sorry!
But thanks anyway for sharing this!