StateManager

Discussion

The StateManager's design has been finalized, and the classes have been created. You can see it in use inside the current code.

Discussions about this design have taken place at its forum topic.

Introduction

The StateManager is a Finite State Machine. In essence the StateManager manages between different states within the game. One of the uses of the StateManager could be to have different game states, like:

  • Splash Screen
  • Login Menu
  • Register Menu
  • The Game

Classes

StateManager

/**
 * \class StateManager
 * \brief Manager for different states within the game.
 *
 * This class acts as the manager for the different states that may occur in the game.
 */
class StateManager
{
private:
    // Members
    Logger*     mLogger;
    Filesystem* mFilesystem;
    Renderer*   mRenderer;
    State*        mActiveState;

public:
    // Constructor & destructor
    StateManager(Logger* loggerClass, Filesystem* filesystemClass, Renderer* rendererClass);
    ~StateManager();

    // State method
    void switchToState(State* state);    

    // Update method
    bool updateState();
};

State

/**
 * \class State
 * \brief The base class for every state.
 *
 * This class is the prototype for all the states in the game. States should inherit
 * from this class. Subclasses implement initialize() and finalize() for creating
 * and cleaning up resources, and the updateState() method gets called every frame
 * by the StateManager. 
 */
class State
{
protected:
    // Members
    Logger*        mLogger;
    Filesystem*    mFilesystem;
    Renderer*   mRenderer;

public:
    // Initialization & finalization methods
    void initializeUtilities(Logger* loggerClass, Filesystem* filesystemClass, Renderer* rendererClass);
    virtual void initialize() = 0;
    virtual void finalize() = 0;

    // Update state method
    virtual State* updateState() = 0;
};

Creating states

You create a state by creating a subclass of the 'State' class. An example of a state is the 'SplashScreenState'. This state simply loads an image, and displays it for a certain amount of time.

The class definition for the SplashScreenState looks like this:

/**
 * \class SplashScreenState
 * \brief The splash screen state.
 *
 * This state is used at the beginning of the game as a splash screen.
 */
class SplashScreenState: public State
{
public:
    // Initialize & finalize methods
    void initialize();
    void finalize();

    // Update state method
    State* updateState();    

private:
    // Members
    ImageResourceManager*        mImageResourceManager;
    Image*                  mSplashImage;
    int                      mCounter;
};

The initialize() & finalize() methods allocate and deallocate the resources, in this case the splash image contained in mSplashImage.

The interesting part is the updateState() method, which gets called every frame. The comments explain its working:

/**
 * Render one frame
 */
State* SplashScreenState::updateState()
{
    mCounter++;

    // Render the splash screen    
    if (mSplashImage != NULL)
    {
        mRenderer->drawImage(mSplashImage, 0, 0);
    }

    // Next scene?
    if (mCounter == 500) {
            // Create a new scene to determin the next scene
        return new TestState();
    }

    // To stay at the current scene, we return 'this'.
    return this;    
}

Whatever you return from your updateState() method will be the next State. If you return 'this' the State will remain the same, if you return 'null' the StateManager will exit of its loop, if you return a new State the StateManager will switch to that.

Usage

Setting up the StateManager

// Create the StateManager
  mStateManager = new StateManager(mLogger, mFilesystem, mRenderer);

  // Set the first scene
  mStateManager->switchToState(new SplashScreenState);

Updating the current State

// Update the state
  if (!mStateManager->updateState()) {
    // No next state, so break!
    break;
  }
page_revision: 19, last_edited: 1227876088|%e %b %Y, %H:%M %Z (%O ago)
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial 3.0 License