## Question of the Week

Falling Snow 2.0
by kirupa

Now that you are able to recreate the effect presented on the previous page, it is time for you to learn the details of the code. Yay!! Let's start to go through all of the code:

snowflakes = 75;
do {
duplicateMovieClip(snow, "snow"+k, k);
k++;
} while (k != snowflakes);

This section of code is responsible for duplicating the snow movie clip a number of times specified by the variable snowflakes. Right now, about 75 snow movie clips will be duplicated from the original now movie clip. If you want more snow movie clips, you can increase the value of snowflakes from 75 to something higher.

You should take into consideration any performance impacts increasing the number of snowflakes would have. The greater the number of snowflakes - instances of the snow movie clip, the greater the toll the effect takes on your system.

The entire duplicateMovieClip function is inside a do loop with the condition to stop once the incrementing variable k reaches the value specified by the variable snowflakes.

//variables
width = 300;
height = 200;

The variables width and height refer to the dimensions of the area of the snow effect. Because our movie was only 300 by 200, the width and height are also 300 by 200. Unless you are interested in having the snow fall in only a small area of your movie, you would set the values for the width and height variables to the width and height of your movie.

//random x, y, and alpha
this._xscale = this._yscale=50+Math.random()*100;
this._alpha = 20+Math.random()*50;

The above section of code ensures each duplicated snow movie clip has a different alpha and size. Note that I combined this._xscale and this._yscale in the same line to equal a random value specified by the Math.random() function. Because the snowflakes are perfect circles, setting their x and y scale values to something other than the same number would create elongated oval shapes.

//random x and y for flakes
this._x = -width+Math.random()*(3*width);
this._y = -10+Math.random()*height;

Beyond the alpha and scale, the above code places each snow flake in a random x and y location throughout your movie. The boundaries of the random positioning is determined by the values of the width and height variables you specified a few sections above.

//speed and trigonometric value
i = 1+Math.random()*2;
k = -Math.PI+Math.random()*Math.PI;

The first line specifies a value for the speed with which the snow movie clip descends. The second line specifies a random value with which the snow flakes will move horizontally in. The third line sets the value of the variable rad (short for radians) to zero - nothing too interesting about this line beyond that!

All of the above code was placed in the onClipEvent(load) handler because we are not interested in updating the values of the above variables after initialization. The variables will initialize once, and their values in the load event will stay constant throughout.

onClipEvent(enterFrame)

The code in the following sections are contained in the onClipEvent(enterFrame) handler. The enterFrame handler processes and runs the code continually at a speed depending on your frame rate. Unlike load, the variables and data contained in enterFrame update, therefore this handler makes it ideal to specify continually updating data for vertical movement, horizontal movement, etc.

// horizontal movement
xmovement = _root._xmouse;

The first line updates the value of the variable rad continuously with the value for k which was specified earlier. The variable xmovement updates itself with the x position of the mouse cursor. I used _root._xmouse because I was interested in the cursor's position from the absolute (0,0) origin. Removing _root will cause the mouse cursor's x co-ordinates to originate from the movie clip's registration point - axis.

The third line updates the x position of the snow movieclip. Math.cos(rad) oscillates the flake horizontally similar to the oscillation visible in a cosine curve. The next half of the line adjusts the direction the snow falls in. width/2 helps set the origin of the movement to be 0 toward the center of the value of the width. Dividing by 50 helps dampen the effect. Decreasing the number over-exaggerates the effect - causing a sudden shift in snow movement based on a slight mouse deviation. A large number greatly diminishes the effect. 50 is a nice balance for a movie that is only 300 pixels wide, but you may find a different number suitable for your animation.

// vertical movement
this._y += i;

This section of code specifies the rate at which the snowflakes fall. Since the y-axis in Flash is reversed, increasing the value of y causes the y position of the movie clip to drop. Strange isn't it?

// remove clips when they misbehave (overstep boundaries)
if (this._x>(width+50)) {
this._x = -45;
this._y = Math.random()*height*2;
}
if (this._x<-50) {
this._x = width+45;
this._y = Math.random()*height*2;
}
if (this._y>=height) {
this._y = -50;
this._x = -width+Math.random()*(3*width);
}

The above three sections of code are fairly self-explanatory. The three sections control when to remove a snowflake from display and when to display it again. There are two horizontal boundaries and one vertical boundaries set in the code. Because the width and height are constrained by the actual values of the width and height variables, the boundaries scale evenly with the size of your movie.

Quick Update
 Joel Bircher created an OOP version of the code found in this tutorial, so you can take a look at his version below also!

I have provided both Flash MX 2004 and Flash MX FLAs for your perusal.

 Flash MX 2004 Flash MX 2004 - OOP Version Flash MX

Thanks to senocular for pointing out the fix to get oscillations working in the newer versions of this animation.

Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!