Book Image

Learning Java by Building Android Games - Third Edition

By : John Horton
5 (1)
Book Image

Learning Java by Building Android Games - Third Edition

5 (1)
By: John Horton

Overview of this book

Android is one of the most popular mobile operating systems today. It uses the most popular programming language, Java, as one of the primary languages for building apps of all types. Unlike most other Android books, this book doesn’t assume that you have any prior knowledge of Java programming, instead helps you get started with building Android games as a beginner. This new, improved, and updated third edition of Learning Java by Building Android Games helps you to build Android games from scratch. Once you've got to grips with the fundamentals, the difficulty level increases steadily as you explore key Java topics, such as variables, loops, methods, object-oriented programming (OOP), and design patterns while working with up-to-date code and supporting examples. At each stage, you'll be able to test your understanding by implementing the concepts that you’ve learned to develop a game. Toward the end, you’ll build games such as Sub Hunter, Retro Pong, Bullet Hell, Classic Snake, and Scrolling Shooter. By the end of this Java book, you'll not only have a solid understanding of Java and Android basics but will also have developed five cool games for the Android platform.
Table of Contents (24 chapters)

Linking up our methods

So far, we know that we can define methods with code like this:

void draw(){
     // Handle all the drawing here
}

And we can call/execute methods with code like this:

draw();

We have also referred to, as well as mentioned in our comments, that the onCreate method (provided automatically by Android) will handle the One-off Setup part of the flowchart.

The reason for this is that all Android games (and the vast majority of other Android apps) must have an Activity class as the starting point. Activity is what interacts with the operating system. Without one, the operating system cannot run our code. The way that the operating system interacts with and executes our code is through the methods of the Activity class. There are many methods in the Activity class, but the one we care about right now is the onCreate method.

The onCreate method is called by Android itself when the player taps our game's icon on their screen.

Important note

In fact, there are a number of methods that are called, but onCreate is enough to complete the Sub' Hunter game. As we write more complicated games, we will learn about and use more methods that the operating system can call.

All we need to know, for now, is how to put the One-off Setup code in onCreate, and we can be sure it will be executed before any of our other methods.

If you look at the flowchart, you will notice that we want to call newGame from the end of onCreate, and after that, we want to initially draw the screen, so we also call draw. Add this highlighted code, as follows:

/*
     Android runs this code just before
     the app is seen by the player.
     This makes it a good place to add
     the code that is needed for
     the one-time setup.
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     
     requestWindowFeature(Window.FEATURE_NO_TITLE);
     Log.d("Debugging", "In onCreate");
     newGame();
draw();
}

So that we can track the flow of the code and perhaps, if necessary, debug our game, the previous code not only calls the newGame method followed by the draw method, but it also contains the following line of code:

Log.d("Debugging", "In onCreate");

This code will print out a message in Android Studio to let us know that we are "Debugging" and that we are "In onCreate". Once we have connected the rest of the methods, we will view this output to see whether our methods work as we intended.

Now, let's print some text in the newGame method, so we can see it being called as well. Add the following highlighted code:

/*
     This code will execute when a new
     game needs to be started. It will
     happen when the app is first started
     and after the player wins a game.
 */
public void newGame(){
     Log.d("Debugging", "In newGame");
     
}

Following this, to implement the course of our flowchart, we need to call the takeShot method from the onTouchEvent method. Additionally, note that we are printing some text for tracking purposes here. Remember that the onTouchEvent method is called by Android when the player touches the screen. Add the highlighted code to the onTouchEvent method:

/*
     This part of the code will
     handle detecting that the player
     has tapped the screen
 */
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
      Log.d("Debugging", "In onTouchEvent");
      takeShot();
      
      return true;
}

Let's complete all the connections. Add a call to the draw method along with some debugging text into the takeShot method, as per the flowchart:

/*
     The code here will execute when
     the player taps the screen It will
     calculate the distance from the sub'
     and determine a hit or miss
 */
