I made a state machine.
You can press 0 and 1 to switch between the hypothetical menu and playing state.
I hope you can help me improve it further.
StateManager.h
#pragma once
#ifndef StateManager_H
#define StateManager_H
#include <iostream>
#include "State.h"
/*
State classes
*/
class StateManager {
public:
// Define m_current_state upon the creation of this class (since that prevents there being a nullptr error in change_state
StateManager(State* state)
: m_current_state(state)
{}
void change_state(State* state) {
m_current_state->on_exit();
m_current_state = state;
m_current_state->on_enter();
}
void update_state(StateManager* manager) {
m_current_state->on_update(manager);
}
State* get_state() {
return m_current_state;
}
private:
State* m_current_state;
};
#endif
State.h
#pragma once
#ifndef State_H
#define State_H
#include "StateManager.h"
// I'm using forward declaration here since I've had a problem with circular dependency
class StateManager;
class State {
public:
// All states have to have these three functions
virtual void on_enter() = 0;
virtual void on_update(StateManager* state_manager) = 0;
virtual void on_exit() = 0;
};
#endif
IntroState.h
#pragma once
#ifndef IntroState_H
#define IntroState_H
#include "StateManager.h"
#include "State.h"
#include "GameState.h"
/*
Basic test state for demonstration
*/
class MenuState : public State {
public:
MenuState();
virtual void on_enter() override;
virtual void on_update(StateManager* state_manager) override;
virtual void on_exit() override;
private:
bool should_change_state;
};
#endif
Introstate.cpp
#include "IntroState.h"
MenuState::MenuState()
: should_change_state(false)
{}
void MenuState::on_enter(){
std::cout << "Entering the menu state" << std::endl;
}
void MenuState::on_update(StateManager* state_manager){
// update the menu
std::cout << "Should the state be changed to the playing state" << std::endl;
std::cin >> should_change_state;
if (should_change_state == true) {
state_manager->change_state(new PlayingState());
}
}
void MenuState::on_exit(){
std::cout << "Exiting the menu state" << std::endl;
}
GameState.h
#pragma once
#ifndef GameState_H
#define GameState_H
#include "IntroState.h"
#include "State.h"
/*
Basic test state for demonstration
*/
class PlayingState : public State {
public:
PlayingState();
virtual void on_enter() override;
virtual void on_update(StateManager* state_manager) override;
virtual void on_exit() override;
private:
bool should_change_state;
};
#endif
GameState.cpp
#include "GameState.h"
PlayingState::PlayingState()
: should_change_state(false)
{}
void PlayingState::on_enter() {
std::cout << "Entering the playing state" << std::endl;
}
void PlayingState::on_update(StateManager* state_manager) {
// update the menu
std::cout << "Should the state be changed to the menu state" << std::endl;
std::cin >> should_change_state;
if (should_change_state == true) {
state_manager->change_state(new MenuState());
}
}
void PlayingState::on_exit() {
std::cout << "Exiting the playing state" << std::endl;
}
Source.cpp
#include "StateManager.h"
#include "State.h"
#include "IntroState.h"
int main() {
StateManager* manager = new StateManager(new MenuState());
int exit = 0;
while (exit != 1) {
manager->update_state(manager);
}
return 0;
}
Thanks!