Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Learning Java by Building Android Games - Third Edition
Learning Java by Building Android Games - Third Edition

Learning Java by Building Android Games: Learn Java and Android from scratch by building five exciting games, Third Edition

By John Horton
€23.99 €15.99
Book Mar 2021 686 pages 3rd Edition
eBook
€23.99 €15.99
Print
€28.99
Subscription
€14.99 Monthly
eBook
€23.99 €15.99
Print
€28.99
Subscription
€14.99 Monthly

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Buy Now

Product Details


Publication date : Mar 26, 2021
Length 686 pages
Edition : 3rd Edition
Language : English
ISBN-13 : 9781800565869
Vendor :
Google
Category :
Languages :
Table of content icon View table of contents Preview book icon Preview Book

Learning Java by Building Android Games - Third Edition

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

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

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

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

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

Figure 2.5 – Planning the game using a flowchart

The flowchart shows the steps the game will take, as follows:

  1. The game is launched by tapping on its icon in the app drawer (or running it in Android Studio).
  2. 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.
  3. Next, everything is drawn to the screen: the grid-lines and the text (heads-up display or HUD), including the debugging text (if enabled).
  4. At this point, the game does nothing. It is waiting for the player to tap on the screen.
  5. 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.
  6. Alternatively, if there was a hit, then the BOOM! screen is shown.
  7. 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

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:

  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.

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.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Learn Java, Android, and object-oriented programming from scratch
  • Find out how to build games including Sub Hunter, Retro Pong, Bullet Hell, Classic Snake, and Scrolling Shooters
  • Create and design your own games by learning all the concepts that a game developer must know

Description

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.

What you will learn

Set up a game development environment in Android Studio Respond to a player’s touch and program intelligent enemies who can challenge the player in different ways Explore collision detection, sprite sheets animation, simple tracking and following, AI, parallax backgrounds, and particle explosions Animate objects at 60 FPS and manage multiple independent objects using OOP Work with design patterns such as OOP, singleton, strategy, and entity-component Work with the Android API, the SoundPool API, Paint, Canvas, Bitmap classes, and detect version numbers

What do you get with eBook?

Product feature icon Instant access to your Digital eBook purchase
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Buy Now

Product Details


Publication date : Mar 26, 2021
Length 686 pages
Edition : 3rd Edition
Language : English
ISBN-13 : 9781800565869
Vendor :
Google
Category :
Languages :

Table of Contents

24 Chapters
Preface Chevron down icon Chevron up icon
Chapter 1: Java, Android, and Game Development Chevron down icon Chevron up icon
Chapter 2: Java – First Contact Chevron down icon Chevron up icon
Chapter 3: Variables, Operators, and Expressions Chevron down icon Chevron up icon
Chapter 4: Structuring Code with Java Methods Chevron down icon Chevron up icon
Chapter 5: The Android Canvas Class – Drawing to the Screen Chevron down icon Chevron up icon
Chapter 6: Repeating Blocks of Code with Loops Chevron down icon Chevron up icon
Chapter 7: Making Decisions with Java If, Else, and Switch Chevron down icon Chevron up icon
Chapter 8: Object-Oriented Programming Chevron down icon Chevron up icon
Chapter 9: The Game Engine, Threads, and the Game Loop Chevron down icon Chevron up icon
Chapter 10: Coding the Bat and Ball Chevron down icon Chevron up icon
Chapter 11: Collisions, Sound Effects, and Supporting Different Versions of Android Chevron down icon Chevron up icon
Chapter 12: Handling Lots of Data with Arrays Chevron down icon Chevron up icon
Chapter 13: Bitmap Graphics and Measuring Time Chevron down icon Chevron up icon
Chapter 14: Java Collections, the Stack, the Heap, and the Garbage Collector Chevron down icon Chevron up icon
Chapter 15: Android Localization – Hola! Chevron down icon Chevron up icon
Chapter 16: Collections and Enumerations Chevron down icon Chevron up icon
Chapter 17: Manipulating Bitmaps and Coding the Snake Class Chevron down icon Chevron up icon
Chapter 18: Introduction to Design Patterns and Much More! Chevron down icon Chevron up icon
Chapter 19: Listening with the Observer Pattern, Multitouch, and Building a Particle System Chevron down icon Chevron up icon
Chapter 20: More Patterns, a Scrolling Background, and Building the Player's Ship Chevron down icon Chevron up icon
Chapter 21: Completing the Scrolling Shooter Game Chevron down icon Chevron up icon
Chapter 22: What Next? Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Filter icon Filter
Top Reviews
Rating distribution
Empty star icon Empty star icon Empty star icon Empty star icon Empty star icon 0
(0 Ratings)
5 star 0%
4 star 0%
3 star 0%
2 star 0%
1 star 0%

