# Making Snow in Flash CS3



## CPhantom (Dec 14, 2008)

So I've looked all around, followed a few guides, and can't get snow working correctly in flash CS3!


Does anyone know how to make it? I am needing it done for a light snowfall on all 600 x 450 page x.x;


----------



## Egonny (Dec 14, 2008)

That isn't so difficult is it?
Just make a snowflake, make a tween animation, copy the layer a 30 times and move them around.


----------



## CPhantom (Dec 14, 2008)

It's not that simple at all. To get a real snowy effect, you have to use Action Script and write it out as well to get the snow to randomly fall at different sizes, speeds, and transparencies. If you did it the way you said, it'd repeat in the same area over and over again.


----------



## Qith (Dec 14, 2008)

Here, I wrote you some code. I don't think you'd need any alpha difference, since snow's not really see-through... if you want it anyway, you could just change the beginFill code to something like beginFill(0xFFFFFF, rndBetween(0.3,1));.

CODE//***COMMENCE THY SNOWING!***//
stop(); //makes sure this frame keeps looping;
stage.quality = "high"; //sets the quality to high, value can also be StageQuality.HIGH (but this is obviously shorter);
stage.align = "topLeft"; //sets the stage to stick to the top left upon being resized, value can also be StageAlign.TOP_LEFT;
stage.scaleMode = "noScale"; //makes sure the stage does not scale automatically upon being resized, value can also be StageScaleMode.NO_SCALE;

//***SETUP***//
var flakeAmnt:int = 150; //amount of snowflakes;
var flakeSize:Number; //for randomization of flake size later in code;
var minFlakeSize:Number = 1.5; //minimal flake size (for randomization);
var maxFlakeSize:Number = 4.5; //maximum flake size (for randomization);
var avgSpeedY:Number = 1; //average vertical fall speed;
var deviationY:Number = 1.5; //maximum deviation from average vertical speed;
var avgSpeedX:Number = 0; //average horizontal speed (use a negative number to make more flakes go to the left);
var deviationLeft:Number = 1.5; //maximum deviation from average horizontal speed, towards the left;
var deviationRight:Number = 1.5; //maximum deviation from average horizontal speed, towards the right;
var snowFlakes:Array = []; //Array to be filled with snowflakes;

//***FLAKE CREATION***//
for (var i:int = 0; i < flakeAmnt; i++){ //this loop creates all snow flakes, one per iteration;

flakeSize = rndBetween(minFlakeSize, maxFlakeSize); //determine size for this flake;
snowFlakes_ = new MovieClip(); //create a new MovieClip in a new spot in the Array that corresponds to the current iteration's number (i), for the flake to be in;
addChild(snowFlakes); //add the MovieClip to the stage so that it shows up;

snowFlakes.graphics.beginFill(0xFFFFFF, rndBetween(.3,1)); //begin a white (0xFFFFFF is hexadecimal for RGB white) fill for drawing a snow flake into the previously created MovieClip;
snowFlakes.graphics.drawCircle(0,0,flakeSize); //draw a snow flake (a simple circle) around the (0,0) coordinate of the MovieClip, using the size (flakeSize) we determined at the beginning of the loop;
snowFlakes.graphics.endFill; //end fill for the snow flake;

snowFlakes.flakeBlur = new BlurFilter; //create a new BlurFilter instance;
snowFlakes.flakeBlur.quality = 2; //set the BlurFilter's quality to 2 (which is like medium, I wouldn't generally recommend going above 3 since it can get pretty heavy);
snowFlakes.flakeBlur.blurX = snowFlakes.flakeBlur.blurY = rndBetween(1,8); //set the BlurFilter's horizontal and vertical blur values to the same random value;
snowFlakes.filters = [snowFlakes.flakeBlur]; //apply the filter to the flake;

snowFlakes.fallSpeedY = rndBetween(Math.abs(avgSpeedY-deviationY),Math.abs(avgSpeedY+deviationY)); //determine vertical fall speed according to the variables we set in the setup at the top, using the rndBetween function at the bottom;
snowFlakes.fallSpeedX = rndBetween(avgSpeedX-deviationLeft,avgSpeedX+deviationRight); //same thing, this time for horizontal speed;

snowFlakes.x = rndBetween(0,stage.stageWidth); //placement of flake at random horizontal coordinate on stage;
snowFlakes.y = rndBetween(0,stage.stageHeight);//placement of flake at random vertical coordinate on stage;

}

