Reader small image

You're reading from  Learning Java by Building Android Games - Third Edition

Product typeBook
Published inMar 2021
Reading LevelBeginner
PublisherPackt
ISBN-139781800565869
Edition3rd Edition
Languages
Right arrow
Author (1)
John Horton
John Horton
author image
John Horton

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

Right arrow

Chapter 9: The Game Engine, Threads, and the Game Loop

In this chapter, we will see the game engine come together. By the end of the chapter, we will have an exciting blank screen that draws debugging text at 60 frames per second on a real device, although probably less on an emulator. While doing so, we will learn about programming threads, try-catch blocks, the Runnable interface, the Android activity lifecycle, and the concept of a game loop.

My expression of excitement for a blank screen might seem sarcastic but once this chapter is done, we will be able to code and add game objects, almost at will. We will see how much we have achieved in this chapter when we add the moving ball and controllable bat in the next one. Furthermore, this game engine code will be used as an approximate template (we will improve it with each project) for future projects, making the realization of future games faster and easier.

We will be covering the following in this chapter:

  • Coding...

Coding the PongActivity class

In this project, as discussed previously, we will have multiple classes. Four to be exact. The Activity class provided by the Android API is the class that interacts with the operating system. We have already seen how the operating system interacts with onCreate when the player clicks the app icon to start an app (or our game). Furthermore, we have seen how the operating system calls the onTouchEvent method when the user interacts with the screen, giving us the opportunity to make our game respond appropriately.

As this game is more complicated and needs to respond in real time, it is necessary to use a slightly more in-depth structure. At first, this seems like a complication, but in the long run, it makes our code simpler and easier to manage.

Rather than having a class called Pong (analogous to SubHunter) that does everything, we now have a class that just handles the startup and shutdown of our game, as well as helping a bit with initialization...

Coding the PongGame class

The first thing we will do is solve the problem of our PongGame class not being of the View type. Update the class declaration as highlighted, like this:

class PongGame extends SurfaceView {

You will need to import the android.view.SurfaceView class as shown next so that Android Studio knows about the SurfaceView class. You can add the line of code after the package declaration in the PongGame.java file or use the Alt + Enter keyboard combination as we have done before.

SurfaceView is a descendant of View and now PongGame is, by inheritance, also a type of View. Look again at the import statement that has been added. This relationship is made clear as highlighted next:

android.view.SurfaceView

Tip

Remember that it is because of polymorphism that we can send descendants of View to the setContentView method in the PongActivity class and it is because of inheritance that PongGame is a type of SurfaceView.

There are quite a few descendants...

Thinking ahead about the PongGame class

We will be returning to this class constantly over the course of this project. What we will do in this chapter is get the fundamentals set up ready to add the game objects (the bat and ball) as well as collision detection and sound effects over the next two chapters.

To achieve this, first we will add a bunch of member variables, and then we will add some code inside the constructor to set the class up when it is instantiated/created by PongActivity.

After this, we will code a startNewGame method that we can call every time we need to start a new game, including the first time we start a game after the app is started by the user.

Following on, we get to code the draw method, which will reveal the new steps that we need to take to draw to the screen 60 times per second, and we will also see some familiar code that uses our old friends Canvas, Paint, and drawText.

At this point, we will need to discuss some more theory, things such...

The game loop

What is a game loop anyway? Almost every game has a game loop. Even games you might suspect do not, such as turn-based games, still need to synchronize player input with drawing and processing AI while following the rules of the underlying operating system.

There is a constant need to update the objects in a game, perhaps by moving them, rotating them, and so on. And then everything must be drawn in its new position, all the while responding to user input. A visual might help:

Figure 9.2 – Visualizing the game loop

Figure 9.2 – Visualizing the game loop

Our game loop comprises three main phases:

  1. Update all game objects by moving them, detecting collisions, and processing AI if used.
  2. Based on the just-updated data, draw the objects (current frame of animation) in their latest state.
  3. Respond to screen touches from the player.

We already have a draw method for handling that part of the loop. This suggests that we will have a method to do all the...

Getting familiar with threads

So, what is a thread? You can think of threads in programming in the same way you do threads in a story. In one thread of a story, we might have the primary character battling the enemy on the frontline, while in another thread the soldier's family is going about life at home. Of course, a story doesn't have to have just two threads. We could introduce a third thread; perhaps the story also tells of the politicians and military commanders making decisions. And these decisions then subtly, or not so subtly, affect what happens in the other threads.

Programming threads are just like this. We create parts/threads in our program that control different aspects for us. In Android, threads are especially useful when we need to ensure that a task does not interfere with the main (user interface) thread of the app or if we have a background task that takes a long time to complete and must not interrupt the main thread of execution. We introduce threads...

Implementing the game loop with a thread

Now we have learned about the game loop, threads, and try and catch, we can put it all together to implement our game loop.

We will add the entire code for the game loop, including writing two methods in the PongGame class to start and stop the thread that will control the loop.

After we have done this, we will again need to do a little bit more theory. The reason for this is that the player can quit the app whenever they like, and our game's thread will need to know so that it can stop itself. We will examine the Android activity lifecycle, which will give us the final pieces of the puzzle that we need before we run our game.

Implementing Runnable and providing the run method

Update the class declaration by implementing Runnable, just like we discussed we would need to and as shown in this next highlighted code:

class PongGame extends SurfaceView implements Runnable{

Notice that we have a new error in the code. Hover...

Running the game

Click the play button in Android Studio and the hard work and theory of the last two chapters will spring to life:

Figure 9.4 – Running the game

Figure 9.4 – Running the game

Now we can make much faster progress in the following chapters and we will use quite similar code for a game loop in all the remaining projects in this book.

Summary

This was probably the most technical chapter so far. Threads, game loops, timing try and catch blocks, using interfaces, the activity lifecycle, and so on… that's an awfully long list of topics to cram into a chapter. If the exact interrelationships between these things are not entirely clear, it is not a problem. All you need to know is that when the player starts and stops the game, the PongActivity class will handle starting and stopping the thread by calling the PongGame class's pause and resume methods. It achieves this via the overridden onPause and onResume methods, which are called by the operating system.

Once the thread is running, the code inside the run method executes alongside the user interface thread that is listening for player input. Once we call the update and draw methods from the run method, at the same time as keeping track of how long each frame is taking, our game is ready to rock and roll. We just need to add some game objects to...

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

Author (1)

author image
John Horton

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