Creating the game manager

The game manager is an important part of most games. A game manager is a class that should contain data relating to gameplay; including, but not limited to keeping track of score, credits/currency, player health, and other general gameplay information. In this topic, we're going to take a look at a game manager class to gain an understanding of how they work into our game structure.

Getting ready

Please refer to the class named GameManager in the code bundle.

How to do it…

The game manager we're going to introduce will be following the singleton design pattern. This means that we will only create a single instance of the class throughout the entire application life cycle and we can access its methods across our entire project. Follow these steps:

  1. Create the game manager singleton:
    private static GameManager INSTANCE;
    
    // The constructor does not do anything for this singleton
    GameManager(){
    }
    
    public static GameManager getInstance(){
      if(INSTANCE == null){
        INSTANCE = new GameManager();
      }
      return INSTANCE;
    }
  2. Create the member variables with corresponding getters and setters which should keep track of gameplay data:
    // get the current score
    public int getCurrentScore(){
      return this.mCurrentScore;
    }
      
    // get the bird count
    public int getBirdCount(){
      return this.mBirdCount;
    }
      
    // increase the current score, most likely when an enemy is destroyed
    public void incrementScore(int pIncrementBy){
      mCurrentScore += pIncrementBy;
    }
      
    // Any time a bird is launched, we decrement our bird count
    public void decrementBirdCount(){
      mBirdCount -= 1;
    }
  3. Create a reset method that will revert all data back to their initial values:
    // Resetting the game simply means we must revert back to initial values.
    public void resetGame(){
      this.mCurrentScore = GameManager.INITIAL_SCORE;
      this.mBirdCount = GameManager.INITIAL_BIRD_COUNT;
      this.mEnemyCount = GameManager.INITIAL_ENEMY_COUNT;
    }

How it works…

Depending on the type of game being created, the game manager is bound to have different tasks. This recipe's GameManager class is meant to resemble that of a certain emotional bird franchise. We can see that the tasks involved in this particular GameManager class are limited, but as gameplay becomes more complex, the game manager will often grow as it has more info to keep track of.

In the first step for this recipe, we're setting up the GameManager class as a singleton. The singleton is a design pattern that is meant to ensure that there is only one static instance of this class that will be instantiated throughout the entire application's life cycle. Being static, this will allow us to make calls to the game manager's methods on a global level, meaning we can reach its methods from any class in our project without having to create a new GameManager class. In order to retrieve the GameManager class' instance, we can call GameManager.getInstance() in any of our project's classes. Doing so will assign a new GameManager class to INSTANCE, if the GameManager class has not yet been referenced. The INSTANCE object will then be returned, allowing us to make calls to the GameManager class' data-modifying methods, for example, GameManager.getInstance().getCurrentScore().

In step two, we create the getter and setter methods that will be used to modify and obtain the data being stored in the GameManager class. The GameManager class in this recipe contains three int values that are used to keep track of important gameplay data; mCurrentScore, mBirdCount, and mEnemyCount. Each of these variables have their own corresponding getters and setters that allow us to easily make modifications to the game data. During gameplay, if an enemy happened to be destroyed then we could call GameManager.getInstance().decrementEnemyCount() along with GameManager.getInstance().incrementScore(pValue), where pValue would likely be provided by the enemy object being destroyed.

The final step involved in setting up this game manager is to provide a reset method for game data. Since we are working with a singleton, whether we move from gameplay to the main menu, to the shop, or any other scene, our GameManager class' data will not automatically revert back to default values. This means that any time a level is reset, we must reset the game manager's data as well. In the GameManager class, we've set up a method called resetGame(), whose job is to simply revert data back to original values.

When starting a new level, we can call GameManager.getInstance().resetGame() in order to quickly revert all data back to the initial values. However, this is a general GameManager class and it is entirely up to the developer which data should be reset pending level reset or level loading. If the GameManager class is storing credit/currency data, it might be wise not to reset that particular variable back to default for use in a shop, for example.