Top-Down Tile Creation and Management


graphics/arrow_icon.gif

In Chapter 8, "The Isometric Worldview," we'll continue our discussion about TBWs as we explore their role in isometric-view games.


Most TBWs in Flash are going to be in either top-down view or 3D isometric view, like Shark Attack! The way you store and manipulate the tile data is exactly the same for both of those views, but the way you display the tiles on the screen is not. In this chapter we look at how to create the tiles in the top-down view and how to store information about those tiles. In the last part of this section, we'll introduce a very powerful but simple math trick that can greatly reduce the processing needed to use a TBW.

Creating the Grid and Storing Information

To build the grid of tiles on the screen, you must use nested loops loops within loops. If you wanted to build just one straight line of ten tiles, you would only need to use one loop. In each iteration of that loop (remember that in this example there would be ten iterations per outer loop) you would use attachMovie() to create an instance of a movie clip, and then you would place it in the correct spot on the stage. Since a grid has several of these types of lines right under each other, we loop the loop to create the entire grid. Remember that we have one loop to create a row of tiles, so then we run this loop one time for each row we want to add.

graphics/tip_icon.gif

Think of the inner loop as a day and the outer loop as a week. The inner loop loops through 24 hours in a day, but it does this from start to finish for each day (the outer loop). So over the course of one week, there would be 7*24 iterations.

