Chapter 2: Java – First Contact
In this chapter, we will make significant progress with the Sub' Hunter game even though this is our first lesson on Java. We will explore, in detail, exactly how Sub' Hunter will be played and the steps/flow that our completed code will need to take to implement the game.
We will also learn about how Java uses code comments to document the code, take a brief initial glimpse at methods to structure our code, and an even briefer first glimpse at Object-Oriented Programming (OOP), which will begin to reveal the power of Java and the Android API.
The autogenerated code that we referred to in Chapter 1, Java, Android, and Game Development, will also be explained as we proceed and add more code. In this chapter, we will cover the following topics:
- Planning the Sub' Hunter game
- Introducing Java methods
- Structuring Sub' Hunter with methods
- Introducing OOP
- Using Java packages
- Linking up the Sub' Hunter methods
First, let's do some planning.
Planning the Sub' Hunter game
The objective of this game is to find and destroy the enemy sub' in as few moves as possible. The player takes a shot and each time guesses the location of the sub' by taking into account the distance feedback (or sonar ping) from all of the previous shots.
The game starts with the player facing an empty grid with a randomly placed (hidden) submarine lurking somewhere within it:

Figure 2.1 – The Sub' Hunter game screen
The grid represents the sea, and each place on the grid is a possible hiding place for the submarine that the player is hunting. The player takes shots at the sub' by guessing where it might be hiding and tapping one of the squares on the grid. In the following screenshot, the tapped square is highlighted, and the distance to the sub' from the tapped square is shown as a number at the top of the screen:

Figure 2.2 – Taking shots in the Sub' Hunter game
This feedback means the sub' is hiding somewhere on (not within) the radius of 15 squares, as demonstrated in the previous screenshot.
Important note
Note that the dashed circle in the previous screenshot is not part of the game. It is my attempt to explain the possible hiding places of the sub' based on the distance.
As a player takes more shots, they can build up a better mental picture of the likely location of the sub' until, eventually, they guess the exact square and the game is won:

Figure 2.3 – Taking a shot to start the game again
Once the player has destroyed the sub', the next tap on the screen will spawn a new sub' in a random location and the game starts again.
In addition to the game itself, we will be writing code to display debugging information so that we can test the game and check whether everything is working as it should be. The following screenshot shows the game running with the debugging information enabled:

Figure 2.4 – The debugging information of the game
Let's look more closely at the player's actions and how the game will need to respond to them.
The actions flowchart/diagram
We need to plan our code before we start hammering away at the keyboard. You might be wondering how you can plan your code before you have learned how to code, but it is quite straightforward. Study the following flowchart; we will discuss it and then introduce a new Java concept to help us put the plan into action. Follow the path of the arrows and note the diamond shape on the flowchart where our code will make a decision, and the execution of the code could go either way:

