Controlling the game with a GameState class

As the code for this game is spread over many classes to keep each class manageable it raises the problem of what happens when one of these classes needs to know what is going on inside another of the classes. At least when we crammed everything into the main game engine class all the required variables were in scope!

Tip

The author's estimate is that if we continued with our usual pattern (where we cram everything into the game engine) for this project then the GameEngine class would have around 600 lines of code! By the end of this project, doing things a little differently, it will have barely 100 lines of code. Each code file/class will be much simpler. We will, however, need to spend more time understanding how all the different classes interact with each other- and we will. Now we will move on to the GameState class.

There are many ways of dealing with this common issue and the solution(s) you use will be dependent upon the specific project you are working on. I am going to introduce a few of the different ways you can deal with the issue in this project and the next.

The way that we will deal with the different classes being aware of the state (paused, game over, player lost a life, score increased, etc.) of the game is to create a class (GameState) that holds all that state and then share that class by passing it into the required methods of other classes.

Passing GameState from GameEngine to other classes

As we will see as we progress, the GameEngine class will instantiate an instance of GameState and be responsible for sharing a reference to it when it is required.

Now we know that the GameState class will be usable by GameEngine and any other class a reference is passed to but what about if the GameState class needs to trigger actions in the GameEngine class (and it will)?

Communicating from GameState to GameEngine

We will need the GameState class to be able to trigger the clearing(de-spawning) of all the game objects and then respawning them again at the start of every game. The GameEngine has access to all the game objects but GameState will have access to the information about when this must happen.

As we have already discussed, the GameEngine class can certainly take full advantage of much of the data in GameState by simply declaring an instance of GameState but the reverse isn't true- GameState cannot trigger events in GameEngine except when GameEngine specifically asks for state for example when it can use its GameState instance to ask questions about state and then act. For example, here is a snippet of code we will add soon to the GameEngine class.

…
if (!mGameState.getPaused()){
…

In the code snippet, mGameState is an instance of GameState and is using the instance to query whether the game is paused or not. The code uses a simple getter method provided by GameState similarly to how we have done in other projects already for various reasons. Nothing new to see there then.

As we have been discussing, however, we also need GameState to be able to trigger, whenever it wants to, the start of a new game. This implies that GameState could do with a reference to GameEngine but exactly how this will work requires some further discussion.

Here is what we will do. We will discuss the solution that allows GameState to directly trigger actions on GameEngine and then we will implement this solution along with the GameState class and another class, SoundEngine that will also be passed to multiple parts of the project to make playing sound possible wherever it is needed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.185.155