Adding a Character to the World


In this section we're going to add a character to the simple world we have just created. Our character is nothing more than a ball. The goal is to be able to move the ball around the grid using the arrow keys. If a cell has a type of greater than 1, it is a wall, and we will not let the ball enter this cell.

When an arrow key is pressed, we look ahead to see where the edge of the ball would be if we were to move it there. If the edge is in an acceptable cell (type = 1), then we move the ball there; if not, then we disregard the key press. More specifically, if the right arrow key is pressed, then we look at the ball's current position, plus the ball's speed, plus the ball's radius to form a number that represents the far right edge of the ball if it were to be moved one quantity (or unit) of speed to the right. We then check to see in which cell that far-right point is. If it is in a cell of type = 1, then we move the ball there.

Looking ahead:where is he going to go?

graphics/07fig09.gif

graphics/cd_icon.gif

To see this in action, open character_in_grid.fla in the Chapter07 directory. You will see a new movie clip inside the grid movie clip. It is the character and has an instance name of ball. The ActionScript has three additions:

  1. A function called initializeBall() that creates an object to hold the information about the character (which is a ball). This function also creates a few new variables on the game object.

  2. A function called moveBall(). When this function is called, it moves the ball to a new position if that new position is valid.

  3. An onEnterFrame event. This checks for key presses in every frame. If one of the arrow keys is pressed, then the moveBall() function is called.

Here is the initializeBall() function:

 1   function initializeBall() { 2      game.speed = 3; 3      game.path.ball.swapDepths(10000); 4      game.ball = {startx:1, starty:1, clip:game.path.ball}; 5      var x = (game.ball.startx-1)*game.spacing+game.spacing/2; 6      var y = (game.ball.starty-1)*game.spacing+game.spacing/2; 7      game.ball.clip._x = x; 8      game.ball.clip._y = y; 9      game.ball.x = x; 10     game.ball.y = y; 11     game.ball.radius = game.ball.clip._width/2; 12   } 

The purpose of this function is to initialize all objects and variables needed to hold information about the ball. Line 2 above sets a variable called speed to the game object. This represents the speed at which the ball can move. If a key press is detected on any frame, then the ball will be moved that amount. The next line moves the ball movie clip to a high depth. This is done so that we can see it over the tiles that were attached to the stage. If we do not send the ball to a higher depth than the tiles, then it will be hidden behind the tiles. In line 4 an object called ball is defined on the game object. This object is used to store information about the ball, such as the starting position of the ball and a reference to the movie clip it represents. You'll notice that we set the variables startx and starty both to 1. This is because we are going to start the ball in the first tile. The next two lines use the startx and starty position to calculate the place on the stage where the ball needs to be placed. We add game.spacing/2 to both positions so that the ball will be centered in the tile rather than on its registration point. In lines 9 11 we store the x and y positions of the ball and its radius on the ball object.

Next, let's look at the onEnterFrame event. We'll save the moveBall() function for last.

 1   _root.onEnterFrame = function() { 2      if (Key.isDown(Key.RIGHT)) { 3         moveBall("right"); 4      } else if (Key.isDown(Key.LEFT)) { 5         moveBall("left"); 6      } 7      if (Key.isDown(Key.UP)) { 8         moveBall("up"); 9      } else if (Key.isDown(Key.DOWN)) { 10         moveBall("down"); 11      } 12   }; 

There are two conditional chunks of code in here. One checks to see if either the right or left arrow key is pressed; the other checks to see if either the up or down arrow is pressed. If the right or left arrow key is detected as being pressed, then the moveBall() function is called, and the name of the pressed key is passed in as a string. Likewise, if the up or down arrow key has been detected as being pressed, then the moveBall() function is called, and the pressed key is passed in as a string.

