-
-
Notifications
You must be signed in to change notification settings - Fork 0
Silva StateMachine
Mattis DALLEAU edited this page Jun 8, 2022
·
1 revision
A state machine is a class that is used to manage the state of the game.
It is generally used to avoid big conditional branchings
class MyState : public State {
public:
MyState()
{
std::cout << "Hello World!" << std::endl;
}
~MyState()
{
std::cout << "Goodbye World!" << std::endl;
}
void update() override {
std::cout << "Update" << std::endl;
}
};
int main()
{
StateMachine stateMachine;
stateMachine.changeState<MyState>();
stateMachine.update();
stateMachine.update();
}
Expected output:
Init
Update
Update
Goodbye World
When to use a stacked state?
Imagine your are in game and you want to pause it.
You don't want to destroy the current state.
So you create a new state and push it to the stack.
Here is the example:
class GameState : public State {
void update() override {
std::cout << "Playing" << std::endl;
if (KeyboardPressed(KEY_ESCAPE)) {
stateMachine.pushState<PauseState>();
}
player.update();
}
};
class PauseState : public State {
void update() override {
std::cout << "Paused" << std::endl;
if (KeyboardPressed(KEY_ESCAPE)) {
stateMachine.popState();
}
buttons.update();
}
};
This example should make use alternatively the GameState and PauseState classes.
class RunBehaviour : public State {
private:
Player& player;
public:
RunBehaviour(Player& animable) : player(player)
{
}
void update() override {
// Specific update code
if (player.notMoving()) {
player.changeState<IdleBehaviour>(player);
return;
}
}
};
class IdleBehaviour : public State {
private:
Player& player;
public:
IdleBehaviour(Player& player) : player(player)
{
}
void update() override {
// Specific update code
if (player.isMoving()) {
player.changeState<RunBehaviour>(player);
return;
}
}
};
class ActionBehaviour : public State {
private:
Player& player;
public:
ActionBehaviour(Player& player) : player(player)
{
}
void update() override {
// Specific update code
if (player.finishedAction()) {
player.changeState<IdleBehaviour>(player);
return;
}
}
};
class Player {
private:
Animable animable;
StateMachine stateMachine;
Vector2 velocity;
public:
Player() { stateMachine.changeState<IdleBehaviour>(player); }
void update() { stateMachine.update(); }
bool isMoving() const { return velocity.x != 0 || velocity.y != 0; }
bool notMoving() const { return !isMoving(); }
template<typename T>
void changeState(Player& player) { stateMachine.changeState<T>(player); }
};