Reader small image

You're reading from  Android Game Programming by Example

Product typeBook
Published inJun 2015
Reading LevelIntermediate
Publisher
ISBN-139781785280122
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
John Horton
John Horton
author image
John Horton

John Horton is a programming and gaming enthusiast based in the UK. He has a passion for writing apps, games, books, and blog articles. He is the founder of Game Code School.
Read more about John Horton

Right arrow

Chapter 4. Tappy Defender – Going Home

We are on the home straight of our first game. In this chapter, we will draw a HUD to show the player in-game information, and implement the rules of the game so that the player can win, lose, and get fastest times.

After that, we will make a pause screen so the player can admire their achievements (or not) after they win or lose.

In this chapter, we will also generate our own sound FX and then add them to the game. Following that, we will enable the player to save their fastest time, and finally we will add a whole bunch of minor improvements, including a bit of difficulty balancing based on the screen resolution of the player's Android device.

Displaying a HUD


We need to start making our game a bit more rounded. Games have a score or, in our case, a time, and other rules as well. For the player to keep check on their progress we need to display the stats of the game.

Here, we will quickly set up a HUD that will show the player everything they need to know on screen while he is dodging enemies. We will also declare and initialize the variables required to supply data to the HUD. In the next section, Implementing the rules, we can begin to manipulate variables such as, shields, time, fastest time, and so on.

We can start by adding some member variables to the TDView class. We use a float value for the distanceRemaining variable because we will be using pseudo-kilometers and fractions of kilometers to represent the distance remaining until our hero makes it to her home planet. For the timeTaken, timeStarted, and fastestTime variables, we will use the long type because time is represented in milliseconds and the values get really big...

Implementing the rules


Now, we should pause and think about what we need to do later in the project because it will affect what we do while implementing our rules. When the player's ship is destroyed or when player reaches their goal, the game will end. This implies that the game will need to be restarted. We don't want to quit back to the home screen each time, so we need a way to restart the game from within the TDView class.

To facilitate this, we are going to implement a startGame method in our TDView class. The constructor will be able to call it and our game loop will also be able to call it when necessary as well.

It will also be necessary to pass some of the tasks that the constructor currently performs onto the new startGame method so that it can properly do its job. Also, we will use startGame to initialize some of the variables that our game rules and HUD require.

In order to accomplish what we discussed, startGame() will need a copy of the application's Context object. So, like...

Ending the game


If the game is not ended, the game is playing, and if the player has just died or won, the game is ended. We need to know when the game is ended and when it is playing. Let's make a new member variable gameEnded and declare it after the TDView class declaration:

private boolean gameEnded;

Now, we can initialize gameEnded in the startGame method. Enter this code as the very last line in the method.

gameEnded = false;

Now, we can finish the last few lines of our game rules logic, but wrap them in a test to see if the game has ended or not. Add the following code to conditionally update our game rules logic, right at the end of the TDView class's update method:

if(!gameEnded) {
            //subtract distance to home planet based on current speed
            distanceRemaining -= player.getSpeed();

            //How long has the player been flying
            timeTaken = System.currentTimeMillis() - timeStarted;
}

Our HUD will now have accurate data to keep the player informed of...

Adding sound FX


Adding sound effects in Android is really straightforward. First, let's look at where we can get our sound FX from. If you just want to get on with the coding, you can use my sound FX in the Chapter4/assets folder.

Generating the FX

We require four sound FX for our Tappy Defender game:

  • The sound for when our player crashes into an alien, which we will call bump.ogg.

  • The sound for when the player is destroyed, which we will call destroyed.ogg.

  • A fun sound for when the game first begins, which we will call start.ogg.

  • Finally, a victory whoop-type sound, which we will call win.ogg.

Here is a very quick guide to make these sound FX using BFXR. Grab a free copy of BFXR from www.bfxr.net.

Follow the simple instructions on the website to set it up. Try out a few of these things to make our cool sound FX.

Note

This is a very condensed tutorial. You can do so much with BFXR. To learn more read the tips on the website at the previous URL.

  1. Run bfxr.exe.

  2. Try out all the preset types, which generate...

Adding persistence


You may have noticed that the current fastest time is zero and can therefore never be beaten. The other problem is that every time the player quits the game the high score is lost. Now, we will load a default high score from a file. When a new high score is achieved, save it to the file. It doesn't matter if the player quits the game or even switches off their phone; their high score will remain.

First we need two new objects. Declare them as members of the TDView class after the TDView class declaration. The first is a SharedPreferences object and the second is an Editor object, which actually writes to the file for us:

private SharedPreferences prefs;
private SharedPreferences.Editor editor;

We use prefs first as we just want to attempt to load a high score if one exists. We will also initialize editor ready for when we save our high score. We do this in the TDView constructor:

// Get a reference to a file called HiScores. 
// If id doesn't exist one is created
prefs = context...

Iteration


How can we make our game better and more playable? Let's look at a number of possibilities and then go ahead and implement them.

Multiple different enemy graphics

Let's make the enemies a bit more interesting by adding a few more graphics to the game. First, we need to add the extra graphics to the project. Copy and paste enemy2.png and enemy3.png from the Chapter4/drawables folder of the download bundle into the drawables folder in Android Studio.

enemy2 and enemy3

Now, we just need to amend the EnemyShip constructor. This code generates a random number between 0 and 2, and then switches to load a different enemy bitmap accordingly. Our completed constructor now looks like this:

// Constructor
public EnemyShip(Context context, int screenX, int screenY){
    Random generator = new Random();
    int whichBitmap = generator.nextInt(3);
    switch (whichBitmap){
        case 0:
            bitmap = BitmapFactory.decodeResource
            (context.getResources(), R.drawable.enemy3);
 ...

The finished game


Finally, in case you are following along for the theory and not the practical, here is the finished GameActivity on a high resolution screen with a few hundred extra stars and shields:

Summary


We have implemented the component parts of a basic game engine. We can do so much more. Of course, a modern mobile game will have a lot more going on than in ours. How will we handle collisions when there are lots more game objects? Couldn't we tighten up our class hierarchy a bit, as there were lots of similarities between our PlayerShip and EnemyShip classes? How can we add complex internal character animations without confusing the structure of our code, and what if we want smart enemies, enemies who can actually think?

We need realistic backgrounds, side objectives, power-ups, and pick-ups. We want a game world with real-world coordinates that map back accurately regardless of the resolution of the screen.

We need a smarter game loop that runs the game at the same speed regardless of the CPU it is being processed on. Most of all, what we really need, more than any of these things, is a dirty big machine gun. Let's build a classic platform game.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Android Game Programming by Example
Published in: Jun 2015Publisher: ISBN-13: 9781785280122
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
John Horton

John Horton is a programming and gaming enthusiast based in the UK. He has a passion for writing apps, games, books, and blog articles. He is the founder of Game Code School.
Read more about John Horton