Be sure not to discuss your hero’s state of mind. Make it clear from his actions.
– Anton Chekhov
A typical game has two major interface components: a menu system and a heads-up display (HUD).
The menu system defines how the player gets in and out of the game, including selecting options, viewing the credits or
high scores, and so on. Some games, like RPGs, also have in-game menus to manage inventories or to show character
sheets.
The HUD simply shows additional information to the player, for example a compass or his current score.
In this first series of tutorials, we will talk about menus only.
Scenes
To implement menus, we will use a so-called Scene Manager, that is, we will consider our game to be a collection of
different scenes, or states. The intro sequence, for example, would be the first scene to show, followed by the main
menu and from there on the user can branch off into an options menu, view the credits or start the actual game.
Our main goal is to create a scene manager with no limit to the number of elements and distinct elements it can show,
and to provide an easy way to add new scenes. One way to ensure a working scene flow (allowing the user to go back and
forth between scenes) is to use a stack of scene.
The top scene on the stack will be the currently active scene, and going to a new scene means simply pushing that scene
on the stack, while going back means popping the top scene off the stack. Another thing to consider is that sometimes
multiple scenes must be visible, for example when we ask the user whether he really wants to save the changes he made to
the key bindings. In that case, we must always draw the scenes on the stack from the bottom to the top. One
particularity to keep in mind is that once the game starts, we will probably have to clear the entire stack and only
push the game scene on top, which makes the scene stack into a non-standard stack.
Game Scenes
A scene is thus almost like a separate program within our game. Each game scene or state must be able to handle its own
initialization, such as the desired graphical components, it must handle its own events, update the game world and draw
the next frame to the screen.
We will define a purely virtual base class for game states like this:
Note that this class is designed to be a singleton, which ensures that each game state class has only one single
instance, and also provides a global point of access to each state. Also notice that the game states observe the input
handler and get active whenever the user presses a key that is mapped to a game event.
The actual stack of game scenes will be hold by the main application class in a deque:
Now, there is one thing that we still have to consider: How does the main application class know when to change from one
state to another? Well, it does not. Only the currently active state knows when it is time to change to another state.
We thus have to add another function to the GameState class:
And that’s it already. To illustrate how the new system works, I created a few game states, an intro state, a main menu,
the actual game state and a game menu. To navigate through the states, use the Enter and Escape key.