Now let's look at the moveBall() function. It is not complicated, but it is fairly long. This is because we repeat the same sorts of actions for each arrow key (four times).

 1   function moveBall(dir) { 2      ob = game.ball; 3      if (dir == "right") { 4         var tempx = ob.x+ob.radius+game.speed; 5         var tempy = ob.y; 6         var cellx = Math.ceil(tempx/game.spacing); 7         var celly = Math.ceil(tempy/game.spacing); 8         var tempCell = game["cell"+cellx+"_"+celly]; 9         if (tempCell.type != 1) { 10            return; 11         } else { 12            ob.x += game.speed; 13            ob.clip._x = ob.x; 14         } 15      } else if (dir == "left") { 16         var tempx = ob.x-ob.radius-game.speed; 17         var tempy = ob.y; 18         var cellx = Math.ceil(tempx/game.spacing); 19         var celly = Math.ceil(tempy/game.spacing); 20         var tempCell = game["cell"+cellx+"_"+celly]; 21         if (tempCell.type != 1) { 22            return; 23         } else { 24            ob.x -= game.speed; 25            ob.clip._x = ob.x; 26         } 27      } else if (dir == "up") { 28         var tempx = ob.x; 29         var tempy = ob.y-ob.radius-game.speed; 30         var cellx = Math.ceil(tempx/game.spacing); 31         var celly = Math.ceil(tempy/game.spacing); 32         var tempCell = game["cell"+cellx+"_"+celly]; 33         if (tempCell.type != 1) { 34            return; 35         } else { 36            ob.y -= game.speed; 37            ob.clip._y = ob.y; 38         } 39      } else if (dir == "down") { 40         var tempx = ob.x; 41         var tempy = ob.y+ob.radius+game.speed; 42         var cellx = Math.ceil(tempx/game.spacing); 43         var celly = Math.ceil(tempy/game.spacing); 44         var tempCell = game["cell"+cellx+"_"+celly]; 45         if (tempCell.type != 1) { 46            return; 47         } else { 48            ob.y += game.speed; 49            ob.clip._y = ob.y; 50         } 51      } 52   } 

This function accepts a parameter called dir. It represents the string that is passed in, telling the function which key was pressed. In line 2 of the function, we set a reference to the game.ball object called ob. Setting a temporary reference is not absolutely necessary, but it does make the typing a little shorter and actually speeds up the ActionScript a little bit. Next we have an if statement that checks to see if dir is "right", "left", "up", or "down". Very similar actions are repeated for each of the four pieces of this conditional statement. First let's look at lines 3 14, the "right" conditional. The first action in this chunk of code, line 4, sets a variable called tempx that represents the ball's right edge. Since the user is trying to move the ball to the right, we check to see if the ball's right edge would still be in a valid cell if we moved it in that direction. To do this, we use our math trick to determine the cell using the variables tempx and tempy. We then check the object that represents the cell the ball would be over. If the type variable on that object is 1, then it is a valid move. If it is not valid (line 9), then we return out of the function (line 10). If it is a valid type, then we update the ball's position (lines 11 14).

The next three parts of this big conditional statement do the same thing as the first part, except in how they calculate the ball's edge and update the ball's position. The edge of the ball we are interested in depends on the direction of movement. If the down key was pressed, then we are interested in the lowest edge of the ball. If the left key was pressed, then we are interested in the leftmost edge of the ball. Finally all together now if the up key was pressed, then we are interested in the topmost edge of the ball.

graphics/07fig10.gif

Generate a SWF from this file. You can then use your arrow keys to move the ball around. Click the grid to add some walls. Move the ball around and notice how it will not enter a cell that has a wall. Notice that all walls are treated in the same way; it doesn't matter what the wall looks like or how much of the cell the wall occupies. Using creatively drawn walls or smaller cell sizes, this is not as apparent.

One other thing to note is that this is just one way to treat cells in a TBW. More-advanced games have real collision detection within a cell. In that case, the ball could enter a cell that has a wall, but then collision detection checks would kick in to make sure the ball did not move through the wall itself.



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