In this part of the tutorial we’ll be looking at the GameView class, which is maintaining the View of the Game, UI and handling messages from the Thread (e.g. score changes).
Create a new class through the Eclipse add class functionality (Right click the project -> add -> class)
You should create a Class with the name GameView that has the superclass android.view.SurfaceView and make it implement SurfaceHolder.Callback (This might create some errors, but we will implement the missing methods later):
public class GameView extends SurfaceView implements SurfaceHolder.Callback
We extend SurfaceView because that is the view that provides a drawable surface, and by implementing SurfaceHolder.Callback the Android system can call our class whenever there are changes to the screen. We need the following attributes:
The views comes from the layout, and gives us a way to show text on the screen on top of the actual game. The Handler is the class that will recieve messages from the GameThread, and the sensorAccelerometer is an EventHandler that will handle calls from the Accelerometer. Lets create the constructor:
All this does is setting up the holder and add the object as a SurfaceView.Holder callback. The rest of the code creates an anonymous class that handle the messages from the GameThread. It can receive scores and otherwise just display the sent text in the mStatusView. You might remember that the onDestroy() method of the GameActivity would call a cleanup() method of GameView, which should look like this:
This cleans up all possible resources of the Class. The method actually has a small risk of a NullException, albeit very small, as the thread is call without a check to see if it has been set up. Should probably be changed 😉
The next methods are the getters and setters. There is only one of them with any real interest:
We start out setting the GameThread, and after that we set up the onTouchListener and SensorEventListener and all we do is to relay the events to the GameThread. The rest of the getters and setters look like this:
Next we’ll manage the screen changes. First we’ll automatically pause the game if the window goes out of focus for what ever reason:
Next we’ll implement the changes of the surface. Let’s start with the creation of the surface:
The thread.setRunning(true); method call is one we’ll implement, which set the game circle of the thread to running. Next we check to see if the GameThread is new, and therefore hasn’t run before, or if the GameThread has run before but the user has returned to the game. If it is a new game a simple start of the thread is necessary, however if the player returns to the game from somewhere else it isn’t that simple. Stopping and restarting of threads within Android is deprecated, so the developer has to maintain this manually. The easiest way to do this is to take the old terminated thread, and send it to a new GameThread and copy all of the attributes of the old thread into the new, thus starting the new Thread within the same state as the old thread. This should ensure that the user experience is correct, and the game restarts where the user stopped.
The other two surface related methods are:
The surfaceChanged() simply sends the new width and height to the thread. This should happen once and only once for each surface (we don’t allow screen “flipping” here). The surfaceDestroyed() method stops the GameThread by letting it run out of the game loop within the GameThread.
The last thing we need is the two sensor methods we called earlier:
The start sensor sets up the accelerometer. You can use this approach to set up many different sensors, you can go here to see the different possibilities.
Please download GameView.java, if you need it.