Flash 3D Cheats Most Wanted

Now that you know how to create a staggered isometric grid, you'll create a tile with a little more substance (or should we say, volume ). You'll expand the code to attach a new tile randomly to create dynamic isometric cube sculptures. Although you saw in the earlier example on military projection that you can lay out your isometric tiles by hand in the authoring environment, you'll now learn how to use ActionScript to do this, and how this dynamic technique gives you far greater freedom. Eventually it will allow you to create worlds that you can move around in. Here you're going to see how to lay out an isometric world using ActionScript. Along the way, we touch upon the subject of z-ordering as it pertains to isometric tiles.

  1. You're continuing where you left off in the previous example. If you haven't been following in order, you'll find grid_staggered.fla in this chapter's source files. Open it and follow along with this exercise. If you'd like a sneak peek at the finished effect that you're going to create here, take a look at staggered_sculptures.fla .

  2. OK, first off you're going to need a little extra space for this movie since you're going to be stacking isometric cubes on top of one another. Go into the Document Properties dialog box and expand the stage dimensions to 500x400 pixels.

  3. Open up the Library if it isn't already showing using Window > Library (F11), right-click (CMD-click) on the grid tile movie clip, and select Duplicate to create a copy of the symbol. Call the new symbol cube and make sure its Behavior is set to Movie Clip .

  4. Double-click on the new cube movie clip in the Library to open it up for editing, and zoom in on the tile to make it easier to work with. Unlock the guide layer and lock the tile layer.

  5. Click once in an empty area of the stage to make sure you've deselected everything, and then double-click anywhere on the black rectangle to select it all.

  6. With the guide rectangle selected, use the Property Inspector to set its y-coordinate to -10 . This will place it 10 pixels higher than it was. When we're working on a real project and playing with the positions of objects and we don't necessarily know exactly where they're going to end up, we find it easier to position them using the arrow keys on the keyboard. You can hold down SHIFT while using the arrow keys to move objects in larger increments .

  7. Now lock the guide layer and create a new layer using Insert > Layer (or the Insert Layer icon underneath the timeline) and call it tile top .

  8. With the first frame of the tile top layer selected and using the same stroke color as for the grid/floor tile, use the Line Tool (N) to create a second diamond, identical to the first one, by joining the edges of the cross at the center of the rectangular guide.

  9. Join the lower three vertices (corners) of the two diamonds together using the Line Tool (N) as shown in the image below. You will find it easier to draw the perfectly vertical lines if you hold down SHIFT while drawing them to constrain the Line Tool to 45 increments.

  10. Since you will eventually want to fill in the faces of the cube with color, you need to merge the tile and tile top layers . Flash combines strokes that are of the same color on the same layer, so instead of a top tile with vertical extensions and bottom tile, you will end up with a single shape. To do this, start out by unlocking the tile layer and then click on frame 1 of the tile top layer to select all of its contents.

  11. Use Edit > Cut (CTRL/CMD+X) to transfer the selected lines to the clipboard.

  12. Click on the first frame of the tile layer and use Edit > Paste in Place (CTRL/CMD+SHIFT+V) to paste the contents of the clipboard onto the layer.

  13. Click on a free area of the stage to deselect everything. Now if you double-click on any of the lines that make up the cube, you will see that the whole cube gets selected. The two diamonds and vertical beams have merged into a single shape. You'll also notice if you try selecting different parts of the cube that, at the points where two lines of the same color intersect, the lines have been broken up into two segments (in general, when two lines intersect on the same layer, the lines each get broken up into two segments around the intersection point).

  14. Now let's remove those lines that should be hidden from view (in traditional 3D jargon, this is called ”perhaps none too inventively ” hidden line removal ). Select the back face of the lower diamond by holding down SHIFT and clicking on the unwanted line segments. Use the DELETE key to remove the back face of the lower diamond.

  15. Next , using two colors of your choice, fill in the sides and top face of the cube (we used #0066FF for the sides and #0099FF for the top).

  16. Then change the stroke color of the lines to black. Double-click on the border of the cube to select all the lines and use the Stroke Color selector on the Property Inspector to change the color to black ( #000000 ).

  17. While you're at it, you'll do a little housekeeping to keep your movie tidy. Right-click (CMD-click) on the now empty tile top layer and click on the trash can icon to remove the layer. Also, you can hide your guide layer now if you wish since you don't need it any more for this tile:

  18. All right, now that you have your new cube tile ready, you can get to the good stuff and modify the logic for the movie to randomly disperse these cubes around your grid. Before you do that, however, you need to set a Linkage ID for your new movie clip. Open your Library if it isn't already showing (F11), right-click (CMD-click) on the cube symbol, and select Linkage... from the context-sensitive menu. In the Linkage Properties dialog box that opens, enter cube in the Identifier box and click on the Export for ActionScript checkbox to activate it (as usual, Export in first frame automatically gets checked when you check Export for ActionScript , so just leave it checked), and then click the OK button to exit out of the dialog box.

  19. Now you're ready to write some code. Click on the Scene 1 link to exit out of editing the cube symbol and modify the script in frame 1 of the actions layer (in the main timeline) according to the listing below. New and changed code has been highlighted for you.

    // the starting stage x-coordinate for the isometric 3D world WORLD_X = 90; // the starting stage y-coordinate for the isometric 3D world WORLD_Y = 90; // the width of a floor tile in our world TILE_W = 32; // the height of a floor tile in our world TILE_H = 15; // movie clip stacking depth var depth = 1000; // create the rows for (var gridY = 0; gridY < 31; gridY++) { // handle odd and even rows differently if (gridY % 2) { // even row // offset even rows, 16 pixels to the left xOffset = 16 ; // draw one additional tile for even rows numTiles = 11; } else { // odd row xOffset = 0; numTiles = 10; }; // create the columns for (var gridX = 0; gridX < numTiles; gridX++) { // the tile added will either be a grid tile or a cube // there's a 20% chance that it will be a cube var tileID = (Math.random()*10 < 2) ? "cube" : "grid tile"; // attach the chosen symbol _root.attachMovie(tileID, "gridTile"+depth+"_mc", depth++); // calculate the stage x- and y-coordinates to place the tile // based on its grid coordinates (gridX, gridY) var stageX = WORLD_X + (gridX * TILE_W - xOffset); var stageY = WORLD_Y + (gridY * TILE_H / 2); // short-cut reference to the tile movie clip var theTile_mc = _root["gridTile"+depth+"_mc"]; // position the tile to by setting its _x and _y properties theTile_mc._x = stageX; theTile_mc._y = stageY; // randomly stack cubes if (tileID == "cube") { // select a random number of cubes to stack num = Math.abs(Math.random()*4); if (num >= 1) { for (var tileY = 1; tileY <= num; tileY++) { // attach a new cube to the stage _root.attachMovie(tileID, "gridTile"+depth+" _mc", depth++); // short-cut reference to the tile movie clip var theTile_mc = _root["gridTile"+depth+"_mc"]; // calculate the new tile's position theTile_mc._x = stageX; // stack theTile_mc._y = stageY - tileY * (theTile_mc._height/2 - 3); } } } } }

    Let's now concentrate on what you changed and what you added. First, you modified the value of the constant that determines where on the stage vertically that you start drawing the isometric world ( WORLD_Y ). Simple enough. Next, you added the following line that sets the value of a variable called tileID based on whether or not a random number you generate between and 10 is less than 2 . If it is, the value of tileID is set to cube (the symbolID of the cube symbol); otherwise , it is set to grid tile (the linkage ID of our regular grid/floor tile).

    var tileID = (Math.random()*10 < 2) ? "cube" : "grid tile";

    If you haven't seen the ? operator (called a ternary operator) in use before, the preceding line may look very cryptic to you. Actually, it has a very simple syntax. The parentheses around the condition we're checking for are not mandatory, but we use them all the time to make the statements easier to read. The general form of this statement is as follows :

    myVar = (some condition) ? valueOfMyVarIfConditionIsTrue : valueOfMyVarIfConditionIsFalse;

    Next, you attach the chosen movie clip (either the cube or the grid tile, depending on the value of the tileID variable). Everything else is the same as before (and involves placing the chosen grid tile at the correct grid location) until you get to the following new code:

    if (tileID == "cube") { // select a random number of cubes to stack num = Math.abs(Math.random()*4); if (num >= 1) { for (var tileY = 1; tileY <= num; tileY++) { // attach a new cube to the stage _root.attachMovie(tileID, "gridTile"+depth+"_mc", depth++); // short-cut reference to the tile movie clip var theTile_mc = _root["gridTile"+depth+"_mc"]; // calculate the new tile's position theTile_mc._x = stageX; // stack theTile_mc._y = stageY - tileY * (theTile_mc._height/2 - 3); } } }

    To see the effect of this code, test your movie (CTRL/CMD+ENTER), and then comment out this section of code (surround it with /* and */ , like so: /* code block */ ) and test out the movie again. You should see that with the code in place, you get stacked columns of cubes, whereas without the code, you get single cubes:

    So what you do here is find how many extra cubes to stack on top of a cube (if, and only if, the tile you've just added is a cube). Then, you go through a loop, attach the extra cube movie clips, and position them on top of the base cube. The actual code that carries out the positioning is thus:

    theTile_mc._x = stageX; theTile_mc._y = stageY - tileY * (theTile_mc._height/2 - 3);

    As you can see, you're setting the x-coordinate of the stacked cubes equal to the x-coordinate of the base cube. This makes sense when you think about it, since you're putting them on top of one another; thus, only the y-coordinate should be different. To calculate the y-coordinate, you start with the y-coordinate of the base cube and move upward.

  20. Go ahead and test the movie again ( staggered_sculptures.swf ) a couple more times to restart the movie and see the random placement of the cubes in action. Note how cubes that should appear in front of other cubes do so automatically. This is because they are automatically assigned the correct z-order due to the way in which you draw the grid (from left to right and top to bottom). This greatly simplifies your job since you do not have to worry about z-order explicitly. It will also make your life easier when it does come time to take control of the z-order manually in the last example of the chapter. There, you'll make a sprite to move around your 3D world.

In this example, you created a staggered isometric layout and dynamically populated it with some cube-shaped tiles. You did not make the heights of the cubes equal to or a multiple of the height of the floor tile on purpose to escape from the rigidity of the grid.

Going forward, instead of creating random blocks, wouldn't it be nice if you could have various types of tiles and create your worlds based on maps? That's exactly what you're going to do in the next example, where you'll see the more common layout model for isometric maps: the diamond-shaped or rotated model. You'll also see how you can use a tile map to create your worlds with precisely placed tiles.

Категории