Figure 2.5 – Planning the game using a flowchart
The flowchart shows the steps the game will take, as follows:
- The game is launched by tapping on its icon in the app drawer (or running it in Android Studio).
- The sub' is placed in a random location by generating random horizontal and vertical numbers. The score is set to zero if this is not the first play of the game.
- Next, everything is drawn to the screen: the grid-lines and the text (heads-up display or HUD), including the debugging text (if enabled).
- At this point, the game does nothing. It is waiting for the player to tap on the screen.
- When the player taps on the screen, the pixel that has been tapped is converted into a location on the grid, and that location is compared to the location of the sub'. The Hit? diamond illustrates this comparison. Here, the program could branch back to the drawing phase to redraw everything, including the grid location.
- Alternatively, if there was a hit, then the BOOM! screen is shown.
- In fact, the BOOM! part isn't exactly as we see it there. The Wait for Input phase also handles waiting for a screen tap at this point. When the screen is tapped again, it is considered the first shot of the next game; the flow of the code moves back to the Spawn Sub Reset Score code, and the whole process starts again. This will become clearer as the project progresses.
The next two sections of this chapter will show you how to flesh out this design with real Java code. Then, in the next chapter, we will be able to view real results on the screen.
Code comments
As you become more advanced in writing Java programs, the solutions you use to create your programs will become longer and more complicated. Furthermore, as you will see in this chapter and following on throughout the book, Java was designed to manage complexity by having us divide our code into separate chunks and, very often, across multiple files.
Comments are a part of the Java program that does not have any function in the program itself. The compiler ignores them. They serve to help the programmer to document, explain, and clarify their code to make it more understandable to themselves later (maybe even a long time later) or to other programmers who might need to refer to or modify the code. So, a good piece of code will be liberally sprinkled with lines like this:
// This is a comment explaining what is going on
The preceding comment begins with the two forward slash characters, //
. The comment ends at the end of the line. This is known as a single-line comment. So, anything on that line is for humans only, while anything on the next line (unless it's another comment) needs to be syntactically correct Java code:
// I can write anything I like here but this line will cause an error unless it is valid code
We can also use multiple single-line comments:
// Below is an important note // I am an important note // We can have many single line comments
Single-line comments are also useful if we want to temporarily disable a line of code. We can put //
in front of the code and it will not be included in the program. This next code is valid code, which causes Android to draw our game on the screen. We will see it in many of the projects in this book:
// setContentView(gameView);
In the preceding scenario, the code will not run, as the compiler considers it to be a comment and the screen will be blank. There is another type of comment in Java – the multiline comment. This is useful for longer comments and to add things such as copyright information at the top of a code file. Additionally, like the single-line comment, it can be used to temporarily disable code – in this case, it is usually multiple lines.
Everything in between the leading /*
signs and the ending */
signs is ignored by the compiler. Here are some examples:
/* A Java expert wrote this program. You can tell I am good at this because the code has so many helpful comments in it. */
There is no limit to the number of lines in a multiline comment. Which type of comment is best to use will depend upon the situation. In this book, I will always explain every line of code explicitly, but you will also find liberally sprinkled comments within the code itself that add further explanation, insight, or clarification. So, it's always a good idea to read all of the code:
/* The winning lottery numbers for next Saturday are 9,7,12,34,29,22 But you still want to learn Java? Right? */
Tip
All the best Java programmers liberally sprinkle their code with comments.
Let's add some useful comments to the Sub' Hunter project.
Mapping out our code using comments
Now, we will add some single-line and multiline comments to our code, so we know where we will be adding code throughout the project and what its intended purpose is.
In Chapter 1, Java, Android, and Game Development, we left the code with just a couple of lines to the AndroidManifest.xml
file in order to lock the player's screen to landscape and use the full screen.
Open Android Studio and click on the SubHunter.java tab in the Editor window. You can now see the code in the class file.
Referring to our flowchart, we have the One-off Setup element. In Android, the operating system dictates where some parts of our program must take place. For this reason, add the highlighted multiline comment, as shown next, among the existing code. We will explore why this part of the code is where we do the One-off Setup element later, in the Linking up our methods section.
Important note
The complete code for this chapter can be found on the GitHub repo in the Chapter 2
folder.
Now, add the highlighted code shown here:
package com.gamecodeschool.c2subhunter; import android.app.Activity; import android.os.Bundle; public class SubHunter extends Activity { /* Android runs this code just before the player sees the app. This makes it a good place to add the code for the one-time setup phase. */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
Next, immediately before the final curly brace, }
, of the code, add the following highlighted comments. I have highlighted some of the existing code before the new comments to make it clear where exactly to add the new comments:
… @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } /* 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. */ /* Here we will do all the drawing. The grid lines, the HUD and the touch indicator */ /* This part of the code will handle detecting that the player has tapped the screen */ /* The code here will execute when the player taps the screen. It will calculate the distance from the sub' and decide a hit or miss */ // This code says "BOOM!" // This code prints the debugging text }
The preceding comments serve a few purposes. First, we can see that each aspect of our flowchart plan has a place where its code will go. Second, the comments will be a useful reminder of what the code that follows does, and, finally, when we get around to adding the code for each section, I will be able to demonstrate where you need to type in the new code because it will be in the same context with these comments.
Tip
Ensure you have read the comments and studied the flowchart before moving ahead.
We will also add more comments to explain specific lines of code within each of the sections.
I keep mentioning sections. Java has a word for that: methods.
Introducing Java methods
Java methods are a way of organizing and compartmentalizing our code. They are quite a complex topic, and a full understanding of them requires knowledge of other Java topics. By the end of the book, you will be a method ninja. However, for now, a basic introduction will be useful.
Methods have names to identify them from other methods and to help the programmer identify what they do. The methods in the Sub' Hunter game will have names such as draw
, takeShot
, newGame
, and printDebuggingText
.
Note that code with a specific purpose can be wrapped inside a method; for example, take a look at the following snippet:
void draw(){ // Handle all the drawing here }
The preceding method, named draw
, could hold all the lines of code that draw our game. When we set out a method with its code, it is called the method definition. The curious-looking prefixed void
keyword and the postfixes, ()
, will be explained in Chapter 4, Structuring Code with Java Methods. However, for now, you just need to know that all of the code inside the draw
method will be executed when another part of the code wants it to be executed.
When we want to initiate a method from another part of the code, we say that we call the method. And we would call the draw
method with the following code:
draw();
Take note of the following, especially the last point, which is very important:
- Methods can call other methods.
- We can call methods as many times as we want.
- The order in which the method definitions appear in the code file doesn't matter. If the definition exists, it can be called from the code in that file.
- When the called method has completed its execution, the program execution returns to the line after the method call.
So, in our example program, the flow would look like this:
… // Going to go to the draw method now draw(); // All the code in the draw method is executed // Back from the draw method // Any more code here executes next …
Important note
In Chapter 8, Object-Oriented Programming, we will also explore how we can call methods to one file from another file.
By coding the logic of the Sub' Hunter game into methods and calling the appropriate methods from other appropriate methods, we can implement the flow of actions indicated in the flowchart.
Overriding methods
There is one more thing that you need to know about methods before you do some more coding. All the methods I mentioned earlier (for example, draw
, takeShot
, newGame
, and printDebuggingText
) are methods that we will be coding. They are our very own methods, and they are for our use only.
Some methods, however, are provided by the Android API and are there for our (and all Android programmers) convenience – we can either ignore them or adapt them. If we decide to adapt them, then this is called overriding.
There are lots of methods that we can override in Android, but one method is overridden so often that it was automatically included in the autogenerated code. Take a look at this part of the code again:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); }
In the preceding code, we are overriding the onCreate
method. Notice that the prefix and postfix to the name are quite complicated. Exactly what is going on here will be explained when we more thoroughly deal with methods in Chapter 4, Structuring Code with Java Methods.
Important note
The super.onCreate…
code will also be discussed in depth. But if you can't wait, here is a brief explanation: the super.onCreate…
part of the code is calling another version of the onCreate
method that also exists, even though we cannot see it. This is the one we are overriding.
Now we can add the method definitions to the Sub' Hunter code.
Structuring Sub' Hunter with methods
As we add the method definitions to the code, it should come as no surprise where each of the methods will go. The draw
method will go after the comment about …
do
all
the
drawing…
and so on.
Add the newGame
method definition after the appropriate comment, as shown here:
/* 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. */ void newGame(){ }
Add the draw
method definition after the appropriate comment, as highlighted here:
/* 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() { }
Add the onTouchEvent
definition after this comment, as follows:
/* This part of the code will handle detecting that the player has tapped the screen */ @Override public boolean onTouchEvent(MotionEvent motionEvent) { }
Note that the onTouchEvent
method is another overridden method. Android provides this method for our benefit, and when the player touches the screen, it will call this method. All we need to do now is work out how to handle a touch when the onTouchEvent
method gets called. There is also an error in this code, but we will resolve this when we begin learning about OOP later.
Now, add the takeShot
method definition after the comment, as follows:
/* 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(){ }
Add the boom
method definition after the comment, as follows:
// This code says "BOOM!" void boom(){ }
Now, add the printDebuggingText
definition after the comment about the debugging text:
// This code prints the debugging text void printDebuggingText(){ }
As the project progresses, we will add code to each of the method definitions because, at the moment, they are empty and, therefore, don't do anything. Furthermore, as we learn more about methods, the postfixes and prefixes of the method names will also evolve and become easier to understand.
A concept that is very closely related to methods and useful for understanding them better is OOP.
Introducing OOP
OOP makes it easy to do exceptional things. A simple analogy could be drawn using a machine, perhaps a car. When you step on the accelerator, a whole bunch of things are happening under the hood. We don't need to understand what combustion or fuel pumps are because a smart engineer has provided an interface for us. In this case, a mechanical interface, that is, the accelerator pedal.
Take the following line of Java code as an example; it might look a little intimidating so early on in a book for beginners:
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
However, once you learn that this single line of code searches Space for available satellites, and then communicates with them in orbit around the Earth while retrieving your precise latitude and longitude on the planet, it is easy to begin to glimpse the power and depth of OOP. Even if that code does look a little bit long and scary, imagine talking to a satellite in some other way!
Java is a programming language that has been around a lot longer than Android. It is an object-oriented language. This means that it uses the concept of reusable programming objects. If this sounds like technical jargon, another analogy will help. Java enables us and others (such as the Android development team) to write Java code that can be structured based on real-world "things," and here is an important thing to note: it can be reused.
Classes and objects
So, using the car analogy, we could ask the question: if a manufacturer makes more than one car in a day, do they redesign each part before fitting it to each individual car?
The answer, of course, is no. They get highly skilled engineers to develop exactly the right parts that have been further honed, refined, and improved over a number of years. Then, that same part is reused repeatedly, as well as occasionally improved further. Now, if you want to be picky about my analogy, then you could argue that each of the car's components must still be built from raw materials using real-life engineers, or robots. This is true. Just stick with my analogy a bit longer.
The important thing about OOP
What software engineers do when they write their code is they build a blueprint for an object. We then create an object from their blueprint using Java code, and, once we have that object, we can configure it, use it, combine it with other objects, and more.
Furthermore, we can design our own blueprints and make objects from them as well. The compiler then translates (that is, manufactures) our custom-built creations into working code that can be run by the Android device.
Classes, objects, and instances
In Java, a blueprint is called a class. When a class is transformed into a real working thing, we call it an object or an instance of the class.
Tip
In programming, the words "instance" and "object" are virtually interchangeable. However, sometimes, one word seems more appropriate than the other. All you need to know at this point is that an object/instance is a working realization of a class/blueprint.
We are almost done with OOP – for now.
A final word on OOP, classes, and objects – for now
Analogies are useful only to a certain point. It would be more useful if we simply summarize what we need to know right now:
- Java is a language that allows us to write code once that can be used over and over again.
- This is very useful because it saves us time and allows us to use other people's code to perform tasks. Otherwise, we might not have the time or knowledge to write it for ourselves.
- Most of the time, we do not even need to see other people's code or even know how it works!
Let's consider one last analogy. We just need to know how to use that code, just as we only need to learn how to drive a car, not manufacture one.
So, a smart software engineer up at Google HQ writes a desperately complex Java program that can talk to satellites. He then considers how he can make this code easily available to all the Android programmers out there who are writing location-aware apps and games. One of the things he does is that he turns tasks, such as getting a device's location on the planet's surface, into simple one-line tasks. So, the one line of code we saw previously sets many more lines of code into action that we don't see. This is an example of using somebody else's code to make our code infinitely simpler.
Demystifying the satellite code
Here it is again:
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
locationManager
is an object built from a class, and getLastKnownLocation
is a method defined in that class. Both the class that the locationManager
object was built from and the code within the getLastKnownLocation
method are exceptionally complex. However, we only need to know how to use them, not code them ourselves.
In this book, we will use lots of Android API classes and their methods to make developing games easier. We will also make and use our own reusable classes.
Reusable classes
All methods are part of a class. You need an object built from a class in order to use methods. This will be explained in more detail in Chapter 8, Object-Oriented Programming.
If you are worried that using these classes is somehow cheating, then relax. This is what you are meant to do. In fact, many developers "cheat" much more than simply using classes. They use premade game libraries, such as libGDX, or complete game engines, such as Unity or Unreal. We will teach you Java without these cheats, leaving you well prepared to move on to libraries and engines should you wish to.
But where are all of these classes? Do you remember this code from when we were typing the method definitions? Take a closer look at the following code:
/* This part of the code will handle detecting that the player has tapped the screen */ @Override public boolean onTouchEvent(MotionEvent motionEvent) { return true; }
There are two reasons why the previous code had an error. The first reason is that Android Studio doesn't know anything about the MotionEvent
class – yet. Additionally, note that in the previous code, I have added a line of code, as follows:
return true;
This is the second reason there is an error. This will be fully explained in Chapter 4, Structuring Code with Java Methods. For now, just add the highlighted line of code, return true;
, exactly where it appears in the preceding code. Don't miss the semicolon (;
) at the end.
We will solve the MotionEvent
error when we discuss packages next.
Using Java packages
Packages are grouped collections of classes. If you look at the top of the code that we have written so far, you will see these lines of code:
import android.app.Activity; import android.view.Window; import android.os.Bundle;
These lines of code make available the Activity
and Bundle
classes along with their methods. Comment out two of the preceding lines like this:
//import android.app.Activity; import android.view.Window; //import android.os.Bundle;
Now look at your code, and you will see errors in at least three places. The word Activity
has an error because Activity
is a class that Android Studio is no longer aware of in the following line:
public class SubHunter extends Activity {
The word onCreate
also has an error because it is a method from the Activity
class, and the word Bundle
has an error because it is a class that since we commented out the previous two lines, Android Studio is no longer aware of. This next line highlights where the errors are:
protected void onCreate(Bundle savedInstanceState) {
Uncomment the two lines of code to resolve the errors, and we will add some more import…
code for the rest of the classes that we will use in this project, including one to fix the MotionEvent
class error.
Adding classes by importing packages
We will solve the error in the onTouchEvent
method declaration by adding an import
statement for the MotionEvent
class, which is causing the problem. Underneath the two existing import
statements, add this new statement, which I have highlighted:
package com.gamecodeschool.subhunter; // These are all the classes of other people's // (Android) code that we use for Sub Hunter import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent;
Check the onTouchEvent
method, and you will see that the error is gone. Now, add these further import
statements directly underneath the one you just added, and that will take care of importing all of the classes that we need for this entire game. As we use each class throughout the next five chapters, I will introduce them formally. In the preceding code, I have also added some comments to remind me what import
statements do.
Add the highlighted code. The syntax needs to be exact, so consider copying and pasting the code:
// These are all the classes of other people's // (Android API) code that we use in Sub'Hunt import android.app.Activity; import android.view.Window; import android.os.Bundle; import android.view.MotionEvent; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.view.Display; import android.util.Log; import android.widget.ImageView; import java.util.Random;
Notice that the new lines of code are grayed-out in Android Studio. This is because we are not using them yet, and at this stage, many of them are technically unnecessary. Additionally, Android Studio gives us a warning if we hover the mouse pointer over the little yellow indicators to the right of the unused import
statements:

Figure 2.6 – Indicating unused import statements
This isn't a problem, and we are doing things this way for convenience as it is the first project. In the next project, we will learn how to add import
statements as and when needed without any fuss.
We have briefly mentioned the Activity
class. However, we need to learn a little bit more about it to proceed. We will do so while linking up our methods with method calls.
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:
- In the Android Studio menu bar, select Tools | AVD Manager.
- Click on the green play icon for the emulator.
- 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
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
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:
- When the game was started, the
onCreate
method was called (by Android). - This was followed by the
newGame
method, which was executed and then returned to theonCreate
method. - 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
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.
Summary
The phone screen is still blank, but we have achieved our first output to the Logcat window. In addition, we have laid out the entire structure of the Sub' Hunter game. All we need to do now is learn more about Java, and then use it to add code to each of the methods.
In this chapter, we learned that Java methods are used to divide up the code into logical sections, each with a name. We don't know the full details of Java methods yet. However, if you understand that you can define methods and then execute them by calling them, then you know all you need to make further progress.
We also took a first glimpse at OOP. It doesn't matter whether OOP seems a little baffling at this stage. If you know that we can code a class and create usable objects in our code based on that class, then you know enough to continue.
In the next chapter, we will learn about our game's data, for example, how the game "remembers" values such as the position of the submarine or the size of the grid. We will learn that our data can take many forms but can generally be referred to as variables.