Author: makc
Date: May 20th 2008
version: 3.0.3
In this tutorial we will see how to employ new StarField class to create snow effect.
| This time we will start from code stub somewhat resembling our good old fog demo:
Click to download source files This source will get us started with nice winter forest background asking for some snow. |
First, make a movie clip and draw a snowflake in it. Set it to export to actionscript and type “Snoflake” as a class name:

Second, look at StarField starSprites property. It allows you to use your movie clips or bitmaps as an image for “stars”, and that's exactly what we need. In our code stub we already have StarField named snow; let's put it in good use now:
// TODO make snowflakes here var snowflake:Snowflake = new Snowflake (); for (var k:int = 0; k < 1000; k++) { snow.stars [k] = new Vertex ( /* .x = */ w * (k - 500) / 500, /* .y = */ 600 * (Math.random () - 0.5), /* .z = */ (1000 - scene.camera.z) * Math.random () + scene.camera.z ); snow.starSprites [k] = snowflake; } // set snow depth to -1 to bring it on top of trees snow.depth = -1; scene.root.addChild (snow);
Just like with trees, we need same code to scroll the snow in enterFrameHandler:
// move snowflakes for (var k:int = 0; k < snow.stars.length; k++) { snow.stars [k].z -= 10; if (snow.stars [k].z < scene.camera.z) snow.stars [k].z = 1000; }
Unlike trees, however, snow is supposed to fall down, so we have to add another line to our loop:
// additionally, move them down snow.stars [k].y -= 5; if (snow.stars [k].y < -300) snow.stars [k].y = 300;
Finally, to make it a bit more interesting, we will make snowflakes to swing from side to side a little:
// additionally, move them side to side snow.stars [k].x = w * (k - 500) / 500 + 10 * Math.sin (snow.stars [k].y * 3e-2);
If you actually followed the tutorial, you should have ended up with the code like this:
package {
import flash.display.*;
import flash.events.*
import sandy.core.*;
import sandy.core.data.*;
import sandy.core.scenegraph.*;
import sandy.primitive.*;
import sandy.materials.*;
import sandy.materials.attributes.*;
public class Snowflakes extends Sprite {
// screen size
private var w = 400;
private var h = 300;
// sandy scene
private var scene:Scene3D;
// snowflakes starfield
private var snow:StarField;
// trees array
private var trees:Array = [];
public function Snowflakes () {
// set up scene
scene = new Scene3D ("", this, new Camera3D (w, h), new Group (""));
scene.camera.near = 0;
// set up snow
snow = new StarField ();
// TODO make snowflakes here
var snowflake:Snowflake = new Snowflake ();
for (var k:int = 0; k < 1000; k++)
{
snow.stars [k] = new Vertex (
/* .x = */ w * (k - 500) / 500,
/* .y = */ 600 * (Math.random () - 0.5),
/* .z = */ (1000 - scene.camera.z) * Math.random () + scene.camera.z
);
snow.starSprites [k] = snowflake;
}
snow.depth = -1; scene.root.addChild (snow);
// set up trees in the background
var tree_bmp:BitmapData = new TreePng (1, 1);
var darkness:Material = new Material (
new MaterialAttributes (new MediumAttributes (0xFF000000,
new Vector (0, 0, 300), new Vector (0, 0, 1000))));
for (var i:int = 0; i < 16; i++)
{
trees [i] = new Sprite2D ("tree" + i, new Bitmap (tree_bmp),
0.5 * (1 + Math.random ()));
trees [i].autoCenter = false;
trees [i].floorCenter = true;
trees [i].x = w * (i - 8) / 8;
trees [i].y = -tree_bmp.height;
trees [i].z = (1000 - scene.camera.z) * Math.random () + scene.camera.z;
trees [i].material = darkness;
scene.root.addChild (trees [i]);
}
// subscribe to Event.ENTER_FRAME
addEventListener (Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler (event:Event):void {
// move trees
for (var i:int = 0; i < trees.length; i++) {
trees [i].z -= 10; if (trees [i].z < scene.camera.z) trees [i].z = 1000;
}
// move snowflakes
for (var k:int = 0; k < snow.stars.length; k++) {
snow.stars [k].z -= 10; if (snow.stars [k].z < scene.camera.z) snow.stars [k].z = 1000;
// additionally, move them down
snow.stars [k].y -= 5; if (snow.stars [k].y < -300) snow.stars [k].y = 300;
// additionally, move them side to side
snow.stars [k].x = w * (k - 500) / 500 + 10 * Math.sin (snow.stars [k].y * 3e-2);
}
// render the scene
scene.render ();
}
}
}