//***FLAKE ANIMATION***//
addEventListener(Event.ENTER_FRAME, fH); //event listener that fires every time the movie enters a new frame, attached to the fH function (acronym for frameHandler), this is ideal for scripted animation;
function fH(e:Event):void { //the function that gets executed every time the event that it is linked to fires;

for (var j:int = 0; j < flakeAmnt; j++){ //another loop, this time it goes through the entire array that contains the snow flakes, to move each flake to its next position;

snowFlakes[j].x += snowFlakes[j].fallSpeedX; //add the flake's horizontal fall speed (which we determined earlier on) to its current place on the horizontal (x) axis, effectively moving it horizontally;
snowFlakes[j].y += snowFlakes[j].fallSpeedY; //same thing, only for the vertical (y) axis. This can't be negative since that would make the snow fly upwards 
	

	
	
		
		

		
			





 ;

//***this segment is for keeping the flakes on the stage, they get "recycled" every time they go out of view***//
if (snowFlakes[j].y > stage.stageHeight+(snowFlakes[j].height/2)){ //if the flake goes completely out of view on the bottom...
snowFlakes[j].y -= stage.stageHeight+snowFlakes[j].height; //make it go all the way to the top so that it shows up again next iteration!
}
if (snowFlakes[j].x > stage.stageWidth+(snowFlakes[j].width/2)){ //same thing, only for the right side...
snowFlakes[j].x -= stage.stageWidth+snowFlakes[j].width; //and here we move it to the left...
}
if (snowFlakes[j].x < 0-(snowFlakes[j].width/2)){ //and this one's for the left side...
snowFlakes[j].x += stage.stageWidth+snowFlakes[j].width; //and we move it to the right.
}
//***end of recycling segment. Note that of the last two parts (which deal with the left and right sides), only one is ever applicable to the current flake since a flake moving to the left never goes off the stage on the right side***//
}

}

//***SIMPLE FUNCTION FOR RANDOMIZING BETWEEN TWO NUMBERS***//
function rndBetween(min:Number, max:Number) { //take the numbers we got from the call to this function (for example if we put "rndBetween(1,2)" somewhere);
return((Math.random()*(max-min))+min); //use Flash's own Math.random() function to generate a random number between 0 and 1,
//then multiply that with the maximum we got from the call *minus* the minimum. This
//will result in a number between 0 and said maximum minus minimum. Now, we add the minimum
//to this number and we end up with a number between the minimum and the maximum! 
}

Good luck with it! 
	

	
	
		
		

		
		
	


	




...Oh man, this has to be the most generous I've ever been.

*EDIT:* You're right, randomizing the alpha does add some depth! You could also blur them, but that would require more code and processing power.

*EDIT 2:* I went ahead and added the blurring XD! Also, it now keeps covering the entire stage, even if you resize it._


----------



## Egonny (Dec 14, 2008)

Qith said:
			
		

> Here, I wrote you some code. I don't think you'd need any alpha difference, since snow's not really see-through... if you want it anyway, you could just change the beginFill code to something like beginFill(0xFFFFFF, rndBetween(0.3,1));.
> 
> CODE//***COMMENCE THY SNOWING!***//
> 
> ...


_











 I'm such a n00b. How the **** did you come up with that?_


----------



## Qith (Dec 14, 2008)

Experience is king! I edited it again, adding the blur and a few other thingies.

_(not that I'm *that* experienced by the way, but in my experience, writing code gets easier every time you do it! 
	

	
	
		
		

		
		
	


	




)_


----------



## CPhantom (Dec 14, 2008)

