topical media & game development

talk show tell print

#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.