Thursday 3 May 2012

Game state transitions


I thought I'd tackle the top item on the Tetris to-do list; adding persistent hi scores. It's a little sad to have played a game and have no evidence of your achievements. It also encourages replay through a little competition. As I started implementing this feature I realised that the current code structure was getting a little unwieldy and could do with some refactoring first.

The current game path is controlled by the main method in Tetris.cpp. It is essentially a procedural style list of things to do in a list that loops forever:

e.g.

while(true){
   gameLoop();
   gameOver();
}

But then what happens when you want to add new states the to path? For example a landing page or name entry screen if you get a hi score. It would probably look something like this:

while(true){
   showLandingPage();
   gameLoop(); 
   gameOver();

   if(gotHiScore()){
      saveHiScore();
   }
}

This structure can get messy quite quickly if you want to add more states, especially ones are only moved to on a particular condition. To solve this I have introduced a Screen base class into Tetris with an implementation for each game state. The Screen then encapsulates the state transition logic within it.

 class Screen {  
   
   virtual void activate();  
   virtual Screen* getNextScreen();  
 }  

example Screen implementation:

 class PlayScreen : public Screen {  
   
   void activate(){  
    //code to play a game of tetris  
   }  
   
   Screen* getNextScreen(){  
    return new GameOverScreen();  
   }  
   
 }  

This reduces the main loop to:

Screen screen = new LandingScreen();

while(true){
   screen.activate();
   screen = screen.getNextScreen();
}

and it never needs to change, even when new screens are added. It also encapsulates all the code required for that state in a single class. 

Tetris screen state transitions

You can download version 2 of the Tetris Eclipse project here. This new version includes the state transitions and hi score saving/loading (as described here)

No comments:

Post a Comment