Tetriarch, that's a good way to start. The mock-up you made can be managed with a system like the one I described, with each part of the screen being its own self-contained "Screen" (in the term I use to define class) with its own logic. It helps keep your game code from spilling all over the place.
Keep in mind these layers of screens can overlap each other too. If you open up a settings menu screen and click on "Exit Game" it can trigger an event to load a small pop-up screen appearing in the middle of everything, that will say "Are you sure you want to exit?"
I don't have access to my code right now, but when I can I will give a stripped down version of the class that I'm using that I use other types of screens like menus, backgrounds and pop-ups to inherit from. I see you're using C++, but I'm using C# / XNA. I took advantage of its runtime features of being able to get object types and assign events and delegate (which are a form of generalized callback functions) in order to save time to make the screen management system work. These things are still possible in C++ and you don't need to use all those features, they just need some workarounds.
Code: Select all
// Handles all the screen's updates
class ScreenManager
{
private:
std::list<GameScreen> screens;
public:
ScreenManager() {}
~ScreenManager() {}
void AddScreen(GameScreen screen)
{
screens.push_back(screen);
}
void RemoveScreen(GameScreen screen)
{
screens.remove(screen);
}
void Update()
{
// Iterate through all screens
// If screen.IsExiting == false, handle input
// update and draw the screen
}
// Base class for all your game screens
class GameScreen
{
private:
ScreenManager _screenManager;
public:
GameScreen(ScreenManager manager) : manager(_screenManager) {}
~GameScreen();
virtual void Load();
// Take input here. Screenmanager will not call this for disabled screens
virtual void handleInput(InputSystem input);
// Put your own logic in this method for the screen's derived class
// If all screens need common updates (like timers or debug stuff), use this base class
virtual void update(float timeStep);
virtual void draw(GraphicsSystem graphics);
}
This should be a good enough base to build a screen system on. I removed all the extra stuff like transitions, was originally gonna use them but they would add too much bloat to the example.
Some other things you might want to do is give screens the ability to become "disabled" or "sleep", meaning they won't take user input or updates (or maybe it will update but not take input), but still draw themselves. This is useful when you want to bring up an inventory screen and put your action screen out of focus, so your player doesn't move.