Erain 3D
-->

Author: Max Pellizzaro
Date: November 18th 2007
version: 3.0

Introduction to Sprite2D

Objective of the tutorial

In this tutorial we will learn how to use Sprite2D feature. Instead of giving my personal definition of Sprite2D object, let’s read together the definition of the Sandy APIs (which I strongly suggest to always consult). So let’s report here Sprite2D definition:

A Sprite2D object is used to display a static or dynamic texture in the Sandy world. The sprite always shows the same side to the camera. This is useful when you want to show more or less complex images, without heavy calculations of perspective distortion.“

So what this means? Well to me it means that we have a “shortcut” to place a rendered 3D object in your scene, always facing the camera, saving lot of calculation not needed. Let’s make some examples: stars on a sky, fishes in the sea, tress in a forest, bullets from a gun. What we are interested in only the prospective view of that object, that will resize based on its x,y,z position. Sprite2D it has been placed in the library to achieve this goal.
In the tutorial you will see how to model a simple forest made of trees and you will be able to move in the forest simulating the fact you are piloting a plane (or something similar). The forest we are going to build is very simple: fixed number of tress with no ground. In a more advance tutorial I will show you how you can simulate an infinite forest with the ground.

How to

Set up

The Document class must be changed to Example0042.as The name of the class in the .as file and the name of the constructor now is: Example0042. In the archive you will find also an image that represent the tree of our forest.

example0042_b.rar

The AS Code

In this section we report the AS code as a reference, and it will be explained in the next paragraph.

package
{
   import flash.display.*;
   import flash.net.URLRequest;
 
   import flash.events.*;
   import flash.ui.*;
   import sandy.core.Scene3D;
   import sandy.core.data.*;
   import sandy.core.scenegraph.*;
   import sandy.materials.*;
   import sandy.materials.attributes.*;
   import sandy.primitive.*;
   import sandy.util.*;
   import sandy.events.*;
 
   public class Example0042 extends Sprite 
   {
      private var scene:Scene3D;
	  private var camera:Camera3D;
	  private var queue:LoaderQueue;
	  private var numTree:Number = 50;
 
	 public function Example0042():void
     {
	   queue = new LoaderQueue();
       queue.add( "tree", new URLRequest("http://www.flashsandy.org/max/tree.gif") );
	   queue.addEventListener(SandyEvent.QUEUE_COMPLETE, loadComplete );
       queue.start();
	 }
 
	  public function loadComplete(event:QueueEvent ):void
      {  
		 // We create the camera
		 camera = new Camera3D( 500, 300 );
		 camera.y = 10;
		 camera.z = -300;
 
		 // We create the "group" that is the tree of all the visible objects
         var root:Group = createScene();
 
		 // We create a Scene and we add the camera and the objects tree 
	     scene = new Scene3D( "scene", this, camera, root );
		 scene.rectClipping = true;
 
		 // Listen to the heart beat and render the scene
         addEventListener( Event.ENTER_FRAME, enterFrameHandler );
		 stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedHandler);
		 stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMovedHandler);
 
      }
 
      // Create the scene graph based on the root Group of the scene
      private function createScene():Group
      {
         // Create the root Group
         var g:Group = new Group();
 
         // let's create the Sprete 2D object
		 for(var i:Number=0; i<numTree; i++)
		 {
		  var bit:Bitmap = new Bitmap(queue.data["tree"].bitmapData);
		  var s:Sprite2D = new Sprite2D("tree"+i,bit,1);
		  s.x = Math.random()*600 - 300;
		  s.z = Math.random()*600;
		  s.y = 0;
		  g.addChild(s);
		 }
		  return g;
      }
 
      // The Event.ENTER_FRAME event handler tells the Scene3D to render
      private function enterFrameHandler( event : Event ) : void
      {
		 //sphere.pan += 1
		 scene.render();
      }
 
	  // This function handles the move foreward or backward simultaion
	  private function keyPressedHandler(event:KeyboardEvent):void {
            switch(event.keyCode) {
				case Keyboard.UP:
				    camera.moveForward(5);
					break;
				case Keyboard.DOWN:
				    camera.moveForward(-5);
				    break;
			}
        }
 
	  // This function handles the direction of the similation movement	
	  private function mouseMovedHandler(event:MouseEvent):void {
           camera.pan=(event.stageX-300/2)/10;
		   camera.tilt=(event.stageY-300/2)/20;
 
        }	
 
 
   }
}

Examining the code

Let’s see what we did in the code…

private var numTree:Number = 50;

You can play with this number and you will notice how it will affect your CPU usage (and this is why in a more advance tutorial we will learn how to use less tree but we will simulate a never ending forest).

queue = new LoaderQueue();
queue.add( "tree", new URLRequest("asset/tree.gif")
queue.addEventListener(SandyEvent.QUEUE_COMPLETE, loadComplete );
 queue.start();

The LoaderQueue is a nice utility given by Sandy3D that allows you to load any external resources, and you can queue all the resources in a “queue” and extract your resources when needed. In this case we need to just load one tree type, but a nice extension of this tutorial is to load different tree types, and randomly use one or the other.

var bit:Bitmap = new Bitmap(queue.data["tree"].bitmapData);
var s:Sprite2D = new Sprite2D("tree"+i,bit,1);

This is the code that allows us to create a Sprite2D object. We need a name, “tree”+i, since this code is placed in a loop to create all the trees. We need a DisplayObject that we build by defining a Bitmap element from the leaded resources. Last we can define the ration of the leaded object; 1 means that we are not resizing the object.

for(var i:Number=0; i<numTree; i++)
{
 var bit:Bitmap = new Bitmap(queue.data["tree"].bitmapData);
	 var s:Sprite2D = new Sprite2D("tree"+i,bit,1);
 s.x = Math.random()*600 - 300;
 s.z = Math.random()*600;
 s.y = 0;
 g.addChild(s);
 }

As you can see we are creating a number of tress as defined in our variable numTree, and randomly placed them in the forest. We just have the y value set to zero, because our “ground” is flat. Well our forest is ready!

Time to see our result!!

The output

For this Flash you have the UP, DOWN key to move forward and backward, and the mouse to choose the direction (always double click the flash to get the focus and beeing able to use the UP and DOWN key).
If you want to learn more, jump to this tutorial now.