ActionScript 3.0 Particle Systems #2: Snow Effect
r3dux | January 13, 2010More ActionScript, much like the previous one in execution…
Source code and flash files after the jump for those who want ‘em.
Flash File (ActionScript 3.0) Code:
import flash.events.KeyboardEvent; import Snowflake; // Function to return us a random number which is within a specified range function randRange(low:Number, high:Number):Number { var randNum:Number = (Math.random() * (high - low)) + low; return randNum; } // Define our vector (just a dynamic array with a specied type in AS3!) var snowflakeVect:Vector.<Snowflake> = new Vector.<Snowflake>; // Define our number of Snowflakes to display on the screen and a start/stop animation flag var numberOfSnowflakes: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 addSnowflakes():void { // Create variables to store our x & y speeds, which get passed to the Snowflake constructor var flakeXSpeed:Number; var flakeYSpeed:Number; // Create however many Snowflakes we've entered into our numberOfSnowflakes variable for (var loop:uint = 0; loop < numberOfSnowflakes; loop++) { // Generate random x and y speeds for our snowflake instance flakeXSpeed = randRange(-1, 1); flakeYSpeed = randRange(3, 7); // Create a new instance of Snowflake (passing x & y speed parameters) // and add it to our Vector of Snowflakes snowflakeVect.push(new Snowflake(flakeXSpeed, flakeYSpeed)); // Randomise the x (horizontal) and y (vertical) locations on stage snowflakeVect[loop].x = Math.random() * stage.stageWidth; snowflakeVect[loop].y = Math.random() * stage.stageHeight; // Set a random flake alpha within the given range snowflakeVect[loop].alpha = randRange(0.3, 1); // Set a random flake scale within the given range var flakeScale:Number = randRange(0.3, 0.9); snowflakeVect[loop].scaleX = flakeScale; snowflakeVect[loop].scaleY = flakeScale; // Add the Snowflake to the stage addChild(snowflakeVect[loop]); } // End of for loop } // End of addSnowflakes function function removeSnowflakes():void { // Remove however many Snowflakes we're working with from the stage for (var loop:uint = 0; loop < numberOfSnowflakes; loop++) { // Call our custom destructor to unbind any Snowflake eventListeners snowflakeVect[loop].SnowflakeDestructor(); // Remove the Snowflake from the stage removeChild(snowflakeVect[loop]); } // Remove all snowflakes from the vector. // We can't just use "snowflakeVect = null;" or we'll lose our global instance of the vector! while(snowflakeVect.length > 0) { snowflakeVect.pop(); } } // End of removeSnowflakes function function snowflakeController(e:KeyboardEvent):void { // If the animation is stopped, add the Snowflakes and flip the flag if (toggleAnimation == false) { addSnowflakes(); 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 // Snowflakes and flip the flag removeSnowflakes(); toggleAnimation = false; } } // End of SnowflakeController function // With all our functions in place, bind the SnowflakeController function to a keypress stage.addEventListener(KeyboardEvent.KEY_DOWN, snowflakeController);
ActionScript 3.0 Snowflake Class Code:
package { // Import the MovieClip and Event classes import flash.display.MovieClip; import flash.events.Event; public class Snowflake extends MovieClip { // Define our SnowFlake's properties var ySpeed:Number; var xSpeed:Number; // Snowflake Constructor function Snowflake(theXSpeed:Number, theYSpeed:Number):void { // Add an eventlistener for the flake instance that calls the updateSnowflake // function every time we draw a new frame this.addEventListener(Event.ENTER_FRAME, updateSnowflake); // Set our flake's x and y speeds as per the constructor's passed parameters this.xSpeed = theXSpeed; this.ySpeed = theYSpeed; } // End of constructor // Destructor to unbind the Snowflake's ENTER_FRAME event listener when we destroy it public function SnowflakeDestructor():void { this.removeEventListener(Event.ENTER_FRAME, updateSnowflake); } // Function to update the snowflake // Remember that we ARE being passed an event by the EventListener - the ENTER_FRAME event! function updateSnowflake(e:Event):void { this.x += this.xSpeed; this.y += this.ySpeed; // If our snowflake has gone off the bottom of the stage, reset the height back to // above the stage and re-randomise the x and y speeds if (this.y > (stage.stageHeight + this.height)) { // Reset y position to above the stage. I know we don't need to use "0 - blah" // but if we want to do anything with reset offsets later it's already here. this.y = 0 - (this.height / 2); // Re-randomise the speeds this.xSpeed = (Math.random() * 2) - 1; // Range: -1 to +1 this.ySpeed = (Math.random() * 4) + 3; // Range: +3 to +7 } // End of if the flake is off the bottom of the stage } // End of updateSnowflake function } // End of Snowflake class } // End of package
Adobe Flash CS4 files can be found: here
Related posts:











That is quite impressive stuff you’ve learned there, keep it up!
And this one is quite apt too, since it is snowing here (again!) right now.
Thanks, man! Glad you like
Hope the fruzzzing UK weather sorts itself out soon – stay warm, bird-boy! =P
I like the snow effect, question I have what’s the difference in the flash file at the top and the action script one. also if I wanted to accumulate snow ontop of the cabin or the mountains along with it snowing , how can I do that and combine the classes into the one package.
thanks
Jason
Hi Jason,
The difference between the flash file and the class is that the flash file code is placed on a keyframe of the timeline in the main .FLA file, while the class is a standalone file that describes the properties and functions related to a single snowflake, which you can then use to create as many snowflakes as you’d like. I think you can place the snowflake code inside the .fla code (above it), but it’s best to keep classes in separate files to cut down on the code getting bulky (and as such difficult to work with) and so you can re-use the code in other projects with minimum hassle.
You’d need to make significant changes to the code for the snow to accumulate on top of anything depicted in the background image – if you really want to do it, start with just getting the snow to accumulate at the bottom of the stage by checking if it’s moved off the bottom of the stage or collided with another “locked” snowflake, at which point you just move the colliding snowflake back one frames worth of movement and lock it in place, or just lock it in place where it collided depending on how you want it to work…
Collision detection is pretty easy in AS3 as you get the AS3 hitTestObject function to use (example: http://www.foundation-flash.com/tutorials/as3hittesting/) as well as the hitTest function for per-pixel collision detection (which I’ve covered in other flash articles such as this: variable-size-particle-collisions ) when you get more confident with AS3.
With no offense meant, from your question it’s possible that you might be biting off a little bit more than you can chew with snowflake accumulation, so if you find you’re struggling with it, just try and concentrate on getting each aspect required individually until you feel you’re able to put it all together. i.e.:
- Get comfortable adding and manipulating properties of classes
- Make sure you can add a property to a class which will lock the object in place when you set it,
- Make sure you can detect a collision between two objects
- Make sure you can lock two objects in place once they collide
- Make sure you can detect a collision, take one step back, and then lock objects in place once they collide etc.
Hope this helps,
r3dux
Thank a lot!
I modified some variables in “ActionScript 3.0 Snowflake Class Code” in order to create an upping bubbles effect.
Enjoy it!!!
i dont know how to get rid of the control message: press any key..etc
// 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);
i want to put a grafic on top of the flakesani…but how?
thank you
Try this: Snow-CtrlMsg+Banner.zip
Obviously change the banner =P
If you want the snow to be in front of the banner then just delete the Banner symbol and post-it-note.png from the library, then delete the below code from the bottom of the actions layer:
Finally, just pick File | Import | Import to Stage… and point it at your banner of choice.