We have an outer loop set to loop, say, ten times. For each loop there is an inner loop that adds the movie-clip tiles to the row. Here is sample ActionScript that would handle just adding one line of ten movie clips to the stage.

 1   for (var i=1; i<=10; ++i) { 2      //code to add and place the movie clip 3   } 

That would add one horizontal line of ten movie clips. To make this a grid, we need to start this loop one time for each row that we want to add. So we add an outer loop.

 1   for (var j=1; j<=10; ++j) { 2      for (var i=1; i<=10; ++i) { 3         //code to add and place the movie clip 4      } 5   } 

What happens is this:

  • The outer loop starts at j=1 (which is row 1). While j=1, the inner loop runs from i=1 to i=10 placing movie clips. Row 1 is now complete.

  • The outer loop moves to j=2 (which is row 2). While j=2, the inner loop runs from i=1 to i=10 placing movie clips. Row 2 is now complete.

  • And so on, eight more times.

graphics/cd_icon.gif

Open grid.fla in the Chapter07 directory on the CD to see an example. You will see two movie clips on the stage. One of them has an instance name of grid, and the other has no instance name but has a library name of tile. This movie clip also has a linkage identifier of tile so that we can create instances of it on the stage using ActionScript. In addition, the tile clip has eight frames, each with a different tile. The grid movie clip was placed there so that we can attach the movie clips to it. Building the grid in a movie clip is cleaner than attaching dozens of movie clips to the main timeline. This is the first in a string of example files we'll look at in this chapter, each one building on the previous. By the end of the chapter you'll have a very simple Pac-Man like start to a game. The ActionScript in this file does three things:

  1. Creates an object called game that we use to store information about the grid.

  2. Creates a function called buildGrid() that builds the grid on the stage and builds the data structure that we use to store information about each tile.

  3. Executes the buildGrid() function.

Here is the ActionScript used to create the game object.

 1   game = {};  2   game.columns = 10; 3   game.rows = 10; 4   game.spacing = 30; 5   game.depth = 1000; 6   game.path = _root.grid; 7   game.numberOfTypes = 8; 

Line 1 creates the game object, and all of the following lines add information to that object. Lines 2 and 3 define the dimensions of the grid; line 4 defines the spacing (the number of units between the registration points of the tiles). The next line sets a variable to the object called depth. This value will be incremented and used to assign a depth to each newly created movie clip. As we have seen in the previous chapters, we are starting to make it a habit to store references to movie clips in an object. That makes our code more object-oriented. So in line 6, you can see that a reference to the grid movie clip is created. Whenever we want to do anything with the grid, we don't have to type _root.grid we type game.path. The reference game.path will be interpreted as _root.grid since that is the reference we pointed it to in line 6 above. If at some point during the game-design process we had to change the name or location of the grid movie clip, then all we would have to do to update the code would be to change the game.path reference to point to the new grid location. If we did not use this game.path reference, then changing the name or path to grid would be a large undertaking, because we'd have to update a lot of code. The final line of ActionScript above sets a variable called numberOfTypes on the game object. This variable stores the number of tile types there are in this game definition. Since we have eight frames in the tile clip, each a different tile, then we give numberOfTypes a value of 8.

Next, a function called buildGrid() is defined.

 1   function buildGrid() { 2      for (var j=1; j<=game.rows; ++j) { 3         for (var i=1; i<=game.columns; ++i) { 4            var name = "cell"+i+"_"+j; 5            var x = (i-1)*game.spacing; 6            var y = (j-1)*game.spacing; 7            var type = 1; 8            game.path.attachMovie("cell", name, ++game.depth); 9            game.path[name]._x = x; 10            game.path[name]._y = y; 11            game[name] = {x:i, y:j, name:name, type:type,               clip:game.path[name]}; 12         } 13      } 14   } 

This function uses nested loops, as described earlier in this section. The outer loop loops through the number of rows. In each iteration of the outer loop, the inner loop loops through for each column. Each tile (which we call a cell here) is named uniquely by using the row and column of the cell as part of that cell's name. For instance, if the cell belongs to column 8 and row 6, the name would be cell8_6. In lines 5 and 6, the intended position of the new movie clip is calculated. Then a variable called type is created with a value of 1. This refers to the frame that the tile will display. In this example we start each tile on frame 1. Next, the movie clip is created and positioned. In line 11 we do something really important we create an object to store information about the cell that was just created, such as its type, its name, and a reference to the movie clip it represents.

The final line of ActionScript in this file (not shown) is buildGrid(). It calls the function that we just dissected to create the grid.

graphics/07fig04.gif

Precision Detection

Now it's time to introduce the trick I mentioned: a simple but powerful maneuver that lightens the processor load in TBWs tremendously. Imagine this: If the game of Pac-Man were written in Flash, how would you detect if the Pac-Man character was colliding with a dot to be collected (or eaten, or whatever it is that Pac-Man does with it)? First of all, in Pac-Man everything moves fairly slowly, and precision isn't important, so hitTest() would not be a bad choice. Many early game programmers (including myself at one time) have guessed that you'd need to loop through the entire board, constantly performing hitTest(), to see if Pac-Man has collided with any dots. That is not a very efficient process. Luckily there is a trick that allows us to easily know which cell Pac-Man is in, and therefore only check for a collision in that cell. And of course, one collision detection is a lot less CPU-intensive than 100 collision detections. Let's see how to determine which cell Pac-Man is in.

graphics/07fig05.gif

First, let's look at only one direction, horizontal. In the figure above, you can see that there are five cells, each with a width of 20. Pac-Man's x position is 53. Which cell is he in?

 1   spacing = 20;  2   x = 53; 3   cell_column = Math.ceil(x/spacing); 

In line 1, we set a variable called spacing. That is the width of each cell. Line 2 creates a variable called x that stores the position of Pac-Man. In line 3 we employ the simple math trick by dividing the position by the spacing. We then round that number up to the nearest integer. With this trick we can easily find which cell Pac-Man is in! This works in the same way for a vertical situation.

graphics/07fig06.gif

Like the horizontal example, this one also contains five cells, each with a width of 20. The y position of Pac-Man is 30. Here is how you find the number of the cell he's in:

 1   spacing = 20;  2   y = 30; 3   cell_row = Math.ceil(y/spacing); 

By putting both of these together, we can locate Pac-Man's position in the grid. We find the row and the column he's in, and that specifies the cell in the grid.

 1   spacing = 20;  2   x = 53; 3   y = 30; 4   cell_column = Math.ceil(x/spacing); 5   cell_row = Math.ceil(y/spacing); 

graphics/07fig07.gif

Now that we know which cell Pac-Man is in, we can perform a hitTest() between the Pac-Man movie clip and a dot in that tile. Perhaps you can now understand why this is such a powerful trick. If you are making a game in which the character is walking around, and a few tiles contain water, then when your character is in one of those cells, you can make him swim, or drown, or just slow down a little bit. What typically happens is the following:

  1. You detect which cell the character is in.

  2. You look up the object that represents that cell.

  3. You look at the type of cell that your character is in. If it is a cell of fire, then your character might get hurt. If it is a cell with a secret key, then your character can pick it up and gain points.

graphics/cd_icon.gif

Now let's look at a simple example of this trick. Open grid_click.fla in the Chapter07 directory. This file is a modified version of grid.fla. With the added ActionScript in this file, you click a cell and its type changes. If you click one cell enough times, it arrives back at its original cell type. I've used the trick I just introduced to determine which cell was clicked when the mouse button was pressed. Here is the added ActionScript:

 1   function gameClicked(mx, my) { 2      var x = Math.ceil(mx/game.spacing); 3      var y = math.ceil(my/game.spacing); 4      var cell = "cell"+x+"_"+y; 5      var ob = game[cell]; 6      if (ob.type<game.numberOfTypes) { 7         ++ob.type; 8      } else { 9         ob.type = 1; 10      } 11      ob.clip.tile.gotoAndStop(ob.type); 12   } 13   _root.onMouseDown = function() { 14      var mx = _xmouse; 15      var my = _ymouse; 16      if (game.path.hitTest(mx, my)) { 17         gameClicked(game.path._xmouse, game.path._ymouse); 18      } 19   }; 

Look at lines 13 19 first, the onMouseDown event. When the mouse button is pressed, the coordinates of the mouse are saved. If these coordinates are over the grid movie clip (referenced by game.path), we call the gameClicked() function above, passing the coordinates of the mouse into gameClicked(). In lines 2 and 3 we use the trick described in this section to determine the cell that was clicked. In the following line we construct the name of the object that contains information about this cell, and then in line 5 we create a reference to that object called ob. Lines 6 10 check to see if ob.type is less than 8, and if it is, we increment it; otherwise we set it back to 1. Finally, on line 11, we change the frame where the movie clip is to match that of the tile type.

Create a SWF from this file and test it out. Click the cells to change the cell types. Types 2 8 are walls. You can easily create unique configurations of the board.

graphics/07fig08.gif

In the next section we will go over how to add a character to this TBW.

graphics/tip_icon.gif

A character can be anything from a ball to a human. In most games, a character is something the game player can relate to, usually some living being. In the example given in the next section, the character is a ball.



Macromedia Flash MX Game Design Demystified(c) The Official Guide to Creating Games with Flash
Macromedia Flash MX Game Design Demystified: The Official Guide to Creating Games with Flash -- First 1st Printing -- CD Included
ISBN: B003HP4RW2
EAN: N/A
Year: 2005
Pages: 163
Authors: Jobe Makar

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net