Collision Detection
At this stage in the project, with the environment built and balloons in place, it's time to display the main character and have a way to make it move. To do this, you'll create a new function called initPuffin. To get the character on the stage dynamically, you'll need to be able to access it from the Library. For this, you'll have to assign Linkage properties to the movie clip.
Open the Library and select the movie clip playerMC and double-click to go into Edit mode.
Select the movie clip playerMC on the Stage. Assign the instance name to playerMC: puffin_mc.
Select the playerMC in the Library. Then right-click/Ctrl-click and select Linkage. This launches the Linkage Properties panel. In the Identifier text field, type playerMC.
Select the Export for ActionScript and the Export in first frame options. Click OK.
Now you'll write the script to display the character and allow the user to manipulate it by using the arrow keys.
Navigate back to the Tree Maze main Timeline. Click on Frame 1 of the functions layer and add this script after the initTiles() function:
Listing 5.8
function initPuffin() { //Place an instance of the playerMC on stage (given the instance name 'player') addSprite("playerMC", "player", charLoc[0], charLoc[1]); //Create the 'characterName' variable as a shortcut, to reference the much longer nested name. _global.characterName = cell.player; //Character stands still until the player presses a key. characterName.puffin_mc.gotoAndStop("still"); inMotion = false; //Define motion and collision detection variables. //The bounds variable is referencing a built-in Movieclip method to obtain 4 variables related to the character - xMax, yMax, xMin, and yMin. //The speed of the character is relative to the size of the tiles bounds = characterName.getBounds(characterName); }
The addSprite() function places an instance of the playerMC movie clip from the Library onto the Stage in the top-left portion of the maze, using the charLoc value you defined in the initTiles function. Then, to save typing later on, you can create a variable named characterName to store a reference to the cell.player path.
After the character is on the Stage, you'll want to pause the animation. Otherwise, the puffin will be walking in place! You'll make the playhead advance to a frame in the animation where the puffin is standing still, and create a variable to indicate its status.
NOTE
For this game, you will write a math-based collision-detection script. Rather than using the built-in hitTest() method, you will write a script that calculates the position of the player against the bounds of the tree tiles. This process provides far greater accuracy and flexibility, which is also useful if you want to extend your game and add more levels of complexity.
Enter the script here after the previous code on Frame 1 of the functions layer:
Listing 5.9
//The set_coords function is used for collision checking against a tile. function set_coords() { var a = to_tile(characterName._x, characterName._y); _global.playerc = {x:a.x, y:a.y}; } //The move function is called whenever the player presses (or holds) a key. function mc_move(x, y, bounds) { var top = Math.floor(characterName._y+y); var bot = Math.floor(characterName._y+y+bounds.yMax/2); var lef = Math.floor(characterName._x+x); var rig = Math.floor(characterName._x+x+bounds.xMax/2); switch (obstacle) { case (get_tile(lef, top)) : case (get_tile(lef, bot)) : case (get_tile(rig, top)) : case (get_tile(rig, bot)) : break; default : characterName._x += x; characterName._y += y; break; } }
The set_coords() function will take the current x and y location of the player on stage and translate that to an array position using the to_tile() function. This will then be assigned to a global variable so that it can be used in other timelines.
The mc_move() function determines the boundaries of the character and compares these to the array value of its current tile and the tile it is moving toward. The switch statement will not execute if the player character is colliding with an obstacle (if its current position in the array is equal to 2). Otherwise it will move in the direction of the values passed to the function.
A break statement is used to end execution of the case. Here, multiple case statements are nested to make sure that all of the conditions are met; otherwise, the default action is carried out.
The following figure shows what your code should look like at this point.
NOTE
Because the new version of Flash is more strongly typed than older versions, you must use the proper format when calling the xMax and yMax variables, variables which were created by the getBounds method in the initPuffin() function, by capitalizing the letter M. Not doing so would be perfectly acceptable in previous versions of Flash (including Flash MX), but will cause the motion to fail in this version.
Go to the actions layer. Type in the following statements right after the map Array:
Save your work.
Listing 5.10
//Place the tiles initTiles(); //Define the player character initPuffin();
Finally, the initialization functions are called once, when the game begins.