Flash: Kirupa Snow in AS3.0

by troy on November 26, 2008

Thanks to Kirupa for the very popular snow tutorial effect...goes back ages..AS1.

While I'm sure one for AS3 exists, there's not much codeso I just converted the AS2 one here, which apparently was converted from the AS1 version here

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Follow pretty much either of them to get the gist if you need pictures of the IDE.

I differ slightly in implementation.

Create a new MovieClip named SnowFlake, draw the appropriate snow graphic, (e.g. a white 4x4 pixel circle at -2,-2). Right click in the library and give it a linkageID of "SnowFlake" as it will be needed by the SnowField Generator.

Create a 2nd MovieClip named SnowField inside draw a outlined box no fill the dimensions you want the snow to fill. Paste the following on it's frame1.

var snowflakes:Array = new Array();
var snowflakeProps:Dictionary= new Dictionary(true);
var max_snowsize:Number = .04;
// pixels
var snowflakesCnt:Number = 150;
var oheight:Number;
var owidth:Number;
init();
function init():void {
 
	owidth = width;
	oheight = height;
	// quantity
	for (var i:int=0; i<snowflakesCnt; i++) {
 
		var t:MovieClip = new SnowFlake();//
		t.name = "snowflake"+i;
 
		t.alpha = .2+Math.random()*.6;
		t.x = -(owidth/2)+Math.random()*(1.5*owidth);
		t.y = -(oheight/2)+Math.random()*(1.5*oheight);
		t.scaleX = t.scaleY=.5+Math.random()*(max_snowsize*10);
		var o:Object = new Object();
		o.k = 1+Math.random()*2;
		o.wind = -1.5+Math.random()*(1.4*3);
 
		snowflakeProps[t] = o;
 
		addChild(t);
		snowflakes.push(t);
	}
	addEventListener(Event.ENTER_FRAME, snowFlakeMover);
}
function shakeUp():void{
	for (var i:int=0; i<snowflakes.length; i++) {
		var t:MovieClip = snowflakes[i] as MovieClip;
		t.x = -(owidth/2)+Math.random()*(1.5*owidth);
		t.y = -(oheight/2)+Math.random()*(1.5*oheight);
	}
}
function snowFlakeMover(evt:Event):void {
	var dO:MovieClip;
	var o :Object;
	if(visible && parent.visible){
	for (var i:int = 0; i < snowflakes.length; i++) {
		dO = snowflakes[i] as MovieClip;
		o = snowflakeProps[dO];
		dO.y += o.k;
		dO.x += o.wind;
		if (dO.y>oheight+10) {
 
			dO.y = -20;
 
		}
		if (dO.x>owidth+20) {
 
			dO.x = -(owidth/2)+Math.random()*(1.5*owidth);
			dO.y = -20;
 
		} else if (dO.x<-20) {
 
			dO.x= -(owidth/2)+Math.random()*(1.5*owidth);
			dO.y = -20;
		}
 
	}
	}
}

Some interesting aspects of this approach.

  • we capture the size of the manually built bounding box, this is generally easier to work with than variables for designers, in the Fla the outline is invisible
  • using a Dictionary to store the various model for the MovieClip view, instead of appending them to the MovieClip. They could be arbitrarily complex and have strong typing if so desired.
  • one centralized animation loop, useful if you ever want to say stop all flakes, most the old approaches had onEnterFrame per snowflake, making them harder to wrangle. It might also be slightly faster with it centralized, not 100% sure.
  • we disable the animation if the clip or the parent is invisible, or it's been removed from stage, bumping up the number of particles this is likely to help performance
  • add a reposition animation that is useful for reusing the snow component between scenes, but keeping the snow fresh
  • fun with the gradient glow filter to create a semi icecube effect on the text
  • fun with the bevel filter to create a snow bank effect

Here's the FLA

{ 18 comments… read them below or add one }

Kenny Dorman December 10, 2008 at 8:34 am

Hi Troy,

Firstly, please accept my sincerest gratitude for sharing your AS3 snow solution.

