Create a Customizable Snow Effect with ActionScript 3

Create a Customizable Snow Effect with ActionScript 3.0

It’s been a cold winter all over the place, so let’s recognize that fact with a nice wintery scene. In this tutorial we will create a falling snow effect using Flash and ActionScript 3.0.

Final Result

Let’s take a quick look at the final effect:

Step 1: Brief Overview

Using an image as a background we will create a falling snow effect. The snow will be a user defined MovieClip that will be exported to be used as a class. We will duplicate and animate this clip with AS3.

Step 2: Set Up

Open Flash and create a new Flash File (ActionScript 3.0).

Set the stage size to 500 x 375 px and set the frame rate to 24fps.

Step 3: Getting the Background

A snowy scene will be required for this effect.

You can create your own or adapt a custom background. In this example I used a photograph from Andy Armstrong, which has a Creative Commons License.

Step 4: Importing the Image

When you’re done choosing the background go back to Flash, click File > Import > Import to Stage and select the image you downloaded.

Place the image in the center of the stage and go to the next step.

Step 5: Create your Snowflake

A MovieClip will be used as a Snowflake, I used this basic Snowflake bitmap:

Convert the bitmap to a MovieClip, mark the Export for ActionScript checkbox, and name it Snowflake.

Alternatively, you could create a new MovieClip called Snowflake and just draw a circle inside it, with a gradient fill to make it look soft and round.

Step 6: Create your Document Class

Create a new ActionScript Document and save it as Snow.as.

Step 7: Start your Code

The package keyword allows you to organize your code into groups that can be imported by other scripts; it’s recommended to name them starting with a lowercase letter and use intercaps for subsequent words — for example: myClasses.

If you don’t want to group your files in a package or you have only one class you can use it right from your source folder, but the idea here is to be organized.

