topical media & game development

talk show tell print [swf] [flash] flex

  package {
          import aether.effects.transformations.TranslateEffect;
          import aether.utils.Adjustments;
          import aether.utils.ImageUtil;
          import flash.display.Bitmap;
          import flash.display.BitmapData;
          import flash.display.BitmapDataChannel;
          import flash.display.BlendMode;
          import flash.display.Sprite;
          import flash.filters.BlurFilter;
          import flash.geom.Matrix;
          import flash.geom.Point;
          [SWF(width=550, height=400, backgroundColor=0xABC8D2)]
Demonstrates how snowfall can be simulated using multiple planes of bitmap data overlaid and animated at different rates.

          public class @ax-graphic-flex-image-effects-08-Flex-Snowfall extends Sprite {
                  private static const NUM_PLANES:uint = 3;
                  private static const VERTICAL_MOVEMENT_RATE:Number = 0.3;
                  private static const HORIZONTAL_MOVEMENT_RATE:Number = 0.05;
                  // the amount the snow planes should move back and forth horizontally
                  private static const HORIZONTAL_MOVEMENT_RANGE:Number = 20;
                  private var _snowPlanesData:Vector.<BitmapData>;
                  private var _snowPlanesBitmaps:Vector.<Bitmap>;
                  private var _angles:Vector.<Number>;
                  private var _verticalOffsets:Vector.<Number>;
Constructor. Creates assets and sets up ENTER_FRAME handler for animation.

                  public function @ax-graphic-flex-image-effects-08-Flex-Snowfall() {
                          addEventListener(Event.ENTER_FRAME, onSpriteEnterFrame);
Creates the bitmap data with the sky image.

                  private function makeSky():void {
                          var sky:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
                          sky.perlinNoise(250, 200, 3, Math.random(), false, true, BitmapDataChannel.RED, true);
                          Adjustments.setLevels(sky, 0, 150, 240);
                          var bitmap:Bitmap = new Bitmap(sky);
                          // overlay clouds over colored background
                          bitmap.blendMode = BlendMode.SCREEN;
Creates the multiple planes that will be used for the snow.

                  private function makeSnowPlanes():void {
                          // save the data into vectors to be used in animation
                          _snowPlanesData = new Vector.<BitmapData>();
                          _snowPlanesBitmaps = new Vector.<Bitmap>();
                          _angles = new Vector.<Number>();
                          _verticalOffsets = new Vector.<Number>();
                          var width:Number = stage.stageWidth;
                          var height:Number = stage.stageHeight;
                          var bitmapData:BitmapData;
                          var bitmap:Bitmap;
                          // create all of the planes based on the NUM_PLANES constant
                          for (var i:uint = 0; i < NUM_PLANES; i++) {
                                  // create texture -- the third argument is the density of the plane, the fourth the scale of the flakes
                                  bitmapData = getSnowPlane(width, height, 0.05 + 0.001*i, i+1);
                                  bitmap = new Bitmap(bitmapData.clone());
                                  // all planes should just overlay their lighter elements over planes and sky below
                                  bitmap.blendMode = BlendMode.SCREEN;
                                  // each plane starts its animation off at a different angle
Generates a snow texture using a pixel dissolve that is scaled up and a blur.
parameter: density Controls the amount of flakes that should appear.
returns: The bitmap data created.

                  private function getSnowPlane(width:Number, height:Number, density:Number, scale:Number):BitmapData {
                          var snow:BitmapData = new BitmapData(width, height, true, 0x00000000);
                          var dissolve:BitmapData = snow.clone();
                          // pixel dissolve transparent image to a white color to create white dots
                          dissolve.pixelDissolve(dissolve, dissolve.rect, new Point(), int(Math.random()*255), width*height*density, 0xFFFFFFFF);
                          // scale up dissolve so that dots become larger and blurred
                          var matrix:Matrix = new Matrix();
                          matrix.scale(2*scale, 2*scale);
                          snow.draw(dissolve, matrix, null, null, null, true);
                          // blur it more
                          ImageUtil.applyFilter(snow, new BlurFilter(4, 4));
                          return snow;
Handler for ENTER_FRAME to control animation of multiple planes of bitmap data.
parameter: event Event dispatched by this sprite.

                  private function onSpriteEnterFrame(event:Event):void {
                          var x:Number;
                          for (var i:uint = 0; i < NUM_PLANES; i++) {
                                  // each plane is animated using sine values
                                  x = Math.sin(_angles[i]) * HORIZONTAL_MOVEMENT_RANGE;
                                  // planes move vertically at different rates based on their depth
                                  _verticalOffsets[i] += (VERTICAL_MOVEMENT_RATE + (i*VERTICAL_MOVEMENT_RATE)/2);
                                  // translate the original data, not the previously translated data
                                  var clone:BitmapData = _snowPlanesData[i].clone();
                                  new TranslateEffect(x, _verticalOffsets[i], true, 0x000000, true).apply(clone);
                                  // put new data in bitmap
                                  _snowPlanesBitmaps[i].bitmapData = clone;
                                  _angles[i] += HORIZONTAL_MOVEMENT_RATE;

(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.