C ++ Game State System

Good: I'm pretty new to C ++ and static languages ​​in general. Since the years of ruby ​​(and other dynamic languages), I do not know if this is possible.

I am creating a game state system for ... well a game. I want to make the system easy for me to cut and paste into other games without any (or very few) changes.

Two things I want to improve are the way to switch states and the way to hold state pointers.

Any number of states can exist, but at least 2–3 states will always be in memory.

Ugliness number 1.

I currently have a state manager class with something like this:

void StateManager::changeState(StateID nextStateID)
{
    // UNFOCUS THE CURRENT STATE //
    if (currentState())
    {
        currentState()->onUnFocus();

        // DESTROY THE STATE IF IT WANTS IT //
        if(currentState()->isDestroyedOnUnFocus()) {
            destroyCurrentState();
        }
    }

    if (m_GameStates[nextStateID]) {
        // SWITCH TO NEXT STATE //
        setCurrentState(nextStateID);
    }
    else
    {
        // CREATE NEW STATE //
        switch (nextStateID)
        {
        case MainMenuStateID:
            m_GameStates[MainMenuStateID] = new MainMenuState;
            break;
        case GameStateID:
                        m_GameStates[MainMenuStateID] = new GameStates;
            break;
        };
        setCurrentState(nextStateID);
    }

    // FOCUS NEXT STATE //
    currentState()->onFocus();
}

This approach works, but I don’t feel very pleasant.

Is it possible to pass a type? And then call it new?

new NextGameState;  // Whatever type that may be.

? a class State.

№ 2.

, , , , - , .

State* m_GameStates[MaxNumberOfStates];

NULL, , , .

, :

m_GameStates[m_CurrentState];

. , , , NULL, 2 3 . [ : ?]

vector_ptr, , , , . , , Ugliness No 1., .

.

, .

+5
6

, , .

, . , , , .

, , , :

template <typename T>
void Foo() {
  T* x = new T();
  ...
}

Foo<int>() // call Foo with the type T set to 'int'

, , .

, , , , (MainState) (MainMenu), . , , , ( , MainState / ?)

, , , .

map:

#include <map>

// I'm not sure what type m_CurrentState is, so use its type instead of KeyType below
std::map<KeyType, State*> m_GameStates;

// and to perform a lookup in the map:
GameStates[m_CurrentState];

, :

. new . , ( Foo* f = new Foo;, Foo f;

. , .

, new . -, , , new .

, .

RAII.

0

enum (eration) (- ). , , .

+2

, State pattern.

, State. , , , . .

, Pauseed and Unpaused, buttonPressed. , . "" , "". , .

+2
void StateManager::changeState(StateID nextStateID)
{
     leaveState(actualState); 
     enterState(nextStateID);
}

- .; -)

- , / changeState - , ?

: 2- - , - , 300. , - . , , , , - , "maxStates". , , X-, 2-3.

+2

To create states you want a factory. Thus, the state identifier remains good overall. To store states, I would go with std :: map

+1
source

Take a look at the Boost Statechart Library

0
source

All Articles