Oh wow! Thanks a million Qith! You are my hero .


----------



## Qith (Dec 14, 2008)

You're welcome!
Hehe, I just noticed I posted the script like 12 minutes after you'd posted, but I didn't write it *that* quickly. I guess it took me about 45 minutes or something (a little over an hour if you include the comments).


----------



## mbeard (Dec 15, 2008)

Hi,

Sorry this is my first post but I'm not a spammer I just need help and I've never used Flash before 
	

	
	
		
		

		
		
	


	




)

I've kindly borrowed your code for snowing, but one every iteration, the snow is sticking on the screen.

Is there a way of clearing the entire screen on every iteration of the movie?






)


----------



## Qith (Dec 15, 2008)

Hey, go right ahead 
	

	
	
		
		

		
		
	


	




. I'm not sure I understand what you mean by "iteration" in this case though... if you mean on every ENTER_FRAME, clearing the screen every frame already sort of happens... Flash Player completely calculates every frame, every time it enters a new frame, and discards the last one (well behind the scenes it does calculate what it needs to redraw and what it can leave on the screen, but that's not something you can influence with ActionScript).
I'm also a bit in the dark about what you mean by it "sticking on the screen", that sounds like abnormal behaviour... if you mean the snow is leaving traces, then that's really weird. I can only think of that happening when you're drawing it to a Bitmap Object you're displaying and don't empty *that* every frame, but I'm guessing you're not doing that.
There's no easy, general way of clearing the screen, because of the object-oriented nature of ActionScript. You'd have to remove each object from the stage. But if you'd do that each frame, only to generate a new set of snow flakes with random locations, you'd just get noise (it would look kind of like TV noise, probably) and no real object animation.

This script was written in ActionScript 3, are you sure you're using Flash CS3 or CS4 (or another authoring environment that takes AS3) and specifically chose "Flash File (ActionScript 3.0)" when you made a new file to test this in?

*EDIT:* ALSO, if by it sticking to the screen you mean the screen stays white, _that might be because you haven't changed the background colour to something other than white yet_. You can set the file's background colour in the *PROPERTIES* pane.


----------



## Orangegamer (Dec 15, 2008)

can someone tell me where to get flash CS3?
because ive been wanting to explore that program
because u can make lots of cool things
so can someone tell me where u got it?


----------



## Qith (Dec 15, 2008)

If you want to buy it, I suggest you UTFG. I also suggest going for the latest version, which is CS4.

If you want a trial of *CS3*, try this link.

If you want a trial of *CS4*, this link will get you to Adobe's download page if I'm not mistaken; you'll have to create an account and log in before you can download anything though.


----------



## Psyfira (Dec 15, 2008)

You can get a 30 day trial from Adobe's Website, which will last long enough to have a bit of a play with. If you're still in school you can get a student discount on the software, but it's still quite pricey.

(Edit: Qith- Jinx 
	

	
	
		
		

		
		
	


	




)


----------



## mbeard (Dec 16, 2008)

Qith said:
			
		

> Hey, go right ahead
> 
> 
> 
> ...




The flash movie plays fine and the it snows. When I preview my video, by either pressing F12 for CTRL & Enter, the video as a whole loops.

On the final frame, where the snow is, it sticks and the video begins again with the old snow static and the new snow snowing again.

EDIT: I could basically do with, and I don't know if it exists as I started using Flash all of 2 days ago, is a method, which on the last frame of the Flash movie, clears all the snowflakes on the screen. Is this possible?


----------



## Qith (Dec 16, 2008)

Ah, _now_ I understand... this script was meant to run in one single frame that continually loops, instead of *multiple frames*. That's why I put the "stop();" code at the top, that's supposed to stop the movie at this frame (it still generates an ENTER_FRAME event 60 times per second - or whatever you've set the frame rate to be - that's why the code in the "fH" function keeps running even though the movie has been stopped).