void takeShot(){
     Log.d("Debugging", "In takeShot");
     draw();
}

In the draw method, we will just print to Android Studio to show that it is being called. Remember that on the flowchart, after we complete the drawing, we wait for touches. As the onTouchEvent method handles this and receives a call directly from Android, there is no need to connect the draw method to the onTouchEvent method.

Important note

The connection between Android and the onTouchEvent method is permanent and never broken. We will explore how this is possible when we discuss threads in Chapter 9, The Game Engine, Threads, and the Game Loop.

Add the following highlighted code to the draw method:

/*
     Here we will do all the drawing.
     The grid lines, the HUD,
     the touch indicator and the
     "BOOM" when a sub' is hit
 */
void draw() {
     Log.d("Debugging", "In draw");
}

Note that we haven't added any code to the printDebuggingText or boom methods. Neither have we called these methods from any of the other methods. This is because we need to learn some more Java, and then do more coding before we can add any code to these methods.

When we run our game and the screen is clicked/tapped on, the onTouchEvent method, which is analogous to the Wait for Input phase, will call the takeShot method. This, in turn, will call the draw method. Later in this project, the takeShot method will make a decision to call either draw or boom depending upon whether the player taps on the grid square with the sub' in it or not.

We will also add a call to the printDebuggingText method once we have some data to debug.

Start the emulator if it isn't already running by following these same steps from Chapter 1, Java, Android, and Game Development:

  1. In the Android Studio menu bar, select Tools | AVD Manager.
  2. Click on the green play icon for the emulator.
  3. Now you can click on the play icon in the Android Studio quick launch bar, and, when prompted, choose whatever your emulator is called and the game will launch on the emulator.

Now open the Logcat window by clicking on the Logcat tab at the bottom of the screen, as shown in the following screenshot.

In the Logcat window, when we start the game, lots of text has been output to Logcat. The following screenshot shows a snapshot of the entire Logcat window to make sure you know exactly where to look:

Figure 2.7 – The Logcat window

Figure 2.7 – The Logcat window

The following screenshot zooms in on the three relevant lines, so you can clearly see the output even in a black and white printed book:

Figure 2.8 – Debugging output in the Logcat window

Figure 2.8 – Debugging output in the Logcat window

Moving forward, I will only show the most relevant part of the Logcat output, as text in a different font, like this:

Debugging: In onCreate
Debugging: In newGame
Debugging: In draw

Hopefully, the font and the context of the discussion will make it clear when we are discussing the Logcat output and when we are discussing Java code.

Here is what we can gather from all of this:

  1. When the game was started, the onCreate method was called (by Android).
  2. This was followed by the newGame method, which was executed and then returned to the onCreate method.
  3. This then executed the next line of code and called the draw method.

The game is now currently at the Wait for Input phase, just as it should be according to our flowchart:

Figure 2.9 – The game is at the Wait for Input phase

Figure 2.9 – The game is at the Wait for Input phase

Now, go ahead and click on the screen of the emulator. We should see that the onTouchEvent, takeShot, and draw methods are called, in that order. The Logcat output might not be exactly what you expect, however. Here is the Logcat output I received after clicking on the screen of the emulator just once:

Debugging: In onTouchEvent
Debugging: In takeShot
Debugging: In draw
Debugging: In onTouchEvent
Debugging: In takeShot
Debugging: In draw

As you can see from the output, exactly the correct methods were called. However, they were called twice.

What is happening is that the onTouchEvent method is very versatile, and it is detecting a touch when you click on the mouse button (or tap a finger), and it is also called when the mouse button (or a finger) is released. To simulate a tap, we only want to respond to releases (that is, a finger up).

To code this functionality, we need to learn some more Java. Specifically, we need to learn how to read and compare variables, then make decisions based on the result.

Variables are our game's data. We will cover everything we need to know about variables in the next chapter, and we will make decisions based on the value of those variables in Chapter 7, Making Decisions with Java If, Else, and Switch, when we put the finishing touches (pun intended) on the Sub' Hunter game.