package 
{

Step 8: Import Required Classes

These are the required classes, for a more detailed description about each class, please refer to the Flash Help (press F1 within Flash).

import flash.display.MovieClip;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;

Step 9: Declare the Class

The extends keyword defines a class that is a subclass of another class. The subclass inherits all the methods, properties and functions; that way we can use them in our class.

Our document class is going to extend the MovieClip class.

public class Snow extends MovieClip
{

Step 10: Set Up Variables

Let’s take a look at the variables we’ll use.

//A Vector object that will store the snowflakes movieclips
private var flakesVector:Vector.<MovieClip> = new Vector.<MovieClip>();
//Timer object that controls the horizontal movement
private var timer:Timer = new Timer(2000); 

(If you’re using Flash CS3, you can use an Array instead of a Vector.)

Step 11: Write the Constructor

The constructor is a function that runs when an object is created from a class; this code is the first to execute when you make an instance of an object or run using the Document Class. In this case, it’s the first code to run when our SWF is started.

Here we’ve specified two parameters that have values by default: the speed parameter, which stores the pixels each snowflake moves down by every frame, and flakesNumber, which is the number of snowflakes presented on screen.

public function Snow(speed:int = 3, flakesNumber = 150):void
{

Step 12: Duplicate the Snowflakes

A for statement handles this action.

	for(var i:int = 0; i < flakesNumber; i++)
	{
		//Instantiates the snowflake clip
		var flake:Snowflake = new Snowflake(); 
					
		//Gives a unique and random falling speed to each snowflake
		flake.vel = (Math.random() * speed) + 0.5; 
		//Picks a random value between 0.5 and -0.5, this is the horizontal movement speed
		flake.xSpeed = Math.floor(Math.random() * (0.5 - -0.5 + 1)) + -0.5; 				
		flake.scaleX = (Math.random() * 1) + 0.3; 	//Scales the snowflake
		flake.scaleY = flake.scaleX;
		flake.x = Math.random() * stage.stageWidth; 	//Random Position
		flake.y = Math.random() * stage.stageHeight;
					
		addChild(flake); //Adds the clip to the stage
	
		//Adds the clip to the Vector object so it can be accessed by other functions
		flakesVector.push(flake); 
	}

	//Adds a listener to the stage to execute the fall function every frame
	addEventListener(Event.ENTER_FRAME, fall); 

	timer.addEventListener(TimerEvent.TIMER, 	changeMovement);
	timer.start(); //Starts the timer
}

Step 13: Add the Fall Function

The falling function.

This will be triggered every frame, due to the ENTER_FRAME event listener. It will move the snowflakes horizontally and down each frame according to the speed calculated in xSpeed and vel. It will also re-position the snowflakes at the top when they pass the bottom of the stage.

private function fall(e:Event):void
{
	//This for loops through the snowflakes to apply the code to every clip
	for(var i:int = 0; i < flakesVector.length; i++) 	{

Step 14: Horizontal Movement

Move each snowflake horizontally. At first each will only move to the right, but the timer event handler will change that.

flakesVector[i].x += flakesVector[i].xSpeed;

Step 15: Vertical Movement

The snowflake will be moved down every frame by its vel (velocity) variable, which has a different value for each flake.

flakesVector[i].y += flakesVector[i].vel;

Step 16: Reset Positions

If the snowflake clip gets below the stage, it will be moved back to the top and assigned with a new random x-postition.

if(flakesVector[i].y > stage.stageHeight)
{
	flakesVector[i].x = Math.random() * stage.stageWidth;
	flakesVector[i].y = -flakesVector[i].height;
}

Step 17: Change Movement

A Timer object will change the horizontal movement of the flakes by multiplying the xSpeed of each flake by -1 every couple of seconds. This function is triggered by the TIMER event listener we added earlier.

		private function changeMovement(e:TimerEvent):void
		{
			for(var i:int = 0; i < flakesVector.length; i++)
			{
				flakesVector[i].xSpeed *= -1;
			}
		}
	}
}

Step 18: Set the Document Class

Go back to the .fla file, and in the Properties Panel write Snow in the Class field to make this the Document Class.

Test your movie to see the effect in action.

Step 19: Try Custom Snowflakes

You can modify the Snowflake MovieClip to make it look however you want, this is an example of the results you can get!

Conclusion

Play with the parameters of the class and create custom MovieClips to make your own Snow Effect.

Thanks for reading!

  • WesleyE

    To bad that the snow particles are a bit jumpy in their x motion. You should put some ease into that.

    I’ll post my snowflake behavior script here when I’m home, it’s way more smooth.

    • WesleyE

      Ah, here it is, try this for the x motion;

      var rad:int = 0;
      this.x += Math.sin(this.rad);

      Then increase the rad var with some number each frame. It will ease the x motion in and out in a simple math way.

  • Pingback: uberVU - social comments

  • http://www.seansmyth.ie Sean Smyth

    Really nice tutorial. I found one like this before but it wasn’t explained have a s good as this one.

  • http://www.seostuff.org.ua Alex Nadtoka

    Cool tut)) Thanks

  • Yeah boy

    Great tutorial. But. The snowflakes seem to move together in columns, this takes away the realnessness of it all. The snowflakes shouldnt be bound like that I think. Cheers

  • http://cjcat.blogspot.com Allen Chou

    There’s one simple way to ease the horizontal movement. You can declare two variables “vx” and “vy”, which stand for the X and Y components of a particle’s velocity. And the pseudocode goes something like this:

    particle.vx += random number;
    particle.vy += random number;
    particle.x += particle.vx * time;
    particle.y += particle.vy * time;

    Instead of modifying the particle displacement directly, this method alters the particle velocity, the first derivative of displacement, and updates the displacement according to the velocity. This oughtta smooth things out.

  • André

    Nice, but it seems that hit a invisible wall…

    try:
    private var iniX:Number;

    when you create with the random x value set the iniX with this random x value…

    them just add an Event.ENTER_FRAME on an onUpdate funtion in your tween engine…

    this.x=iniX+(Math.sin(y)*10);

    10 is the radius of the movement, you can change the value 10 to scaleX*10 for example… when the scale is lower the radius will be lower too… so when it´s far the movement is more sweet

  • Deoxys

    The snow falls really ugly xD

  • Deoxys

    lol, the snow falls really ugly (too jumpy)

  • http://www.timsoret.com Tim Soret

    If you want to have the best flash snow ever for a few bucks, head to :

    http://activeden.net/item/3d-realistic-snow-as2-as3/77506

    Feel free to study my code, it should learn you a lot.

    • Debbie

      bookmarked it. great job!

  • John

    This could have been accomplished quicker and more efficiently using the HYPE framework: http://hype.joshuadavis.com/

    Its has object pooling, color pooling, bitmap canvas and classes for most programmatic motion types.

    • http://snaptin.com Ian Yates
      Staff

      I’d certainly like to see some more HYPE submissions come our way – if anyone has any novel ideas, let us know!

  • Jagzviruz

    I am getting a Type error when I open this page.

    • http://gamedev.michaeljameswilliams.com/ MichaelJW

      Could you paste the error message? Thanks.

  • Maria

    1084: Syntax error: expecting identifier before lessthan.

  • sunny

    very good .thank you! i’m chinese girl

  • Natha

    Thank you For this great Tutorial!
    I’m a beginner in flash and this is good. I’d would have liked if you specified where the code should be written, since it is very confusing for a beginner, like me, to know in which of the two files. the .fla or .as we should be typing. beside that everything is great.Thanks again.

  • Natha

    Thank you For this great Tutorial!
    I’m a beginner in flash and this is good. I’d would have liked if you specified where the code should be written, since it is very confusing for a beginner, like me, to know in which of the two files. the .fla or .as we should be typing. besides that everything is great.Thanks again.

  • http://tutorialblog.info/ tutorial blog

    thank

  • Pingback: Instructional Technology Blogs | Home

  • Pingback: Creare un effetto neve con ActionScript 3! | sastgroup.com

  • Pingback: Creare un effetto neve con actionscript 3!

  • Pingback: Efeito de neve personalizável com ActionScript 3 | Pontuaki Downloads e informação

  • Sean

    Nice Tutorial, and very easy to complete….thanks

  • Emmanuel

    I want to have the snow appear behind one of my layers and not falling in front of it… how can i do this? Please help…

  • MasGepenk

    i have an error report at
    line 14
    “private var flakesVector:Vector. = new Vector.();”
    (1084: Syntax error: expecting identifier before lessthan.)

    • http://michaeljameswilliams.com/ Michael James Williams

      Hi MasGepenk, do you have Flash CS4 or above?

      • MasGepenk

        CS3 Pro….does it work on it…??

  • Patricia

    Hi Carlos

    Great Tutorial! I just have one question. How to start the falling snow in a specific moment of the timeline instead of starting the movie with it falling?

  • mel

    i’m getting dis error:
    1026: Constructor functions must be instance methods.

    :(

  • http://ndajsndkajsnd Emelie

    Hey!

    Really nice effect! I get it to work in a blank new document.

    But! I don’t get it to work in another project. I have two scenes, first scene is linking to the second scene. But as soon as I change the docuemnt class to Snow I get several error messages like this:

    Scene 1, Layer ‘Actions’, Frame 1, Line 12 1046: Type was not found or was not a compile-time constant: MouseEvent.

    Please, an idea anyone?

    • http://michaeljameswilliams.com/ Michael James Williams

      You’ll need to import all the classes it talks about. Check out this link for more details.

  • http://www.facebook.com/chrishpz Chris Hpz

    Typing the code and copying the code line for line produces a lot of errors. Would you mind posting the entire .as file code in one window? Thanks