topical media & game development
#graphic-flex-image-effects-06-Flex-Forest.ax
#graphic-flex-image-effects-06-Flex-Forest.ax
[swf]
[flash]
flex
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Sprite;
import flash.filters.BlurFilter;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.events.Event;
import flash.geom.Point;
[SWF(width=550, height=400, backgroundColor=0x111911)]
This class demonstrates how you can construct simple 3D models by rotating
multiple planes and rendering these within a single display object container.
public class @ax-graphic-flex-image-effects-06-Flex-Forest extends Sprite {
private static const TOTAL_TREES:uint = 10; // how many trees
private static const TREE_DISPERSAL:uint = 400; // how far out from center the trees can be placed
private static const TREE_SIZE:uint = 100; // the average pixel width/height of a tree
private static const PLANES_IN_TREE:uint = 4; // the number of planes that are rotated to form a tree
private var _forest:Sprite;
Constructor. This kicks off the drawing of the forest, rotates this sprite
to create an overhead view, and sets up an ENTER_FRAME listener to handle the animation.
public function @ax-graphic-flex-image-effects-06-Flex-Forest() {
create@ax-graphic-flex-image-effects-06-Flex-Forest();
rotationX = 15;
addEventListener(Event.ENTER_FRAME, onSpriteEnterFrame);
}
Creates the sprite that will hold the trees, centers it, then runs through
loop to create each tree and adds it to the sprite.
private function create@ax-graphic-flex-image-effects-06-Flex-Forest():void {
_forest = new Sprite();
_forest.x = stage.stageWidth/2;
_forest.y = stage.stageHeight/2;
// creates bitmap that will be used for tree texture
var treeImage:BitmapData = createTreeImage();
for (var i:uint = 0; i < TOTAL_TREES; i++) {
_forest.addChild(createTree(treeImage));
}
addChild(_forest);
}
Generates bitmap image that will be used for tree texture.
returns: The BitmapData instance containing the generated tree texture.
private function createTreeImage():BitmapData {
var point:Point = new Point();
// create transparent bitmap data instance of the appropriate size
var treeImage:BitmapData = new BitmapData(TREE_SIZE, TREE_SIZE, true, 0x00000000);
// create two additional bitmap data instance of the same size
var leaves:BitmapData = treeImage.clone();
var noise:BitmapData = treeImage.clone();
// fill leaves with solid dark green
leaves.fillRect(leaves.rect, 0xFF005500);
// create grayscale noise
noise.perlinNoise(TREE_SIZE/10, TREE_SIZE/8, 2, 0, false, true);
// copy noise's red channel into greeen leaves alpha, introducing transparency
leaves.copyChannel(
noise,
noise.rect,
point,
BitmapDataChannel.RED,
BitmapDataChannel.ALPHA
);
// draw leaves (with alpha) into triangle shape
var sprite:Sprite = new Sprite();
sprite.graphics.beginBitmapFill(leaves);
sprite.graphics.lineTo(TREE_SIZE/2, 10);
sprite.graphics.lineTo(TREE_SIZE-10, TREE_SIZE-10);
sprite.graphics.lineTo(10, TREE_SIZE-10);
sprite.graphics.lineTo(TREE_SIZE/2, 10);
sprite.graphics.endFill();
// draw triangle shape into bitmap data
treeImage.draw(sprite);
// apply displacement and slight blur to tree image
var displaceFilter:DisplacementMapFilter = new DisplacementMapFilter(
noise,
new Point(),
BitmapDataChannel.RED,
BitmapDataChannel.RED,
0,
-TREE_SIZE/4
);
var blurFilter:BlurFilter = new BlurFilter(4, 4);
treeImage.applyFilter(treeImage, treeImage.rect, point, displaceFilter);
treeImage.applyFilter(treeImage, treeImage.rect, point, blurFilter);
// get rid of data no longer needed
noise.dispose();
leaves.dispose();
return treeImage;
}
Creates sprite containing multiple rotated planes holding tree texture.
parameter: treeImage The BitmapData to apply to each plane in the tree.
returns: The sprite created.
private function createTree(treeImage:BitmapData):Sprite {
var tree:Sprite = new Sprite();
// create and add each plane
for (var i:uint = 0; i < PLANES_IN_TREE; i++) {
tree.addChild(createTreePlane(treeImage, i));
}
// apply some random vertical scaling
tree.scaleY = 1+Math.random()*.8;
// apply random positioning within dispersal area
tree.x = Math.random()*TREE_DISPERSAL-TREE_DISPERSAL/2;
tree.z = Math.random()*TREE_DISPERSAL-TREE_DISPERSAL/2;
return tree;
}
Create single plane that will be used within tree "model".
parameter: treeImage The BitmapData to apply to the plane.
parameter: index The index of the plane within the fuill tree, used to determine rotation.
returns: The sprite created.
private function createTreePlane(treeImage:BitmapData, index:uint):Sprite {
var bitmap:Bitmap = new Bitmap(treeImage);
// center bitmap on registration point
bitmap.x = -TREE_SIZE/2;
bitmap.y = -TREE_SIZE/2;
// place bitmap within sprite so it may be rotated around registration poin
var treePlane:Sprite = new Sprite();
treePlane.rotationY = index*(180/PLANES_IN_TREE);
treePlane.addChild(bitmap);
return treePlane;
}
Handler for ENTER_FRAME event. This rotates the forest.
parameter: event Event dispatched by this sprite.
private function onSpriteEnterFrame(event:Event):void {
_forest.rotationY += 1;
}
}
}
(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.