Implementing the game level

The Flag Defense game is essentially an event-based game, which only needs a very simple game loop. This is because in this turn-based game, each action occurs sequentially and is based on events. So, our game loop essentially is very simple and involves only advancing of animation frames, moving characters, rendering the updated level, and switching few game states.

Consider the following code in the MainLevel class:

private function loop(e:EnterFrameEvent):void {
  Starling.juggler.advanceTime(e.passedTime);diceAnim.update(e.passedTime);
  worldLayer.render(e.passedTime, groundImage);
  if(gameState == GameStates.GREEN_MOVE && worldLayer.noneWalking()){
    clearPath();
    switchGameState(GameStates.BLUE_DICE);
  }else if(gameState == GameStates.BLUE_MOVE && worldLayer.noneWalking(true)){
    clearPath();
    switchGameState(GameStates.GREEN_DICE);
  }
}

The worldLayer.render method calls the update method of all soldiers, moves them if their walking property is true, and then draws the game world.

The game states

The following are the different game states that we have used in the game and their functionalities:

  • GREEN_DICE: This indicates that the dice is thrown by the green player, tap to stop dice rolling
  • GREEN_PATH: This indicates the path drawing done by the green player by touching and dragging
  • GREEN_PATHCOMPLETE: This indicates the path completed by the green player, that is, the path now has the same number of moves as the dice value
  • GREEN_MOVE: This indicates the automatic movement for the green player on the drawn path
  • BLUE_DICE: This indicates an automatic dice throw for the blue player
  • BLUE_DICESTOP: This indicates an automatic dice stop for the blue player
  • BLUE_PATH: This indicates automatic pathfinding, path drawing for the blue player
  • BLUE_MOVE: This indicates the automatic movement of the blue player on the found path

All game states starting with BLUE constitute the AI for this game. The GREEN_MOVE game state can also be considered as an AI as the soldier needs to follow the path automatically.

The touch listener

The MainLevel class listens to the touch events and makes sure that it responds accordingly based on the current game state. Double-tapping anywhere on the screen will toggle the UI on and off. For the game states GREEN_PATH and GREEN_PATHCOMPLETE, we track touches for drawing the path by a user. If we touch a green soldier, we start the path drawing and as we move the touch, the path array for that soldier is updated if the new tile is directly walkable from the previous touched tile. Path drawing stops when we touch a nonwalkable tile, when we release our touch, or when the path length becomes higher than the dice value. Arrows are drawn on the ground layer while the path is updated. It also makes sure that the game state switches to GREEN_PATHCOMPLETE when we have enough path points.

Following the AI path

In the game, we will need the soldiers to follow the path we draw for them as well as the enemy soldiers to find their own path. Let us first see how path following is done.

The soldier class (CustomIsometricCharacter) is already wired to move in the direction specified by its facing property if its walking property is true. For following a path, we set the walking property to true, find the next destination from its path array, find the new facing value by comparing the current position and destination. The path array of a soldier will have tile coordinates in a sequential order. So, once the soldier reaches the current destination, we will update the destination to the next point from the path array and the process is repeated till there are no more points in the array. Then the walking property is turned off as we have followed our path to reach the final destination.

The important methods implementing the preceding functionality in the soldier class are markDestination(), findDirection(), and move(delta:Number).

Path finding

For the green soldiers, path finding is direct as the player himself does it by drawing the path. The code just makes sure that the newly marked tile is walkable and is either vertically or horizontally next to the previous valid position saved in the path array. In our engine, we don't allow the soldiers to walk diagonally between the tiles.

For the blue soldiers, we need to find the path using a path finding algorithm. There are many standard algorithms for the same which can be applied to a 2D array to find a shortest path. Two of the major candidates are Dijkstra's algorithm and A * algorithm. There are far too many standard implementations of these algorithms in AS3 that you are not advised to reinvent the wheel, but use one which suits the purpose. Essentially, most of all the implementations will need a collision array with 0 value for a walkable tile and 1 for an obstacle. We create the same in the createLevel method of the MainLevel class, shown as follows:

for(var i:int=0; i<groundLayer.rows; i++){
  worldLayer.collisionArray[i] = new Array();
  for(var j:int=0; j<groundLayer.cols; j++){
    if(worldLayer.overlayArray[i][j] != "*" || groundLayer.groundArray[i][j] == "tile4.png")
    {
      worldLayer.collisionArray[i].push(1);
    }else{
      worldLayer.collisionArray[i].push(0);
    }
  }
}

The array has a value, 1 when there is an overlay item in that tile position or if the ground has tile4.png which is the base for our castles. The ground tile is considered as the castle tile occupies multiple tiles, but can be an overlay value in only one of those tile positions.

We are using the Pathfinder class by Joe Hocking, which is an A * implementation found at http://www.newarteest.com/flash/astar.html with some slight modification to remove the diagonal path finding.

We can call the Pathfinder class to return an array of points in sequential order from a starting point to an end point by using the following code:

path=PathFinder.go(startPoint.x,startPoint.y,endPoint.x,endPoint.y,collisionArray);

For the blue soldiers, we calculate the path from their paintPoint position to the green flag position, and splice the resulting array to only include as many points as decided by the dice throw. Once the path is found, the path following part is the same for all the soldiers as explained before.

Making AI decision

Simulating AI-based decision making requires a bit of extra effort. We need to purposefully introduce delays in each step for making it realistic and to introduce a human element. Most of the AI decisions can be made instantly which does break the illusion of the human player that we are trying to convey. In our game, each AI decisions are made via methods which are called with a delay using the juggler class as follows:

Starling.juggler.delayCall(switchGameState,2,[GameStates.BLUE_DICESTOP]);
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.111.197