Game states

Started by
6 comments, last by adam23 17 years, 5 months ago
So, I'm writing a small space invaders clone and i'm wondering how to handle game states. Im thinking of using an enum like so: enum GameState { MAIN_MENU, GAME, PAUSE, etc....} Then in my main loop I would check the state and do the approriate drawing and keymapping. Of course this is all in theory. Is that a good way to go about it or is there a more common way to do it?
Advertisement
Using an enum is a very simple way of doing it. Using an OO approach you can do it more elegantly:
interface IState{    void UpdateState ();}class StateMachine{    void Update ();    void SetCurrentState (IState *state);    IState *current_state;}class MainMenu : IState{    void UpdateState ();}class Game : IState{    void UpdateState ();}

And then, in your main game loop:
void MainGameLoop{    StateMachine state_machine;    state_machine.SetCurrentState = new MainMenu;    while (!end_of_game)    {         state_machine.Update ();    }}

By not using enums for the state, you reduce the number of dependancies in the code, which is a good thing.

Skizz
Imagine the complexity of the code after you've added about a 10 screens... I'd say, no thanks. You may find a state machine system easier to maintain and work in. Basically, you create an abstract Screen class, with a Draw(), Input() and Update() function, anything that's necessary to let a screen do what it needs to do. Then, you derive each menu and gamescreen from this class. In your main loop, you use a pointer to a Screen object, on which you evoke these Draw(), etc. functions.
The trick here is, that you can swap to which object this pointer points, so you can control which object is currently active. The main loop stays simple, uncluttered, and the code for each screen is contained within it's own class.

EDIT: Got beaten to it. Oh well. Just make sure you delete what you new, in case you're not familiar with these operators yet. :)
Create-ivity - a game development blog Mouseover for more information.
Using game states is usually a good idea. I usually use a list or something to save them in though. If you start using switch statements it can get kind of hard to follow.

Here is what I do

//Abstract class State
class State
{
public:
State(int id);
virtual void Open()= 0;
virtual void Render() = 0;
virtual void Update(float elapsed) = 0;
virtual void Close() = 0;
int getId(return m_id);

private:
m_id;
};

Then I make states like this

class Game : public State
{

//bla bla bla
//overload pure virtual functions
};

class Menu :public State
{
//
//
};
Then create a list like this

const int GAME_STATE = 1;
const int MENU_STATE = 2;

std::list<State*> m_states;
//Add the states
list.push_back(new Game(GAME_STATE));
list.push_back(new Menu(MENU_STATE));

I usually create a class called StateManager that has functions that allows
you to add, remove, and change states.

Make sure you iterate through at the end and delete the states so you don't have a memory leak.

Note I typed this in here, so there is probably errors, I'm just giving you a general idea.

EDIT: I was beaten to it as well, you guys are really quick :)
Adamhttp://www.allgamedevelopment.com
Woah, quick response! Thanks for the help everyone. I'll try the state machine and see how it goes :)
How would sharing information between states be handled?
Referring to adam23's usage of std::list, I should say, it is much more convinient to use std::stack in the case of game states. You start with the "Main Menu" as your bottom-most item, push a "Game" state, then "Options" state on top of that... and when exiting out of each state just pop the top item of the stack until you reach back to the main menu, when you exit the main menu, the stack will be empty, which signals the termination of the program.
--------------------------------------Amaze your friends! Astound your family! Kennify your text!
What kind of information would you want to share?

One example I can think of is high scores, I had a tetris game that would display the score in a different state. What I did is save the value to a file when the game ended and then loaded it from my next state. Another option is to use a global structure or class that encapuslates all the shared information. Each state would have access to this class and change data accordingly. It could even be a singleton class so only one instance is created and so every state can access it easily.

In my RTS game that I'm working on I had trouble deciding how to share information between diferrent character states like Attack, Walk, Retreat, etc.

I finally decided that each state does not need to know about the others. The Character will hold the relevent information that can be accessed by each state. In fact I created a CharacterStateManager that each character has an instance of that holds a pointer to the character that owns it. That way through the manager the state can access any data it needs to such as position, fatique, health, and from that information it decides if it needs to change states.
Adamhttp://www.allgamedevelopment.com

This topic is closed to new replies.

Advertisement