topical media & game development
#graphic-flex-image-effects-08-Flex-Rainstorm.ax
#graphic-flex-image-effects-08-Flex-Rainstorm.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;
[SWF(width=550, height=400, backgroundColor=0x000000)]
Demonstrates how rainfall can be simulated using multiple planes of bitmap data
overlaid and animated at different rates.
public class @ax-graphic-flex-image-effects-08-Flex-Rainstorm extends Sprite {
private var _rainData0:BitmapData;
private var _rainData1:BitmapData;
private var _rainBitmap0:Bitmap;
private var _rainBitmap1:Bitmap;
private var _blackRect:BitmapData;
Constructor. Creates assets and sets up ENTER_FRAME handler for animation.
public function @ax-graphic-flex-image-effects-08-Flex-Rainstorm() {
makeSky();
makeRainPlanes();
// this will be used to darken previous frame renders in order to create trailing droplets
_blackRect = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0x44000000);
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.adjustContrast(sky, -0.8);
Adjustments.adjustBrightness(sky, -100);
addChild(new Bitmap(sky));
}
Creates the two planes that will be used for the rain droplets.
private function makeRainPlanes():void {
_rainData0 = getRainTexture(0.4);
// we clone the data since we will be transforming it each frame
// and previous renders need to remain in place
_rainBitmap0 = new Bitmap(_rainData0.clone());
// white droplets will overlay over dark background
_rainBitmap0.blendMode = BlendMode.SCREEN;
addChild(_rainBitmap0);
_rainData1 = getRainTexture(0.5);
_rainBitmap1 = new Bitmap(_rainData1.clone());
_rainBitmap1.blendMode = BlendMode.SCREEN;
addChild(_rainBitmap1);
}
Generates a rain texture using noise, adjustments and blurs.
parameter: density Controls the amount of droplets that should appear.
returns: The bitmap data created.
private function getRainTexture(density:Number):BitmapData {
var noise:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
var perlin:BitmapData = noise.clone();
high contrast, grayscale noise
noise.noise(int(new Date()), 0, 255, BitmapDataChannel.RED, true);
// blur to create more levels of gray
ImageUtil.applyFilter(noise, new BlurFilter(2, 2));
// density setting controls how levels are applied
var black:uint = 240 - 127*density;
var mid:uint = (240 - black)/2 + black;
Adjustments.setLevels(noise, black, mid, 240);
// create additional Perlin noise to add more levels of light and dark
perlin.perlinNoise(50, 50, 2, Math.random(), false, true, BitmapDataChannel.RED, true);
noise.draw(perlin, null, null, BlendMode.MULTIPLY);
perlin.dispose();
// blur slightly more vertically for falling drops
ImageUtil.applyFilter(noise, new BlurFilter(1, 2));
return noise;
}
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 {
// move rain plane data slightly, more vertically than horizontally
new TranslateEffect(1, 6, true).apply(_rainData0);
// draw the black rectangle of low opacity over rain image to create a fade
_rainBitmap0.bitmapData.draw(_blackRect);
// draw new, translated rain data over old data
_rainBitmap0.bitmapData.draw(_rainData0, null, null, BlendMode.SCREEN);
new TranslateEffect(2, 8, true).apply(_rainData1);
_rainBitmap1.bitmapData.draw(_blackRect);
_rainBitmap1.bitmapData.draw(_rainData1, null, null, BlendMode.SCREEN);
}
}
}
(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.