HTML5 Canvas [193]
GAME_STATE_CHECK_FOR_GAME_OVER
This state will first check to see whether the player is dead, and then check to see whether he has won. That means that the player cannot win if an enemy tank makes it to the goal on the same try as the player.
If the player has lost, the state changes to GAME_STATE_PLAYER_LOSE; if the player has won, it moves to the GAME_STATE_PLAYER_WIN state. If neither of those has occurred, the game is set to GAME_STATE_WAIT_FOR_PLAYER_MOVE. This starts the game loop iteration over, and the player begins her next turn.
GAME_STATE_PLAYER_WIN
If the player wins, the maxEnemy is increased for the next game. The player’s score is also checked against the current session high score to determine whether a new high score has been achieved. This state waits for a space bar press and then moves to the GAME_STATE_NEW_GAME state.
GAME_STATE_PLAYER_LOSE
The player’s score is checked against the current session high score to determine whether a new high score has been achieved. This state waits for a space bar press and then moves to the GAME_STATE_NEW_GAME state.
Simple Tile Movement Logic Overview
Micro Tank Maze employs simple tile-to-tile movement using the “center of a tile” logic. This logic relies on making calculations once the game character has reached the center of a tile. The origin point of our game character tiles is the top-left corner. Because of this, we can easily calculate that a game character is in the center of a tile when its x and y coordinates are equal to the destination tile’s x and y coordinates.
When the user presses a movement key (up, down, right, or left arrow), we first must check whether the player is trying to move to a “legal” tile on the playField. In Micro Tank Maze, all tiles are legal. The only illegal moves are off the edges of the board. So, if the player wants to move up, down, left, or right, we must first check the tile in that direction based on the key pressed in the gameStateWaitForPlayerMove() function. Here is the switch statement used to determine whether the player pressed an arrow key:
if (keyPressList[38]==true){
//up
if (checkBounds(-1,0, player)){
setPlayerDestination();
}
}else if (keyPressList[37]==true) {
//left
if (checkBounds(0,-1, player)){
setPlayerDestination();
}
}else if (keyPressList[39]==true) {
//right
if (checkBounds(0,1, player)){
setPlayerDestination();
}
}else if (keyPressList[40]==true){
//down
if (checkBounds(1,0, player)){
setPlayerDestination();
}
}
Notice that the checkBounds() function takes a row increment and then a column increment to test. It is important to note that we don’t access tiles in the same manner that we would access pixels on the screen. Tiles in the playField array are accessed by addressing the vertical (row) and then the horizontal (column) (using [row][column], not [column][row]). This is because a simple array is organized into a set of rows. Each row has a set of 15 columns. Therefore, we do not access a tile in the playField using the [horizontal][vertical] coordinates. Instead, we use the [row][column] syntax that simple arrays use to powerful and elegant effect.
In the checkBounds() function, enter the row increment, then the column increment, and then the object to be tested. If this is a legal move, the checkBounds() function sets the nextRow and nextCol to be row+rowInc and col+colInc, respectively:
function checkBounds(rowInc, colInc, object){
object.nextRow = object.row+rowInc;
object.nextCol = object.col+colInc;
if (object.nextCol >=0 && object.nextCol<15 &&
object.nextRow>=0 && object.nextRow<15){
object.dx = colInc;
object.dy = rowInc;
if (colInc==1){
object.rotation = 90;
}else if (colInc==-1){
object.rotation = 270;
}else if (rowInc==-1){
object.rotation = 0;
}else if (rowInc==1){
object.rotation = 180;
}
return(true);
}else{
object.nextRow = object.row;
object.nextCol = object.col;
return(false);
}
}
If the move is legal, the dx (delta, or change in x) and dy (delta, or change in y) are set to the colInc and