I’m a simple graphic designer with zero ActionScript (read: Programming) skills. I had been trying Kirupa’s solutions only to ultimately become frustrated at the fact I had an AS3 dependent screensaver project and none of the earlier AS revisions would compile. I also kept coming up against truly horrific memory leak issues with Flash AVM2 eg. running for 15 minutes I lost 1Gb RAM! [*not* good for a screensaver – there does appear to be known problems with Garbage Collection in AVM2 – I’ve since been using a hack by Grant Skinner to force GC ]

Your solution works excellently. I converted the snow symbol to a dollar sign, since the screensaver theme is about “improving financial performance” – I needed a ‘dynamic’ solution to add a little spice to a relatively dry as dust subject.

I’m hoping that you can perhaps advise me on your last two bullet points and maybe something else I was considering?

I don’t see any ‘glow’ filter being applied – does that have to be applied via filters in the Properties panel, or do I need to tweak a value in the script? Likewise, how do you invoke the snow bank effect via the Bevel filter?

I was hoping that perhaps I could have the snow (dollar) particles/objects increase in scale as they advanced to the bottom of the screen. Alternatively, is it possible to have the objects ‘skewed’ in such a fashion as to create the illusion of perspective? [i.e. objects appear to be advancing towards you – sort of opposite direction to the lucas arts Star Wars credits – perhaps fading into the scene]

Rather than the objects simply vanishing with a blip when they meet the total number threshold and push(ed) off the stack – can they decay with opacity over time i.e. fading to zero % alpha; then removed if at 0%? Can that be done with the maths in your script? Also, what would I have to do to the script to make the particles move in the opposite direction i.e. advance to the top of the screen instead of down?

Lastly, I note that the ‘SnowField’ behaves like a mask, where the snow fills the area not covered by the field. Is it possible to have it behave in the opposite direction i.e. particles render inside the field; and, if so, can the field be an alternative shape eg. triangle? I would also like to have the snow transition between multiple SWFs [see array loader comments below] – is that possible?

From not having used Flash since version 5.x, I’ve come up against a tremendous amount of issues in the last fortnight trying to produce what I thought would be a relatively simple project in Flash CS3 eg. building an array loader for multiple SWFs > I now have this working with AS3 but, I’ve still to discover whether I can compile the separates via the loader in such a way that a Sreensaver compiler can create the final *.scr installer – have you ever done this successfully? Are there any Screensaver compilers you’d recommend? [I have access to both a Mac & Windows machine]

Apologies that I’ve wittered on a bit here, it’s probably due to the relief I’m feeling of discovering your AS3 snow solution :-) but hope that you can spare a little time to advise me on any of my queries above.

Yours gratefully,

Kenny Dorman

Kenny Dorman December 10, 2008 at 10:14 am

“I note that the ‘SnowField’ behaves like a mask”

To explain…I meant if you reduce the scale of ‘SnowField’ to smaller than the stage, the particles/objects render outside the field as opposed to inside it – eg. if resizing SnowField from top > bottom (so now half stage height) the objects disappear as they approach the perimiter of the (invisible) field.

K:-D

troy December 10, 2008 at 5:58 pm

Hi Kenny,

Thanks for the feedback. Unfortunately I’m very busy and you’ve asked a ton of questions so I’m not going to be able to answer them all.

The gradient glow filter is for the “Snow AS3.0” text in the middle, not the snowflakes. By adjusting the white towards the edges and transparent in the middle it somewhat imitates a icecube (to me at least). If you want to apply a glow to snow itself either do it on the snow flake/dollar sign by taking the graphic inside the snowflake symbol, and making it a nother symbol, and applying the filter to it.. e.g.

Snowflake_mc
+- someGraphicSymbol with fitlers

Making the flakes grow as they travel is just a matter of increasing the scaleX and scaleY as they move, and remembering to reset when they regenerate. You need to find some contractors skilled in programming you can hit up, I am unfortunately already overworked.

You could achieve the Star Wars effect in Flash10 by rotating the rotationX, or by adding a z depth and doing depth sorting. There are a few tutorials for 3d on the web.

