Game dev, Suit’em up – 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 and that makes the GameStateManager unfreeze the PlayState. Pop:ing is used when removing the last element of an array. Follow the green arrow.

StateFlowchart

This entry was posted in 5SD023, 5SD033 and tagged , , , . Bookmark the permalink.

1 Response to Game dev, Suit’em up – Game states

  1. fabbemannen says:

    It’s always a problem to get some length on the comments when the author seems to have done a proper job.

    The whole concept of exclusive states was an interesting read and seems to work theoretically. I’m not completely sure how useful it is as most of the times the states got four different statuses that I can think of:
    Active (updating and shown)
    Frozen (shown, but not updating)
    Inactive (not shown, not updating)
    Hidden (not shown, but updates)

    Having the ability to change the status of another state to whatever you’d like instead of just freezing all underlying states seems like a necessity to avoid too many states changing at once which requires a lot of checks to avoid issues when working on bigger projects, I assume.
    In a game like this, will it ever be useful to have all the underlying states frozen or is it better to just reload everything instead of just letting it sit in the background without doing anything while it is inactive/frozen?

    The only other thing I was thinking about was that the DrawManager handled buttons and text. Having it in there seems like a weird place for it, so I agree with you on having it somewhere else. A class that only handles GUI might be a way of doing it, but letting each state take care of their own GUI should probably work without creating too much of a clusterfuck in the code. This is mostly just preference with a project on this level, though.

    Good luck with the project, it seems to really be going on fine so far! I don’t really have anything that I think I got a better solution to, so you got that going for you ^^

Leave a comment