topical media & game development
#graphic-flex-image-effects-08-Flex-Snowfall.ax
#graphic-flex-image-effects-08-Flex-Snowfall.ax
[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.events.Event;
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() {
makeSky();
makeSnowPlanes();
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;
addChild(bitmap);
}
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);
_snowPlanesData.push(bitmapData);
bitmap = new Bitmap(bitmapData.clone());
// all planes should just overlay their lighter elements over planes and sky below
bitmap.blendMode = BlendMode.SCREEN;
_snowPlanesBitmaps.push(bitmap);
addChild(bitmap);
// each plane starts its animation off at a different angle
_angles.push(Math.PI/NUM_PLANES*i);
_verticalOffsets.push(0);
}
}
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.