The solution would be to take all the frames that you made on the Main Timeline (I assume you've animated something there) and put those into a new MovieClip and place that on the stage in the first frame of the movie. That way, the MovieClip will keep playing (and looping) and the snow can keep falling as well. This is considered good practice anyway, since it helps you to separate the components of your animation or application.

To do this, first make sure you put the actions on a separate layer on top of the rest (again, good practice because of the separation). Just create a new layer, drag it above the other one and cut and paste the code from where it used to be into that frame. Make sure you include the "*stop();*" line!
Then select all of the animation's frames *in the TimeLine pane* (for example, by clicking on the first frame, then shift-clicking on the last one). Right-click on the selection and go "Cut Frames". Next, go "Insert -> New Symbol" and press OK (make sure the type is MovieClip, the name isn't important). Now, you're inside a new MovieClip. The TimeLine pane will display an empty TimeLine, right-click there and go "Paste Frames". Voilà, you've placed your animation into a MovieClip that's now in your Library (which is probably displayed on the right)!

Now, return to the main stage (there's probably a small bar at the top somewhere that has "Scene 1 -> Symbol 1" in it, click on "Scene 1"). There, you can drag the "Symbol 1" MovieClip you just created from the library to the stage, position it where you want it to be and... well it should work!

*EDIT:* Wow, I think I just f*cked up there, the last sentence should make sense now.

*ALSO, I think I found an easier solution* if you're still up for it! Can't believe I didn't think of this earlier XD. Just put

if (!snowFlakes){

before the

var snowFlakes:Array = [];

line and put a second } after the } from the first _for loop_ (line 41 in the original script). That way, the flakes will only be created once and they'll keep on falling. Sorry I didn't think of that before!


----------



## mbeard (Dec 16, 2008)

Qith said:
			
		

