Flash_and_Flex_03_2009

3D Methods of Display Objects in Flash Player 10

Our next example involves drawing a 3D cube in the form of the six-sided die shown in (Figure 3). Setting up the stage To illustrate a different way of producing a 3D object, in this application we use six MovieClip objects that we create on the stage at authoring time. In this case, we use the Rectangle tool to draw a 160 by 160 square with black stroke and white fill, and we used the Oval tool to draw black-filled circles of width 25. By using the Object Drawing mode, it is easy to duplicate and position the circles to make each of the faces of the die fairly quickly. Once each face is drawn, we select each and choose Modify > Convert to Symbol to make it a MovieClip with registration point in the center. (Ours are called FaceClip1 , FaceClip2 , etc.) Use the Properties panel to give these new MovieClips the instance names mcSide1 , mcSide2 , mcSide3 , mcSide4 , mcSide5 , and mcSide0 (for the face with six spots). You can leave these piled up on the stage for now – they will be positioned by our code at run time. The stage set up is shown in (Figure 4). Before delving into the code, we will give an overview of the basic strategy.

First, we will create a Sprite object called spCube that has as children the six MovieClips we just created. We will position these clips as 3D objects in space. For example, we will place mcFace1 closest to ourselves at coordinates (0,0,-80), and we will place mcFace2 to the left of center at coordinates (-80,0,0) but rotated 90 degrees about the y-axis so that it is perpendicular to our view plane. We similarly place the other four sides to literally construct a cube in space with our MovieClip faces. Everything would work splendidly at this point if Flash automatically sorted the 3D objects by z-distance, but it does not. Consequently, working with the spCube object directly will look very strange since no matter what order the faces are supposed to be in , they will always be displayed according to their original order in the display list. So we need some code that will break the cube apart and rebuild it to make the display list order coincide with the z-distance order. There is no easy way to detect when this needs to be done, so we will take the approach that every time the screen is updated, we will destroy the cube and rebuild it in the correct order. The key ingredients to keeping up with the existing order and changing to the desired order are Vector3D objects holding the original

coordinates of the centers of the faces and the transform.matrix3D property of spCube that knows the current orientation of the cube at all times. The code We first position mcSide0 , …, mcSide5 to form a cube within the Sprite object spCube , which in turn will be a child of the Sprite container spBoard , the rectangular region the cube floats over. The variables picSize , boardWidth and boardHeight establish the size of everything that will be drawn at run time. The remaining variables below are simply declared here for use later on, see (Listing 5). When we need to do our z-sorting, we will sort with respect to the midpoints of the faces. Each midpoint is a point in 3D, and thus, it can be represented as an instance of the Vector3D class, so the collection of all midpoints will form an array of Vector3D objects. An array whose elements are of the same data type can be represented as an instance of the Vector class, also new to Flash CS4. Since vecMidPts should be a Vector consisting of Vector3D objects, the following declaration/constructor is used. We populate this Vector object with midpoints of the cube in three-dimensional space using the variable picSize (set above) to keep the code as general as possible. Note that the coordinates are relative to spCube , and the point (0,0,0) will be the center of the cube, see (Listing 6). We will put each of the dice face MovieClips into an array of MovieClips . Since each element of the array will have the same type, we can use the Vector class once again. Notice that vecSides[0] contains the face with six spots, see (Listing 7). We next call the functions that initialize our application,thoughthefunctionswillbedefined a bit later. The isRotating variable governs the rotation of the cube but will not be true until the mouse button is down . The setUpListeners function adds mouse listeners for the mouse down and drag rotation motion. However, the main ideas we want to focus on first are in the makeCube and sortFaces functions. var vecMidPts:Vector. = new Vector.(6);

Listing 9. The sortFaces function destroys the cube and rebuilds it based on z-order

function sortFaces():void {

var arrDist:Array = new Array(6); var i:int; var curMatrix:Matrix3D; var curMid:Vector3D; curMatrix = spCube.transform.matrix3D.clone(); for (i=0;i<6;i++){

curMid = curMatrix.deltaTransformVector(vecMidPts[i]); arrDist[i] = {distance:curMid.z, i:which};

}

arrDist.sortOn("distance",Array.NUMERIC | Array.DESCENDING); while (spCube.numChildren>0){ spCube.removeChildAt(0); } for (i=0;i<6;i++){ spCube.addChild(vecSides[arrDist[i].which]);

} } Listing 10. Set up the mouse listeners for rotation dragging function setUpListeners():void { spBoard.addEventListener(MouseEvent.ROLL_OUT,boardOut); spBoard.addEventListener(MouseEvent.MOUSE_MOVE,boardMove); spBoard.addEventListener(MouseEvent.MOUSE_DOWN,boardDown); spBoard.addEventListener(MouseEvent.MOUSE_UP,boardUp); }

isRotating=false; setUpListeners();

makeCube(); sortFaces();

To understand the makeCube function, consider that to make a cube, each MovieClip face must be placed correctly and then rotated in 3D to have the correct orientation. The placement is easy since we built

03/2009 (5)

81

Made with FlippingBook HTML5