r3dux.org

A number-pimping side project from the valleys in *NEW* upside-down flavour.

  • Home
  • ABOUT
  • OLD SITE
  • SEARCH
  • FEEDBACK

ActionScript 3.0 Particle Systems #1: Random Motion

r3dux | January 12, 2010

I’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 :D

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.

Related posts:

  1. New XBox 360 Motion Capture System
Categories
Coding
Tags
ActionScript, ActionScript 3.0, Adobe, CS4, Flash, Motion, Particle, Random, Systems
Comments rss
Comments rss
Trackback
Trackback
Print This Post Print This Post

« How To: Play Band Hero/Guitar Hero 5/Rock Band 2 on a Soft-modded Wii Challenged »

20 Responses to “ActionScript 3.0 Particle Systems #1: Random Motion”

  1. ActionScript 3.0 Particle Systems #2: Snow | r3dux.org says:
    January 13, 2010 at 1:45 pm

    [...] ActionScript, much like the previous one in [...]

    Reply
  2. oxid says:
    February 11, 2010 at 11:48 pm

    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?

    Reply
    • r3dux says:
      February 12, 2010 at 12:44 pm

      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 GMT GMT+11) – and I think it’ll answer your question quite comprehensively! :D

      P.S. Like your particle stuff – keep up the good work!

      Reply
  3. ActionScript 3.0 Draw Speed Test: Drawing Primitives Vs. Placing MovieClips | r3dux.org says:
    February 13, 2010 at 7:37 am

    [...] got a comment about ActionScript 3 the other day which asked a simple and fair question (paraphrased as): If [...]

    Reply
  4. benny says:
    May 14, 2010 at 12:42 am

    hi… I am working as a flash trainee programmer in Chennai, and actioscript volunteer too. Your animations are simply great…….. thanks..

    Reply
    • r3dux says:
      May 16, 2010 at 12:37 am

      Thanks, man – glad you like.

      Reply
  5. akira_lee says:
    September 10, 2010 at 7:16 pm

    hello

    this is great! i just love it but it’s giving me a error :( ERROR 1084: Syntax error: expecting identifier before lessthan.

    SOURCE:

    var particleVect:Vector.<Particle> = new Vector.<Particle>;

    how do i make it work right?

    thanks in advance

    edit: Modified source line to show the Particle part within angle brackets -r3dux

    Reply
    • r3dux says:
      September 10, 2010 at 8:04 pm

      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

      Reply
  6. akira_lee says:
    September 10, 2010 at 9:21 pm

    Hello r3dux

    It’s working, my flash was “weird” :) thank you for your quick reply

    keep up your amazing work ;)
    kiss

    Reply
    • r3dux says:
      September 11, 2010 at 12:14 pm

      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:

      stage.quality = StageQuality.MEDIUM;

      or

      stage.quality = StageQuality.LOW;

      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

      Reply
  7. Lindsay says:
    November 9, 2010 at 7:45 am

    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?

    Reply
    • r3dux says:
      November 9, 2010 at 9:31 am

      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

      Reply
  8. Lindsay says:
    November 9, 2010 at 11:24 pm

    Thanks!

    Reply
  9. Tim says:
    July 9, 2011 at 7:42 am

    Is there any way to get the particles to stay behind objects?

    Reply
    • r3dux says:
      July 9, 2011 at 6:03 pm

      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.

      Reply
  10. Michael says:
    April 12, 2012 at 10:15 am

    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

    Reply
  11. Michael says:
    April 12, 2012 at 10:22 am

    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! :)

    Reply
    • r3dux says:
      April 12, 2012 at 12:32 pm

      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:

      // Add the particle to the stage
      addChild(particleVect[loop]);

      You might have:

      // *** Put this somewhere near the top of script in the .fla ***
      // Create a MovieClip to hold the particles
      var particleMC:MovieClip = new MovieClip;
       
      // Make the particleMC completely transparent initially so we can fade it in later
      particleMC.alpha = 0;
       
      // Add the particleMC to the stage
      addChild(particleMC);
       
      // *** Put this in the addParticles function to replace adding the particles to the stage with adding them to the particleMC ***
      // Add the particle to the particleMC
      particleMC.addChild(particleVect[loop]);

      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:

      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 a MovieClip to hold the particles
      var particleMC:MovieClip = new MovieClip;
       
      // Set it to be completely transparent
      particleMC.alpha = 0;
       
      // Add it to the stage
      addChild(particleMC);
       
      // Create a frame counter and initialise it to zero
      var frameCount:uint = 0;
       
      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
      		particleMC.addChild(particleVect[loop]);
       
      	} // End of for loop
       
      } // End of addParticles function
       
      // Function to fade in the particleMC
      function fadeIn(e:Event):void
      {
      	// Fade in over 100 frames. Once the frameCount is 100, stop incrementing
      	// it because the alpha will be 1.0 (full opacity)
      	if (frameCount < 100)
      	{
      		frameCount++;
      		particleMC.alpha = frameCount / 100.0;
       
      	}
      	else // Unregister the fadeIn function when we've finished fading in
      	{
      		stage.removeEventListener(Event.ENTER_FRAME, fadeIn);
      	}
      }
       
      // Add the particles
      addParticles();
       
      // Add an eventlistener to fade in the particleMC
      stage.addEventListener(Event.ENTER_FRAME, fadeIn);
       
      // Stop the animation here - the particles themselves will update on each
      // new frame as per the EventListener specified in the particle constructor
      stop();

      Hope this helps!

      Reply
  12. DL says:
    November 25, 2012 at 7:19 am

    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!

    Reply
  13. DL says:
    November 25, 2012 at 7:28 am

    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! :D

    Reply

Leave a Reply

Click here to cancel reply.

Translate

Categories

Archives

Tags

3D ActionScript ActionScript 3.0 Adobe AI Ballarat Bash C++ Class Cover CS4 Effect Error Film Flash FPS GLFW Glitch GLSL Hack How-To install Java Kinect Linux Live Mash-Up Microsoft Motion mount OpenGL Particle Problem PS3 Remix Retro script Slides Sound Ubuntu Video VirtualBox Wii Windows XBox

Gamercard

OpenR3dux

Misc.

Flattr this

RSS Feed

r3dux twitter feed



“The debt that each generation owes to the past, it must pay to the future.”

 - Abigail Scott Dunaway

rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox