XNA Development - Basic Concepts: State Machines

Finite State Machines

One way of thinking about a video game is as a State machine. A state machine is a way of thinking about behavior based on a set number of states and transitions between states. In a classic video game we might have the following game states:

State Machine
  • Initialize
  • Attract Mode
  • Playing
  • Lost Life
  • Level Over
  • Game Over

When the machine is plugged in, it starts in the Initialize State.

After it loads everything into memory, it enters the Attract State playing a demo game, showing high scores, etc.

When someone drops in a quarter and presses the Player 1 button, it enters the Playing State.

In the Playing state, one of two things can happen: the player gets killed, or the player clears the level.

     If the player gets killed, the game enters the LostLife State.
          If the player has more lives, the game reenters the Playing State, if not it enters the GameOver State.

     When the player beats a level the game enters the LevelOver State.
          If there are more levels, it reenters the Playing State again. If not it enters the GameOver State.

Once the game is over the player can choose to replay, entering the Playing State or the game returns to the Attract State.

In our game, we can keep all these in an Enumeration. We'll then use a stack to keep track of the current state. Our update method will then use the game state to make decisions. For instance, if we're in the Attract state, we'll need to create the player motion since we're not responding to player input. It might look something like this:

public enum GameState
{
     Initialize,
     AttractMode,
     Playing,
     LostLife,
     LevelOver,
     GameOver
}

And in the main Game1.cs file...

GameState state;
protected override void Update(GameTime gameTime)
{
     switch (state)
     {
          case GameState.Initialize:
               // do loading stuff
               break;

          case GameState.AttractMode:
               // play demo
               break;

          case GameState.Playing:
               // respond to player input
               break;

          case GameState.LostLife:
               // maybe explode ship
               break;

          case GameState.LevelOver:
               // load new level
               break;

          case GameState.GameOver:
               // allow player to continue
               break;

     }
}

Things like the player colliding with an asteroid would then alter the game state. A full code sample of managing game states is available at creators.xna.com site here.

Using states are also useful for artificial intelligence in games. For instance in Pac-Man, what behaviors do the ghosts have?

  • Normally they travel the maze
  • If near Pac-Man, they chase him.
  • At seemingly random times, they reverse directions.
  • If Pac-Man eats a power pellet, they flee him.
  • If eaten, they return directly to the center 'cage'.

We could then use an enumeration to define the behavior like this:

public enum GhostBehavior
{
     Roaming,
     Chasing,
     Reversing,
     Fleeing,
     Dead
}

The Update method of a ghost would define different behaviors based on it's state. Different events (say, Pac-Man eating a power pellet) would change the state of the ghost.



<< Next >>