Filter reviews by


No reviews found
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

How do I buy and download an eBook? Chevron down icon Chevron up icon

Where there is an eBook version of a title available, you can buy it from the book details for that title. Add either the standalone eBook or the eBook and print book bundle to your shopping cart. Your eBook will show in your cart as a product on its own. After completing checkout and payment in the normal way, you will receive your receipt on the screen containing a link to a personalised PDF download file. This link will remain active for 30 days. You can download backup copies of the file by logging in to your account at any time.

If you already have Adobe reader installed, then clicking on the link will download and open the PDF file directly. If you don't, then save the PDF file on your machine and download the Reader to view it.

Please Note: Packt eBooks are non-returnable and non-refundable.

Packt eBook and Licensing When you buy an eBook from Packt Publishing, completing your purchase means you accept the terms of our licence agreement. Please read the full text of the agreement. In it we have tried to balance the need for the ebook to be usable for you the reader with our needs to protect the rights of us as Publishers and of our authors. In summary, the agreement says:

  • You may make copies of your eBook for your own use onto any machine
  • You may not pass copies of the eBook on to anyone else
How can I make a purchase on your website? Chevron down icon Chevron up icon

If you want to purchase a video course, eBook or Bundle (Print+eBook) please follow below steps:

  1. Register on our website using your email address and the password.
  2. Search for the title by name or ISBN using the search option.
  3. Select the title you want to purchase.
  4. Choose the format you wish to purchase the title in; if you order the Print Book, you get a free eBook copy of the same title. 
  5. Proceed with the checkout process (payment to be made using Credit Card, Debit Cart, or PayPal)
Where can I access support around an eBook? Chevron down icon Chevron up icon
  • If you experience a problem with using or installing Adobe Reader, the contact Adobe directly.
  • To view the errata for the book, see www.packtpub.com/support and view the pages for the title you have.
  • To view your account details or to download a new copy of the book go to www.packtpub.com/account
  • To contact us directly if a problem is not resolved, use www.packtpub.com/contact-us
What eBook formats do Packt support? Chevron down icon Chevron up icon

Our eBooks are currently available in a variety of formats such as PDF and ePubs. In the future, this may well change with trends and development in technology, but please note that our PDFs are not Adobe eBook Reader format, which has greater restrictions on security.

You will need to use Adobe Reader v9 or later in order to read Packt's PDF eBooks.

What are the benefits of eBooks? Chevron down icon Chevron up icon
  • You can get the information you need immediately
  • You can easily take them with you on a laptop
  • You can download them an unlimited number of times
  • You can print them out
  • They are copy-paste enabled
  • They are searchable
  • There is no password protection
  • They are lower price than print
  • They save resources and space
What is an eBook? Chevron down icon Chevron up icon

Packt eBooks are a complete electronic version of the print edition, available in PDF and ePub formats. Every piece of content down to the page numbering is the same. Because we save the costs of printing and shipping the book to you, we are able to offer eBooks at a lower cost than print editions.

When you have purchased an eBook, simply login to your account and click on the link in Your Download Area. We recommend you saving the file to your hard drive before opening it.

For optimal viewing of our eBooks, we recommend you download and install the free Adobe Reader version 9.