- slide 1 of 3
The first thing we need to do in order to implement a main menu is to enable all the current game objects that are running to be removed all at once. This may seem backwards, but it makes sense when you consider that the main menu will be displayed before the game is played and also when it has ended. Obviously we don’t want to have the player running around on the main menu after the game has finished.
The GameObjectManager class gains a few new functions to facilitate this ability to remove all current game objects: shutdownAll, removeOldGameObjects and addNewGameObjects.
The shutdownAll function is quite simple. It loops through the current collection of GameObjects and calls their shutdown function. This cleans up their resources and removed them from the game. [code]
Finally, a small change needs to be made to the draw function to call the removeOldGameObjects and addNewGameObjects functions, ensuring that the gameObjects collection is kept in sync. [code]
The ApplicationManager is then modified to include two new functions: startLevel and openMainMenu.
The startLevel function initializes the objects needs to create the game. This code was originally in the startupApplicationManager function. [code]
The openMainMenu function creates a new instance of the new MainMenu class. Both the startLevel and openMainMenu functions call the GameObjectManager shutdownAll function to ensure the application has a clean slate before creating their respective objects. [code]
- slide 2 of 3
- slide 3 of 3
The MainMenu class is a very simple class that displays an image on the screen, and calls the ApplicationManager startLevel function when a key has been pressed.
The last additional class is the LevelEndPost. This class is very similar to the Powerup class, except that it calls the ApplicationManager openMainMenu function when the player touches it, effectively ending the current level. [code]
One thing that is worth mentioning here is that each class that extends the GameObject class has two functions to enable them to be cleaned up: shutdown and shutdownClassName. This is because you can not override a parent function, and then still call that parent function.
That was a bit of a mouthful, but the following diagram should make it easier to understand. Take the classes VisualGameObject, AnimatedGameObject and Powerup. See how a call to the shutdown function in each class flows through to the base classes.
shutdown -> shutdownVisualGameObject -> shutdownGameObject
shutdown -> shutdownAnimatedGameObject -> shutdownVisualGameObject -> shutdownGameObject
shutdown -> shutdownPowerup -> shutdownAnimatedGameObject -> shutdownVisualGameObject -> shutdownGameObject
By adding the shutdownAll function to the GameObjectManager, and implementing a system whereby the shutdown function on all classes that extend the GameObject will recursively shutdown parent classes, we have a very easy way to clean up any game objects and swap back and forth between a main menu screen. In future articles we will use this ability to load new levels, and implement high score screens.