You can do the decay of opacity over time by adding something like
o.fade = -.01;

in the init loop and in the snowFlakeMover add
dO.alpha += o.fade;

to make the flakes move the opposite direction, take the clip that contains the snowfield and using the transform tool flip it upside down.

I was able to change the size of the snowfield smaller than the stage, not sure what you are doing wrong.

You can mask the snow_mc effect however you want to make snow appear inside outside of whatever shapes you give it.

No idea on the screensaver. Sorry.

Yes I feel your pain, flash CS4 has even more changes in the UI, especially the tweening (cool though!)

Good luck.

Kenny Dorman December 11, 2008 at 8:57 am

You’re a gent for replying Troy – much appreciated.

Gradient glow – my error…misinterpreted the bullet point.

Reverse direction transform – that works, but with dollar sign being a non-symmetrical object I’ll need to originate the dollar in a reflected state otherwise it’s inverted/flipped once transformed.

SnowField – I believe it’s to do with the origin point. I used the Sub-selection tool and moved the top vector corners down towards the bottom, but the origin point is still at 0,0; so, “flakes” are starting from there (0,0) and travelling down screen then vanish as they reach object (SnowField) boundary. If I resize the SnowField b/box using the Free Transform tool then it distorts the particles eg. squashed. I’m now, as I write, realising that I should have resized by moving the bottom upwards in the MC then re-situate entire field to the bottom of the stage, therefore, taking the origin point downwards with the object. Likewise, I should have tried resizing the field in the MC *not* the stage when using the Free Transform tool – that way, the objects don’t get distorted. Doh!

Thanks for the other tips – I’ll definitely try your suggestions for the opacity fade. I suspect the 3D Star Wars credits transform is beyond my current capabilities and will leave for a project were deadline isn’t critical.

Once again, my genuine thanks. Best wishes from Scotland.

K:-D

gherat December 29, 2008 at 11:02 am

The alpha part does not work this way..

t.alpha = 20+Math.random()*60;

should be

t.alpha = (20+Math.random()*60)/100; or t.alpha = 0.2+Math.random()*0.6

This is because alpha value ranges between 0 and 1

Cheers gherat..

Markus February 24, 2009 at 4:49 am

Great, I really needed this for my AS3 project!

Thx so much! :)

Eli December 29, 2009 at 10:25 am

amazin thanks

Wandrew Wang September 22, 2012 at 2:42 am

hey thanks for sharing =D

but I use CS5

Can this work with your code too?

Wandrew Wang September 22, 2012 at 2:45 am

oh I just saw

“would this also work for cs5?
adaire987 1 年 以前
It should do
TheICTGuy 回覆對象: adaire987 1 年 以前”

on your youtube

haha thanks for sharing

Julie October 17, 2013 at 4:50 pm

I LOVE this! My only problem is that every time I try to add a click tag I lose the snow. Any suggestions?

troy October 18, 2013 at 1:18 am

Hmm, Not sure what you mean by click tag. Probably need some programmer to look over it for you if you don’t read the AS3 (which is reasonably simple)

janelle December 16, 2013 at 3:24 pm

How can I get the snow flakes to fall inside of a object an not just across the stage?

Gabriel R December 16, 2013 at 8:53 pm

Awesome !! Is there a way to make it stop lets say after 15 seconds??

troy December 16, 2013 at 9:54 pm

Yes just use a setTimeout to remove the event listener on the render.

troy December 16, 2013 at 9:56 pm

Use a mask with whatever holes you want (e.g. text) over the clip with the snowflakes.

Gabriel R December 17, 2013 at 11:25 am

awesome, thank you Troy

Cameron December 22, 2013 at 4:52 pm

Hi, I love your tutorial troy and want to use it in a game of mine but I cant find the loop in the animation. Do you know where the loop in the flash animation starts please?

troy December 22, 2013 at 6:24 pm

addEventListener(Event.ENTER_FRAME, snowFlakeMover); in the init funtion

Leave a Comment

 

{ 1 trackback }

Previous post:

Next post: