Questions about game states
- by MrPlow
I'm trying to make a framework for a game I've wanted to do for quite a while. The first thing that I decided to implement was a state system for game states. When my "original" idea of having a doubly linked list of game states failed I found This blog and liked the idea of a stack based game state manager.
However there were a few things I found weird:
Instead of RAII two class methods are used to initialize and destroy the state
Every game state class is a singleton(and singletons are bad aren't they?)
Every GameState object is static
So I took the idea and altered a few things and got this:
GameState.h
class GameState
{
private:
bool m_paused;
protected:
StateManager& m_manager;
public:
GameState(StateManager& manager) : m_manager(manager), m_paused(false){}
virtual ~GameState() {}
virtual void update() = 0;
virtual void draw() = 0;
virtual void handleEvents() = 0;
void pause() { m_paused = true; }
void resume() { m_paused = false; }
void changeState(std::unique_ptr<GameState> state)
{
m_manager.changeState(std::move(state));
}
};
StateManager.h
class GameState;
class StateManager
{
private:
std::vector< std::unique_ptr<GameState> > m_gameStates;
public:
StateManager();
void changeState(std::unique_ptr<GameState> state);
void StateManager::pushState(std::unique_ptr<GameState> state);
void popState();
void update();
void draw();
void handleEvents();
};
StateManager.cpp
StateManager::StateManager()
{}
void StateManager::changeState( std::unique_ptr<GameState> state )
{
if(!m_gameStates.empty())
{
m_gameStates.pop_back();
}
m_gameStates.push_back( std::move(state) );
}
void StateManager::pushState(std::unique_ptr<GameState> state)
{
if(!m_gameStates.empty())
{
m_gameStates.back()->pause();
}
m_gameStates.push_back( std::move(state) );
}
void StateManager::popState()
{
if(!m_gameStates.empty())
m_gameStates.pop_back();
}
void StateManager::update()
{
if(!m_gameStates.empty())
m_gameStates.back()->update();
}
void StateManager::draw()
{
if(!m_gameStates.empty())
m_gameStates.back()->draw();
}
void StateManager::handleEvents()
{
if(!m_gameStates.empty())
m_gameStates.back()->handleEvents();
}
And it's used like this:
main.cpp
StateManager states;
states.changeState( std::unique_ptr<GameState>(new GameStateIntro(states)) );
while(gamewindow::gameWindow.isOpen())
{
states.handleEvents();
states.update();
states.draw();
}
Constructors/Destructors are used to create/destroy states instead of specialized class methods, state objects are no longer static but