ActionScript 3.0 Particle Systems #5: Smoke Effect

I’ve basically spent the day trying to get this one right, and it’s not too bad, although it’s pretty heavy on the CPU. Really, you want about 150 particles and a slower fade out, or 150 particles and add two per frame instead of just one, but on my rig it’s getting jerky with that many particles, so in the animation below we’ve got 80 particles as a compromise =( Also, because we’ve only got 80 particles I’ve deliberately ramped up the alpha decay (i.e. how quickly the particles fade out) and upped the vertical speed to get them off the stage before the particle is forced to vanish by our particle limit. If you put the mouse cursor right down near the bottom of the stage and look at the particles at the top you’ll just catch them vanishing instead of fading out fully, but these are the compromises we make for a smoother framerate ;)

If it’s running poorly on your machine, try right clicking on the stage and lowering the quality, or just grab the files from after the jump and mess around in Flash CS4 (free trials available) with all the different variables (especially the ones that start with min or max!!).

I’ve set the window-mode to use GPU acceleration on this one, so if nothing displays and you’ve got an older graphics card (and you want to see it), just view the source code for this page, grab the object section and change wmode=”gpu” to wmode=”direct”.

Credits: LearnFlash.com’s particle systems vids for the how-to, kaioa.com for the FPSCounter Class, and me for coding it up and running with it!

EnJoY!

Update: I’ve modified the above example to use the RateController Class I wrote yesterday. Aside from adding a RateController object, the only other modification was adding a listener to toggle the animation on a MOUSE_LEAVE event (cursor leaving the stage), and then changing the toggleAnimation function to wait for a click (and not MOUSE_MOVE i.e. cursor returns to stage) before adding particles again. Too easy… :)

Update 2: Many thanks to Joel for pointing out that in my zeal to optimise things I’d actually added some null pointer errors as well as some extra fps, and for correctly suggesting that using Sprites instead of MovieClips would result in a small speed boost, too. The swf file above and code & zip file below have received suitably stern words, and everything now works (relatively) swiftly and error free.

As usual, source code and flash files after the hop skip jump…

Flash File (ActionScript 3.0) Code:

ActionScript 3.0 SmokeParticle Class Code:

ActionScript 3.0 FPSCounter Class:

As promised, Adobe Flash CS4 files for the above can be found: here.

3 thoughts on “ActionScript 3.0 Particle Systems #5: Smoke Effect”

  1. Thanks for sharing. Given my lack of experience I can’t offer much to help speed up the animation, but I did notice you use a MovieClip for your canvas. Could you get by using a Sprite instead? Perhaps that’s a negligible improvement, but I thought I’d mention nonetheless. Also, the debug flash player throws a null reference error relating to particleDestructor() and addParticles().

    1. Hey Joel – thanks for your input.

      It seems that a Sprite is pretty much a MovieClip without a timeline (although there are other static/dynamic property issues too, they don’t come into play in this particular piece of code), so a Sprite makes more sense to use than a MC, and will indeed speed things up, but by a very small amount – but hey, it all counts!

      I hadn’t noticed the null reference was introduced when I recently updated the code to remove the particles as soon as they’re entirely transparent or above the stage – I was just trying to eke out every bit of performance I knew how by removing particles from the stage as soon as I possibly could.

      The unintended side effect of this was that flash then tries to remove the particles twice:
      – Once when they’re transparent or above the stage (called from within the SmokeParticle Class), and
      – Again when the particle limit gets rid of the oldest particle (i.e. array element 0) to add a new particle (called from the main flash file)

      Hence the null pointer reference for any particle that has already been “removed” when the transparent/above remover kicked in from the updateParticle function.

      If you comment out the parent.removeChild(this); line in the ParticleDestructor function, normal service is resumed, but performance suffers because we’re not eliminating the particle as soon as we possibly can.

      I’ll have a look at the code again this evening and either wrap the removeChild calls in some conditions, or add a SmokeParticle property to keep track of whether the particle’s already been removed so hopefully we can keep our speed gain from nuking the particle early, but lose the null-pointer shenanigans :)

      Update: Done!

Leave a Reply

Your email address will not be published.