> Ah, _now_ I understand... this script was meant to run in one single frame that continually loops, instead of *multiple frames*. That's why I put the "stop();" code at the top, that's supposed to stop the movie at this frame (it still generates an ENTER_FRAME event 60 times per second - or whatever you've set the frame rate to be - that's why the code in the "fH" function keeps running even though the movie has been stopped).
> 
> The solution would be to take all the frames that you made on the Main Timeline (I assume you've animated something there) and put those into a new MovieClip and place that on the stage in the first frame of the movie. That way, the MovieClip will keep playing (and looping) and the snow can keep falling as well. This is considered good practice anyway, since it helps you to separate the components of your animation or application.
> 
> ...



Once again, thanks so much for the reply.

The second method you posted doesn't work, as Snowflakes isn't initialised on the first run through so it errors as Snowflakes is undeclared.

As for your first idea, I'm going to try it now, although this whole Flash scenario is new to me - I'm used to Java, C++ and the like.

EDIT: Does anyone have any good links on how to do this? I honestly have absoloutely no idea how to do this.


----------



## Qith (Dec 16, 2008)

mbeard said:
			
		

> The second method you posted doesn't work, as Snowflakes isn't initialised on the first run through so it errors as Snowflakes is undeclared.
> 
> As for your first idea, I'm going to try it now, although this whole Flash scenario is new to me - I'm used to Java, C++ and the like.
> 
> ...


_
Yeah, I know Flash can be a bitch... the authoring tool & work flow really take some getting used to. You can try Kirupa and goToAndLearn for some great Flash/AS2/AS3 tutorials! Kirupa has lots of non-scripting stuff, you can use those to learn your way around the UI 
	

	
	
		
		

		
		
	


	




.

By the way, since you're used to Java/C++, you're probably used to writing classes to set everything up. You can do this in AS3 as well, it actually makes things a lot cleaner and more manageable, though for small scripts like this one it can be a bit much (in my opinion). Both Kirupa and GTAL have tutorial content regarding this.

(I edited the code, shouldn't have left that stop(); line in, like mbeard noted below)_


----------



## mbeard (Dec 16, 2008)

Qith said:
			
		

> mbeard said:
> 
> 
> 
> ...


_


That works okay, but in itself causes a problem.

I'm guessing its the stop() line. This is stopping all my animation in the other layers. 

Basically I'm making a Christmas themed flash thing as a Christmas decoration which is hooked up to a projector in the IT department of a company. I've (stupidly) volunteered to make it, and at the same time learn flash, so I'm pretty much using my basic knowledge of coding and 3DSMax to get by with tweening etc.

Any ideas of a workaround?

Sorry to bug you, but I also known secretly you like helping people on things you understand, I love helping C++, Java related queries 
	

	
	
		
		

		
		
	


	


_


----------



## Qith (Dec 16, 2008)

Oh crap, sorry, you should totally remove that stop(); line now XD. What I added was kind of a workaround for that.
You're right about the helping thing, I'm not bugged at all, even though I should definitely be doing other stuff that's due this Friday but that's my own choice 
	

	
	
		
		

		
		
	


	




. You should continue doing Flash, ActionScript knowledge is a great virtue these days!


----------



## mbeard (Dec 17, 2008)

Qith said:
			
		

> Oh crap, sorry, you should totally remove that stop(); line now XD. What I added was kind of a workaround for that.
> You're right about the helping thing, I'm not bugged at all, even though I should definitely be doing other stuff that's due this Friday but that's my own choice
> 
> 
> ...




I commented out the Stop() line but I didn't put a post on as I forgot and had nearly finished work.

I think the actual coding of the ActionScipt is very generic and it looks very java-esque. The bit's I don't understand and am going to research into is:

The rate of which the code is redrawn, i'm guessing every frame though.

Other things are example, are what functions are called at what point? For example C++ and Java both have main functions which are ran and everything runs from then etc etc.

I've got an account on Lynda.com in work so I'm going to see whats on there and work out the theory.

My next job, is to make snowy text appear. Oh no!


----------



## Qith (Dec 17, 2008)

It's hard for me to explain the differences, since I _started_ coding with ActionScript. That was AS2, however, and the difference between that and the current AS3 is really quite huge. AS2 was much more basic and a bit of a mess, of course you could organize your code but the rules in AS3 are much more strict. It's not likely to be very much like C++ since that language operates at a much lower level (I know it's not quite low-level, but ActionScript is decidedly high-level), but it is very similar to Java and even more similar to JavaScript (in fact it is based on the ECMAScript standard, which was more or less derived from JavaScript - though that whole history is more complicated than it is relevant 
	

	
	
		
		

		
			





). To be honest, this particular snowing script wasn't very neat, but it's easier to understand like this for someone who has just started out in Flash with no prior programming/scripting knowledge. I'm pretty sure this is not how AS3 is advertised, most tutorials use different methods of enclosing code in functions etc., more Java-like if you will.

Okay I just realized I could go on about this for a pretty long time 
	

	
	
		
		

		
		
	


	




 (but I'm not going to!). The biggest difference between AS and what you're used to, I guess, is that Action*Script* was really designed to be that - a *scripting* language for automating parts of a Flash movie and for adding some interactivity. Since AS1 it has sort of evolved into something more complicated, and I think Macromedia/Adobe took a great step by totally revamping the language after AS2 and losing backward compatibility in favour of faster performance and a generally better-organized language. Right now, you can use AS3 to write full applications completely independent of the animating tools etc. that are in the Flash authoring environment (for example, using Flex). In such cases, it's more programming than scripting. But, when you use it in conjunction with regular (hand-)animation, you really are just scripting and in my opinion it's kind of useless to write classes and such just to get some extra behaviour into your movie. It's just not worth it putting the time and effort into structuring the code like you do when you're writing an application.

So I can see how it would be more difficult to understand the workings of Flash & ActionScript if you're coming from a world of *real* programming 
	

	
	
		
		

		
		
	


	




. Maybe you could look into Flex, which was made for building applications with ActionScript - using that in conjunction with Adobe Air, creating web-interactive desktop applications... Oh the possibilities! 
	

	
	
		
		

		
		
	


	




 (Haven't done much of that myself, actually, but writing this made me realize I really should 
	

	
	
		
		

		
		
	


	




 )


----------

