Game dev – Game states

I created three types of game states using Jonas Lundgrens GameStateManager. These are: PlayState, PauseState and CustomizeState. The PlayState holds the actual playable game, the pause state exists as a first state that is entered when pausing the game. The CustomizeState exists for the player to be able to customize stats using pickups collected in the game.

The GameObjectManager

I described how this manager works in my last post, but I will do so again. It stacks states on top of each other in a std::vector array and updates them from last to first. Later added states has the possibility to freeze logics of earlier added states. These states that freeze others are called exclusive states.

states_explained

PlayState

First up is the PlayState, this is where the game happens. Right now it handles the entire game using the different managers we have. It takes all managers as parameters in the constructor and saves them as members of the state.

PlayState

When first creating this state all parts of the game was written straight into it. Now we have broken up most of the code into managers. For example, at first we had the sf::RenderWindow and the viewport (sf::View) as members of the Engine. Now these exists within a DrawManager. This manager also holds all Buttons and Texts in the game. This could prove to be a problem because there should be a way of separating texts in the PlayStates and pause states. This needs to be discussed among our team, one solution is to create and have different GUIManagers for each state.

PauseState

This state is created when pressing the escape key on the keyboard when in the PlayState. The PauseState gets pushed into the GameStateManager vector. It is an exclusive state, so the update() function within PlayState doesn’t run anymore. The PauseState has buttons that are basically objects with box-colliders that can be interacted with using the mouse. When the mouse position is within the box of a button and the left mouse button is pressed, actions happen. This is checked with a type of collision, BoxVsPoint. It is handled in the CollisionManager and the code is very simple. When pressing some of these buttons, the “Customization” one for example, the PauseState will use the GameObjectManagers SwapStates() function and swap the PauseState with a new CustomizeState.

PauseState

CollisionBoxPoint

CustomizeState

This state is also exclusive, so the PlayState is still “frozen” when this is active. The CustomizeState handles customization using pickups in our game. I can write in length about how I made this state operational, but for the purpose of this blogpost I will not go into detail. This state contains the same buttons as the PauseState and additional buttons used for affecting our TextileManager (handles upgrades). When re-entering the PlayState, it is unfrozen and the avatar stats are updated using the TextileManager. All states that go from being frozen run a function called Revealed(), thanks to the GameStateManager, that is where the avatar stats are updated.

CustomizeState

PlayStateRevealed

Summary: Freezing and Unfreezing PlayState

As a summary to how the states work, when entering the PauseState (pressing the escape key) all states below it are frozen because the PauseState is exclusive. There is only one state below it in the vector array, the PlayState. From the Pause state there is the option to enter the CustomizeState, which is also an exclusive state. When pressing the “Resume” button in either one of the PauseState or CustomizeState, that state is pop:ed from the vector array. Pop:ing is used when removing the last element of an array. Follow the green arrow.

StateFlowchart