<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Game Code SchoolGame Code School -  &#187; Android</title>
	<atom:link href="https://gamecodeschool.com/category/android/feed/" rel="self" type="application/rss+xml" />
	<link>https://gamecodeschool.com</link>
	<description>Game Coding for Beginners</description>
	<lastBuildDate>Wed, 29 Jan 2025 11:28:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Android Platformer Project Part 2</title>
		<link>https://gamecodeschool.com/android/android-platformer-project-part-2/</link>
		<comments>https://gamecodeschool.com/android/android-platformer-project-part-2/#comments</comments>
		<pubDate>Mon, 15 May 2023 13:18:00 +0000</pubDate>
		<dc:creator><![CDATA[John Horton]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">https://gamecodeschool.com/?p=16603</guid>
		<description><![CDATA[The Singleton Pattern, Java HashMap, Storing Bitmaps Efficiently, and Designing Levels If you have landed on this page from a search engine you should first view part 1 of this platform game tutorial. This is going to be a very busy and varied tutorial. We will learn the theory of the Singleton design pattern. We [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>The Singleton Pattern, Java HashMap, Storing Bitmaps Efficiently, and Designing Levels</h2>
<p>If you have landed on this page from a search engine you should first view <a href="https://gamecodeschool.com/android/android-platformer-project-part-1/">part 1 of this platform game tutorial</a>. This is going to be a very busy and varied tutorial. We will learn the theory of the Singleton design pattern. We will then be introduced to another of the classes of the Java Collections, HashMap in which we will see how we can more efficiently store and make available the wide variety of bitmaps that are required for this project. We will also get started on our new and improved Transform class, code the first of the component-based classes, code the all-new Camera class, and make a significant start on some of the more familiar classes, GameState, PhysicsEngine, Renderer, GameEngine, and more besides.</p>
<p>Here is a list of what to expect and the order to expect it.</p>
<ul>
<li>The Singleton pattern</li>
<li>The Java HashMap class</li>
<li>The memory problem and the BitmapStore</li>
<li>Coding a basic Transform</li>
<li>Coding the block-based component classes</li>
<li>Creating the game levels</li>
<li>Coding a stripped-down GameObjectFactory</li>
<li>Coding the GameState</li>
<li>Coding the SoundEngine</li>
<li>Coding the PhysicsEngine</li>
<li>Coding the Renderer</li>
<li>Explaining and coding the Camera class</li>
<li>Coding the HUD</li>
<li>Coding the UIController</li>
<li>Coding the Activity</li>
<li>Coding the GameEngine</li>
<li>Coding a stripped-down LevelManger</li>
<li>Running the game for the first time</li>
</ul>
<p>By the end of this chapter, we will see the game in its first runnable state!</p>
<p>Throughout the course of this chapter, there will be loads of errors in Android Studio because so many of the classes are interconnected and we can’t code them all simultaneously. Note also that when there is an error in an interface file (and there will be) attempting to implement that interface will also cause an error in the implementing class. Stick with it until the end of this chapter as it all comes together, and we will see the first results on our screens. Be sure to read the information box at the top of chapter 22 as well as the one below for the quicker copy-and-paste approach you might like to take.</p>
<p>If you want to copy and paste the code read this next information box.</p>
<p>Feel free to copy and paste these classes if you prefer. All classes go in the usual folder except where I specifically point it out (for Level based classes). Be aware that my domain name is used in all the package names in the download bundle. The first package declaration in all the files will probably auto-update to your package name when you paste them into your project. However, when the import code refers to the packages that we have created &#8230;GOSpec (in the previous chapter) and …Level (later in this chapter) you will probably need to change the domain name and possibly the project name manually in some or maybe all of the files that import &#8230;GOSpec and …Level.</p>
<p>If you want to type everything then you will just need to add a new class of the correct name by right-clicking the appropriate folder and selecting New | Java Class.</p>
<p>Let’s talk about another pattern.</p>
<h1>The Singleton pattern</h1>
<p>The Singleton pattern as the name suggests is a pattern that is used when we want only one of something. And more importantly, we need to absolutely guarantee we only have one of something. The something I refer to is an instance of a class. Furthermore, the Singleton pattern is also used when we want to allow global access to some of its data or methods. The class can then be used from anywhere within a project and yet is also guaranteeing that all parts/classes of the project that access the class are using the exact same instance.</p>
<p>Part of the Singleton conundrum is simple. To make parts of it available to any other class you simply make the methods public and static.</p>
<p>But how do we guarantee that only one instance can ever be created? We will look at the code next but as a look-ahead what we will do is create a class that has a private constructor. Remember that a private method can only be called from within the class itself. And a public and static method that creates an instance then returns a reference- provided an instance has not already been created- and if it has then a reference to the existing instance is returned. This implies that the class will hold a reference to its own instance. Let’s look at this with some sample code.</p>
<h2>The Singleton code</h2>
<p>Here is the class declaration and it contains just one variable. A private and static instance of an object that is the same type as the class itself.</p><pre class="crayon-plain-tag">class SingletonClass {

private static SingletonClass mOurInstance;

}</pre><p>The name of the class is not relevant just that the name of the class is the same as the type being declared.</p>
<p>Next, we can look at the constructor method.</p><pre class="crayon-plain-tag">private SingletonClass() {

// This is only here to prevent instantiation

}</pre><p>It has the same name as the class as do all constructor methods but note it is private. When a method is private it can only be called by code within the class. Note that depending upon the needs of the project, it is perfectly acceptable to have some code in the constructor, just as long as the constructor is private.</p>
<p>This next method is default access and returns an object of type SingletonClass. Take a look over the code.</p><pre class="crayon-plain-tag">// Calling this method is the only way to get a BitmapStore

static SingletonClass getInstance(Context context) {

if(mOurInstance == null) {

    mOurInstance = new SingletonClass();

}



return mOurInstance;

}</pre><p>As the class is default access, any code in the same package can call the method. In addition, because it is static, it can be called without an instance of the class. Now look at the code in the body. The first line checks whether the private member, mOurInstance has been initialized with if(mOurInstance == null). If the object has not been initialized (is null) then the private constructor is called, and the instance is initialized. The final line of code returns a reference to the private instance. Also note as will be the case in the platform game, it might not even be necessary to return an instance.</p>
<p>Now we add a method that actually does something. After all, a class must have a purpose.</p><pre class="crayon-plain-tag">Static void someUsefulMethod() {

// Do something useful

}</pre><p>Note the previous method, someUsefulMethod is static so it too, like getInstance can be called without a reference to the class. This is why I said the getInstance method doesn’t necessarily have to return an instance of the class.</p>
<p>Next, we add another method. Note that it is not static.</p><pre class="crayon-plain-tag">void someOtherUsefulMethod() {

// Do something else useful

}</pre><p>As someOtherUsefulMethod is not static, an instance of the class would be needed in order to call it. So, in this specific case getInstance would need to return a reference to the object.</p>
<p>Now let’s see how we could use our new class in some other class of our project. First, we declare an instance of SingletonClass but as we cannot call the constructor we initialize it by calling the static getInstance method.</p><pre class="crayon-plain-tag">SingletonClass sc = SingletonClass.getInstance();</pre><p>The getInstance method will check whether the member SingletonClass object needs to be initialized and if required calls the constructor. Either way, getInstance returns a reference to the private member instance of SingletonClass which initializes sc.</p>
<p>Now we can use the two methods that actually do something useful.</p><pre class="crayon-plain-tag">// Call the static method

SingletonClass.someUsefulMethod();



// Call the other method

sc.someOtherUsefulMethod();</pre><p>The first method, someUsefulMethod is called without using a reference because it is static. The second method is called using the sc reference we initialized using getInstance.</p>
<p>It might surprise you to learn that the Singleton pattern is controversial. Its very use is discouraged and even banned in some situations. There are a number of reasons for this but in one-person or small-team projects, many of the objections are either not relevant or much less relevant. Android Studio even has a way to auto-generate a singleton. If you are interested in a discussion about the use of the Singleton pattern then a quick Google will bring up strong condemnations, spirited defenses, and even heated arguments about its use. I suggest you read this article because it gives a fairly balanced view of Singleton and from a game development perspective. <a href="http://gameprogrammingpatterns.com/singleton.html">http://gameprogrammingpatterns.com/singleton.html</a>. Note that the article discusses Singleton in the context of a different programming language, C++ but the discussion is still useful.</p>
<p>If you are going for an interview for a programming job very soon you need to read the previous paragragh. Otherwise, enjoy your Singletons.</p>
<p>Next, we will learn about the Java HashMap class and then we will get to code a Singleton for real.</p>
<h1>More Java Collections – Meet Java Hashmap</h1>
<p>Java HashMaps are neat. They are part of the Java Collections and a kind of cousin to ArrayList. They basically encapsulate really useful data storage techniques that would otherwise be quite technical for us to code successfully for ourselves.</p>
<p>We will get practical with HashMap in the next section when we discuss a problem regarding storing Bitmap instances in our GameObject instances. HashMap will be the second part (Singletons are the first part) of the solution to this problem.</p>
<p>I thought it would be worth taking a first look at HashMap on its own.</p>
<p>Suppose, we want to store the data of lots of characters from an RPG-type game, and each different character is represented by an object of type Character.</p>
<p>We could use some of the Java tools we already know about like arrays or ArrayList. However, Java HashMap is also similar to these things but with HashMap we can give a unique key/identifier to each Character object and access any such object using that key/identifier.</p>
<p>The term hash comes from the process of turning our chosen key/identifier into something used internally by the HashMap class. The process is called hashing.</p>
<p>Any of our Character instances can then be accessed with our chosen key/identifier. A good candidate for a key/identifier in the Character class scenario would be the character&#8217;s name.</p>
<p>Each key/identifier has a corresponding object, in this case, it is of type Character. This is known as a key-value pair.</p>
<p>We just give HashMap a key and it gives us the corresponding object. No need to worry about which index we stored our characters, perhaps Geralt, Ciri, or Triss at, just pass the name to HashMap and it will do the work for us.</p>
<p>Let&#8217;s look at some examples. You don&#8217;t need to type any of this code just get familiar with how it works.</p>
<p>We can declare a new HashMap to hold keys and Character instances like this code:</p><pre class="crayon-plain-tag">Map&lt;String, Character&gt; characterMap;</pre><p>The previous code assumes we have coded a class called Character.</p>
<p>We can initialize the HashMap like this:</p><pre class="crayon-plain-tag">characterMap = new HashMap();</pre><p>We can add a new key and its associated object like this.</p><pre class="crayon-plain-tag">characterMap.put(“Geralt”, new Character());</pre><p>And this:</p><pre class="crayon-plain-tag">characterMap.put(“Ciri”, new Character());</pre><p>And this:</p><pre class="crayon-plain-tag">characterMap.put(“Triss”, new Character());</pre><p>All the example code assumes that we can somehow give the Character instances their unique properties to reflect their internal differences elsewhere.</p>
<p>We can then retrieve an entry from the HashMap like this:</p><pre class="crayon-plain-tag">Character ciri = characterMap.get(“Ciri”);</pre><p>Or perhaps use the Character class’s methods directly like this:</p><pre class="crayon-plain-tag">characterMap.get(“Geralt”).drawSilverSword();

// Or maybe call some other hypothetical method

characterMap.get(“Triss”).openFastTravelPortal(“Kaer Morhen”);</pre><p>The previous code calls the hypothetical methods drawSilverSword and openFastTravelPortal on the Character class.</p>
<p>The HashMap class also has lots of useful methods like ArrayList. See the official Java page for HashMap here: <a href="https://docs.oracle.com/javase/tutorial/collections/interfaces/map.html">https://docs.oracle.com/javase/tutorial/collections/interfaces/map.html</a>.</p>
<p>Now we can use HashMap for real. Before we do let’s look ahead in this project and we will see that we have a bit of a memory problem.</p>
<h1>The memory problem and the BitmapStore</h1>
<p>In all the projects on this website so far, the class representing the object in the game also held a copy of the Bitmap.</p>
<p>When we have just one or a few of each object as we did in previous projects this is not a problem but, in this project, we will have more than a hundred of some of the Bitmaps representing the tiles that make the platforms. At best this is inefficient and will waste memory, and device power and make the game run more slowly and at worst (especially on older devices) the game will crash because it has run out of memory.</p>
<p>We need a way to share Bitmap instances between objects. This suggests a central store. Hey; what about that HashMap and that Singleton thing we just learned about? How convenient.</p>
<h2>Coding the BitmapStore class</h2>
<p>All our game objects already have a specification that holds the name of the required Bitmap in a String. We have also just learned how we can store objects in a HashMap and retrieve them using a key. In addition, we know how to make a class available to all other classes using the Singleton pattern.</p>
<p>What we will do is code a Singleton class called BitmapStore which will hold all the required Bitmap instances using the bitmapName String (from the graphics-based component classes). We will however only store one of each Bitmap.</p>
<p>When the initialize method of the graphics-related component class executes instead of initializing its own Bitmap it will call the addBitmap method of the BitmapStore class. If the Bitmap in question has not already been added to the HashMap then it will do so. When the Bitmap needs to be drawn (during the draw method) each object will simply call the getBitmap method of the BitmapStore class. The BitmapStore, as we will see, will have two HashMaps, one for the regular Bitmap instances and one for reversed instances. The BitmapStore class will also have a getReversedBitmap method.</p>
<p>Create a new class called BitmapStore, and add the following members and the constructor as shown next.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Matrix;

import android.graphics.PointF;



import java.util.HashMap;

import java.util.Map;



class BitmapStore {

private static Map&lt;String, Bitmap&gt; mBitmapsMap;

private static Map&lt;String, Bitmap&gt; mBitmapsReversedMap;

private static BitmapStore mOurInstance;



// Calling this method is the only way to get a BitmapStore

static BitmapStore getInstance(Context context) {



mOurInstance = new BitmapStore(context);

return mOurInstance;

}



// Can't be called using new BitmapStore()

private BitmapStore(Context c) {

mBitmapsMap = new HashMap();

mBitmapsReversedMap = new HashMap();



// Put a default bitmap in each of the maps

// to return in case a bitmap doesn't exist

addBitmap(c,

"death_visible",

new PointF(1, 1),

128,

true);

}

}</pre><p>There are three private members. Two HashMaps called mBitmapsMap and mBitmapsReversedMap. They will hold all the Bitmaps and reversed Bitmaps (when an object requires it) respectively. Notice that they use a String as the key and of course a Bitmap as its pair.</p>
<p>The third and final private member should be as expected. It is an instance of BitmapStore itself as discussed in the Singleton pattern. And, also as should be expected the constructor is private. It cannot be called from outside of the BitmapStore class.</p>
<p>As expected with the Singleton pattern we have a static getInstance method that calls the BitmapStore constructor if it hasn’t done so already and then returns a reference to the one and only instance of the class.</p>
<p>Inside this constructor, the two HashMap instances are initialized and the addBitmap method is called. We will code the addBitmap method shortly so there will be an error because the method doesn’t exist yet. It is worth explaining the details of this call now, however.</p>
<p>If you look at the arguments in the call to addBitmap you will see, we pass in the Context (c), a PointF containing a size (which will allow addBitmap to scale the Bitmap) a somewhat arbitrary value of 128 and a boolean with a value of true.</p>
<p>The value of 128 is a value that has been predetermined as the number of pixels on the device which represents one meter of the game world. If the game world is to be scaled by our soon-to-be-coded Camera class, then it needs to know what to scale it to. When you see the Camera class later this chapter this will be clearer.</p>
<p>The final boolean indicates whether a reversed copy of the Bitmap is required as well.</p>
<p>We mentioned in the previous chapter while exploring the graphical assets that the death_visible graphic is for creating an inescapable wall around the level which will kill the player if touched. This helps avoid bugs like the player falling out of the level and then tumbling for eternity through space. The graphic is noticeable, so the level tester can clearly see that he has sufficiently wrapped the level during the development phase and then before the game is released it can be replaced with a blank graphic so that only the background is visible, but the player is still contained within where the level designer wants him.</p>
<p>All the other calls to addBitmap will be made by the initialize method within the graphics-related component classes.</p>
<p>Now add the getBitmap and getBitmapReversed methods.</p><pre class="crayon-plain-tag">static Bitmap getBitmap(String bitmapName) {



if (mBitmapsMap.containsKey(bitmapName)) {

return mBitmapsMap.get(bitmapName);

} else {

return mBitmapsMap.get("death_visible");

}

}



static Bitmap getBitmapReversed(String bitmapName) {



if (mBitmapsReversedMap.containsKey(bitmapName)) {

return mBitmapsReversedMap.get(bitmapName);

} else {

return mBitmapsReversedMap.get("death_visible");

}

}</pre><p>All that these methods do is receive a String and then return the Bitmap that matches the key. The return statements are wrapped in an if-else block so that when a Bitmap does not exist the death_visible Bitmap is returned. This might at first seem odd. When we see how to lay out level designs we will see that we specifically have a way of adding these death_visible objects. And we will specifically request the death_visible Bitmap when it is required. By returning the death_visible Bitmap as a default, when we neglect to add a Bitmap the death_visible Bitmap will appear within the level when the game is tested, and we will know we have a Bitmap missing. In addition, it will prevent the game from crashing as it would if an uninitialized Bitmap was returned.</p>
<p>Add the addBitmap method shown next.</p><pre class="crayon-plain-tag">static void addBitmap(Context c,

String bitmapName,

PointF objectSize,

int pixelsPerMetre,

boolean needReversed) {



Bitmap bitmap;

Bitmap bitmapReversed;



// Make a resource id out of the string of the file name

int resID = c.getResources().getIdentifier(bitmapName,

"drawable", c.getPackageName());



// Load the bitmap using the id

bitmap = BitmapFactory

.decodeResource(c.getResources(), resID);



// Resize the bitmap

bitmap = Bitmap.createScaledBitmap(bitmap,

(int) objectSize.x * pixelsPerMetre,

(int) objectSize.y * pixelsPerMetre,

false);



mBitmapsMap.put(bitmapName, bitmap);



if (needReversed) {

// Create a mirror image of the bitmap

Matrix matrix = new Matrix();

matrix.setScale(-1, 1);

bitmapReversed = Bitmap.createBitmap(

bitmap,

0, 0,

bitmap.getWidth(),

bitmap.getHeight(),

matrix, true);



mBitmapsReversedMap.put(bitmapName, bitmapReversed);

}



}</pre><p>The addBitmap method should look quite familiar by now. The code loads the Bitmap from the String representing the Bitmap’s name. The Bitmap is scaled in the usual way using createScaledBitmap. The only difference to what we saw in the graphics-based component classes of the previous project is that the size of the object and the value representing the pixels-per-metre is used to determine the size.</p>
<p>The Bitmap is added to the HashMap and if a reversed copy of the Bitmap has been requested then the Matrix class is used to create a reversed copy and the Bitmap is added to the HashMap for reversed Bitmaps.</p>
<p>Add the clearStore method shown next.</p><pre class="crayon-plain-tag">static void clearStore() {

mBitmapsMap.clear();

mBitmapsReversedMap.clear();

}</pre><p>The clearStore method does two things. It first uses the clear method of the HashMap class to empty the mBitmapsMap HashMap and then does the same thing for the mBitmapsReversedMap HashMap. This is needed because typically each level will use a different selection of graphics files and if you don’t clear them then every time the player attempts a different level they will be left with unnecessary bitmaps in the store.</p>
<p>To be realistic about this, it really wouldn’t matter even for a very basic device to have every single bitmap loaded at once- it’s still way more efficient than we have been up until now as we used to load a bitmap for every instance of every game object. But if you added more levels and more object specifications then eventually your game would perform poorly so it is good practice to clear the store before loading the required bitmaps for the current level. This is the purpose of this method.</p>
<h1>Coding the basic transform</h1>
<p>In this project, we will do a better job of the Transform class. In the Scrolling Shooter project, the Transform was packed full of variables and methods that many of the objects didn’t need. It served its purpose to prevent the project from getting even bigger and we got away with it because there was a limited number of objects in the game.</p>
<p>What we will code now is a very simple version of the Transform and it will contain only the members and methods needed by all game objects. When we need a Transform that does more specific things we can then extend this class and add the required extra members and methods.</p>
<p>Add a new class called Transform. Code the member variables and the constructor as shown next.</p><pre class="crayon-plain-tag">import android.graphics.PointF;

import android.graphics.RectF;



public class Transform {

RectF mCollider;

private PointF mLocation;

private float mSpeed;

private float mObjectHeight;

private float mObjectWidth;

private PointF mStartingPosition;

private boolean mHeadingUp = false;

private boolean mHeadingDown = false;



private boolean mFacingRight = true;

private boolean mHeadingLeft = false;

private boolean mHeadingRight = false;



Transform(float speed, float objectWidth,

float objectHeight,

PointF startingLocation) {



mCollider = new RectF();

mSpeed = speed;

mObjectHeight = objectHeight;

mObjectWidth = objectWidth;

mLocation = startingLocation;



// This tells movable blocks their starting position

mStartingPosition = new PointF(

mLocation.x, mLocation.y);

}

}</pre><p>The members should look quite familiar and self-explanatory. We have a RectF to represent the collider (mCollider), PointF instances for the current location and the starting location (mLocation and mStartingPosition), float variables for speed, height, and width (mSpeed, mObjectHeight, and mObjectWidth), and boolean variables for each direction the object could be heading.</p>
<p>In the constructor, all the variables representing position, size, and speed are initialized. All the values come from the method’s parameters. We will see later in the chapter that the GameObjectFactory class will have access to all the specifications needed for a level and will instantiate all the Transform instances by passing the data we have just seen to the Transform constructor. Just as it was in the previous project except this time GameObjectFactory will have more than one type of Transform to choose from.</p>
<p>Code updateCollider and getCollider methods are shown next.</p><pre class="crayon-plain-tag">public void updateCollider() {

mCollider.top = mLocation.y;

mCollider.left = mLocation.x ;

mCollider.bottom =

(mCollider.top + mObjectHeight);



mCollider.right =

(mCollider.left + mObjectWidth);

}





public RectF getCollider() {

return mCollider;

}</pre><p>The updateCollider method uses the position of the object along with its width and height to make sure the collider is up-to-date so that collision detection can be done on its precise position. The getCollider method makes the collider available to the PhysicsEngine class so collision detection can be performed.</p>
<p>Add this bunch of getters and setters shown next.</p><pre class="crayon-plain-tag">void headUp() {

mHeadingUp = true;

mHeadingDown = false;

}



void headDown() {

mHeadingDown = true;

mHeadingUp = false;

}



boolean headingUp() {

return mHeadingUp;

}



boolean headingDown() {

return mHeadingDown;

}



float getSpeed() {

return mSpeed;

}



PointF getLocation() {

return mLocation;

}



PointF getSize() {

return new PointF(

(int) mObjectWidth,

(int) mObjectHeight);

}</pre><p>Although quite a long list the methods we just added are quite simple. They allow the instances of the Transform class to share and set the values of some of its private member variables.</p>
<p>Add these getters and setters next.</p><pre class="crayon-plain-tag">void headRight() {

mHeadingRight = true;

mHeadingLeft = false;

mFacingRight = true;



}



void headLeft() {

mHeadingLeft = true;

mHeadingRight = false;

mFacingRight = false;

}



boolean headingRight() {

return mHeadingRight;

}



boolean headingLeft() {

return mHeadingLeft;

}



void stopHorizontal() {

mHeadingLeft = false;

mHeadingRight = false;

}



void stopMovingLeft() {

mHeadingLeft = false;

}



void stopMovingRight() {

mHeadingRight = false;

}



boolean getFacingRight() {

return mFacingRight;

}



PointF getStartingPosition(){

return mStartingPosition;

}</pre><p>These are the final methods for the Transform class. They make available to get and set, more of the members of the Transform class. Familiarize yourself with the method names and the variables they work with.</p>
<h1>Coding the inanimate and decorative components</h1>
<p>In the previous tutorial, we coded all the interfaces for our component classes. We coded GraphicsComponent, UpdateComponent, and InputComponent. Now we will code the three simplest component classes that will be enough to complete quite a few of our specifications.</p>
<p>Let’s start with the DecorativeBlockUpdateComponent.</p>
<h2>DecorativeBlockUpdateComponent</h2>
<p>The update-related components all implement just one method, update. Add a new class called DecorativeBlockUpdateComponent, implement UpdateComponent and add the empty update method as shown next.</p>
<p>class DecorativeBlockUpdateComponent implements UpdateComponent {</p><pre class="crayon-plain-tag">@Override

public void update(long fps,

Transform t,

Transform playerTransform) {

// Do nothing

// Not even set a collider

}

}</pre><p>Yes, the update method is meant to be empty as the decorative objects don’t move or collide.</p>
<h2>InanmiateBlockGraphicsComponent</h2>
<p>Add a new class called InanimateBlockGraphicsComponent and add the code shown next.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.PointF;

import android.graphics.Rect;



import com.gamecodeschool. platformer.GOSpec.GameObjectSpec;



class InanimateBlockGraphicsComponent

implements GraphicsComponent {



private String mBitmapName;



@Override

public void initialize(Context context,

GameObjectSpec spec,

PointF objectSize,

int pixelsPerMetre) {



mBitmapName = spec.getBitmapName();



BitmapStore.addBitmap(context,

mBitmapName, objectSize,

pixelsPerMetre,

false);



}

}</pre><p>Note the highlighted import might need correcting if you are copying and pasting the class files.</p>
<p>Notice that despite this being a graphics-based component there is no Bitmap object, just a String to hold the name. The class implements the GraphicsComponent interface and therefore must provide the implementation for the initialize and draw methods.</p>
<p>In the code you just added you can see that it receives the required data in the parameters of the initialize method then retrieves the name of the Bitmap from the GameObjectSpec reference.</p>
<p>All the method needs to do is pass all the data on to the addBitmap method of the BitmapStore class and all the work of initializing a Bitmap and storing it for later use (if it hasn’t already) is taken care of by BitmapStore. Just note that the name of the Bitmap is retained in the mBitmapName member variable so InanimateBlockGraphicsComponent can later access the Bitmap again using getBitmap.</p>
<p>Add the draw method to the InanimateBlockGraphicsComponent as shown next.</p><pre class="crayon-plain-tag">@Override

public void draw(Canvas canvas,

Paint paint,

Transform t,

Camera cam) {



Bitmap bitmap = BitmapStore.getBitmap(mBitmapName);

// Use the camera to translate the real world

// coordinates relative to the player-

// into screen coordinates

Rect screenCoordinates = cam.worldToScreen(

t.getLocation().x,

t.getLocation().y,

t.getSize().x,

t.getSize().y);





canvas.drawBitmap(

bitmap,

screenCoordinates.left,

screenCoordinates.top,

paint);





}</pre><p>Inside the draw method, the getBitmap method of the BitmapStore class is used to initialize a local Bitmap object. The Bitmap is drawn to the screen in quite a standard way using drawBitmap but before it is drawn the Camera reference cam is used to get the coordinates at which to draw this game object.</p>
<p>Remember that all game objects have world coordinates. The game objects don’t know or care anything about the device’s screen resolution. The Camera class (in the worldToScreen method) does a calculation based on the position of the camera to translate the object’s world coordinates into appropriate screen coordinates. As we will see later in the chapter, the camera follows the player. So as the player moves through the game world the camera adjusts where on the screen (if anywhere) the game objects get drawn.</p>
<h2>InanimateBlockUpdateComponent</h2>
<p>Now add a new class called InanimateBlockUpdateComponent and code it as follows.</p><pre class="crayon-plain-tag">class InanimateBlockUpdateComponent

implements UpdateComponent {



private boolean mColliderNotSet = true;



@Override

public void update(long fps,

Transform t,

Transform playerTransform) {



// An alternative would be to update

// the collider just once when it spawns.

// But this would require spawn components

// - More code but a bit faster

if(mColliderNotSet) {

// Only need to set the collider

// once because it will never move

t.updateCollider();

mColliderNotSet = false;

}

}

}</pre><p>The class implements UpdateComponent and therefore has an update method. It has one member variable, a boolean called mColliderNotSet. In the update method, the mColliderNotSet boolean is checked to test whether the updateCollider method on the Transform needs to be called. The boolean is then set to false to save a few CPU cycles for the rest of the game. As this object will never move in the game world (although it will move on the screen relative to the camera) this single call to updateCollider is sufficient.</p>
<p>Now we have completed three components we can make some levels that have objects that use these components.</p>
<h1>Creating the levels</h1>
<p>Before we make some levels let’s create another new package to put them in. As a reminder from the previous chapter, when you create a new package, it is important to do so in the correct folder. The correct folder is the same one that we have been putting all the Java files in throughout this book. If you called this project Platformer it will be the app/java/yourdomain.platformer folder.</p>
<p>In the Android Studio project explorer, right-click the app/java/yourdomain.platformer (NOT yourdomain.platformer(androidTest) or yourdomain.platformer(test)), select New | Package and  name it Levels.</p>
<p>The step of creating a package is essential before you can copy and paste the class files.</p>
<p>We will now add some classes that will define all the layout of the levels of the game starting with a generic Level class which all the others can extend.</p>
<p>Don’t add this code yet, just glance at the different letters and numbers in the layouts that will represent different game objects.</p><pre class="crayon-plain-tag">// Backgrounds 1, 2, 3(City, Underground, Mountain...)

// p = Player

// g = Grass tile

// o = Objective

// m = Movable platform

// b = Brick tile

// c = mine Cart

// s = Stone pile

// l = coaL

// n = coNcrete

// a = lAmpost

// r = scoRched tile

// w = snoW tile

// t = stalacTite

// i = stalagmIte

// d = Dead tree

// e = snowy trEe

// x = Collectable

// z = Fire

// y = invisible death_invisible</pre><p>Now let’s see the actual levels comprising the letters and numbers starting with the base class.</p>
<h2>Level</h2>
<p>This class is really short. It will just be used as a polymorphic type, so we can use the extended classes in common code.</p>
<p>Create a new class called Level and add the following code.</p><pre class="crayon-plain-tag">package com.gamecodeschool.c22platformer.Levels;



import java.util.ArrayList;



public abstract class Level {

// If you want to build a new level then extend this class

ArrayList&lt;String&gt; tiles;

public ArrayList&lt;String&gt; getTiles(){

return tiles;

}

}</pre><p>Change the highlighted package statement if copying &amp; pasting</p>
<p>That’s it. It just has an ArrayList called tiles to hold all the game objects and a getter called getTiles which unsurprisingly returns a reference to the ArrayList.</p>
<h2>LevelCity</h2>
<p>We have already seen these next couple of images in the previous chapter. They are shown again here for completeness. Copy the LevelCity file from the Chapter 23/Levels folder of the download bundle. It is not recommended that you try and manually add the code. Paste the file into the Levels folder/package of your project in the Android Studio project explorer window.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b1.png"><img class=" size-full wp-image-16608 aligncenter" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b1.png" alt="B09770_23_b1" width="667" height="375" /></a></p>
<p>This is what the level looks like at the end of the project while the camera is zoomed-out.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b2.png"><img class=" size-full wp-image-16609 aligncenter" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b2.png" alt="B09770_23_b2" width="845" height="224" /></a></p>
<p>Next, add the Montains level.</p>
<h2>LevelMountains</h2>
<p>Copy the LevelMountains file from the Chapter 23/Levels folder of the download bundle. It is not recommended that you try and manually add the code. Paste the file into the Levels folder/package of your project in the Android Studio project explorer window.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b3.png"><img class=" size-full wp-image-16610 aligncenter" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b3.png" alt="B09770_23_b3" width="590" height="404" /></a></p>
<p>This is what the level looks like at the end of the project while the camera is zoomed-out.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b4.png"><img class=" size-full wp-image-16612 aligncenter" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b4.png" alt="B09770_23_b4" width="734" height="258" /></a></p>
<p>Now for the final level.</p>
<h2>LevelUnderground</h2>
<p>Copy the LevelUnderground file from the Chapter 23/Levels folder of the download bundle. It is not recommended that you try and manually add the code. Paste the file into the Levels folder/package of your project in the Android Studio project explorer window.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b5.png"><img class=" size-full wp-image-16611 aligncenter" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b5.png" alt="B09770_23_b5" width="692" height="539" /></a></p>
<p>This is what the level looks like at the end of the project while the camera is zoomed-out.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b6.png"><img class="aligncenter size-full wp-image-16614" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_23_b6.png" alt="B09770_23_b6" width="706" height="264" /></a></p>
<p>I spent quite a bit of time designing and testing the City level. It should be quite challenging and possible to keep replaying and improving on your best time. The Mountains and Underground levels I quickly threw together for the sake of showing how the level structure works and how easy it is to have multiple levels. They are intended as a project for the reader to improve or perhaps start again from scratch.</p>
<h1>Coding a stripped-down GameObjectFactory</h1>
<p>The next step is to code the GameObjectFactory class. This class will look very similar to the class of the same name in the previous project but there will be a few differences that I will point out. We will code just enough in order to build the game objects that are ready to be built and we will revisit this class in the next chapter once we have finished coding all the component classes.</p>
<p>In this and other upcoming classes remember to check that when you import your own classes (everything from the GOSpec package) make sure/change to the correct package name.</p>
<p>Add a new class called GameObjectFactory and add the following member variables and constructor method.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.graphics.PointF;



import com.gamecodeschool.platformer.GOSpec.GameObjectSpec;



class GameObjectFactory {

private Context mContext;

private GameEngine mGameEngineReference;

private int mPixelsPerMetre;



GameObjectFactory(Context context,

GameEngine gameEngine,

int pixelsPerMetre) {



mContext = context;

mGameEngineReference = gameEngine;

mPixelsPerMetre = pixelsPerMetre;

}

}</pre><p>The GameObjectFactory needs three members. A Context and an int with the number of pixels for every meter of the game world so it can pass them to the graphics-related component classes and a GameEngine reference, so it can pass it to any of the input-related component classes, so they can register as observers. These three members (mContext, mGameEnginrReference and mPixelsPerMetre) are initialized in the constructor.</p>
<p>Next, add the create method. We will come back to this method in the next chapter and add more code to the switch block.</p><pre class="crayon-plain-tag">GameObject create(GameObjectSpec spec, PointF location) {

GameObject object = new GameObject();



int mNumComponents = spec.getComponents().length;

object.setTag(spec.getTag());



// First give the game object the

// right kind of transform



switch(object.getTag()){

case "Background":

// Code coming soon

break;



case "Player":

// Code coming soon

break;



default:// normal transform

object.setTransform(new Transform(

spec.getSpeed(),

spec.getSize().x,

spec.getSize().y,

location));

break;

}





// Loop through and add/initialize all the components

for (int i = 0; i &lt; mNumComponents; i++) {

switch (spec.getComponents()[i]) {

case "PlayerInputComponent":

// Code coming soon

break;

case "AnimatedGraphicsComponent":

// Code coming soon

break;

case "PlayerUpdateComponent":

// Code coming soon

break;

case "InanimateBlockGraphicsComponent":

object.setGraphics(new

InanimateBlockGraphicsComponent(),

mContext, spec, spec.getSize(),

mPixelsPerMetre);

break;

case "InanimateBlockUpdateComponent":

object.setMovement(new

InanimateBlockUpdateComponent());

break;

case "MovableBlockUpdateComponent":

// Code coming soon

break;

case "DecorativeBlockUpdateComponent":

object.setMovement(new

DecorativeBlockUpdateComponent());

break;

case "BackgroundGraphicsComponent":

// Code coming soon

break;

case "BackgroundUpdateComponent":

// Code coming soon

break;



default:

// Error unidentified component

break;

}

}



// Return the completed GameObject

// to the LevelManager class

return object;

}</pre><p>First, in the create method a new instance of GameObject is declared and initialized. Just as we did in the previous project we capture the number of components in the current specification and then call the setTag method on the GameObject instance. The GameObject can now be properly identified by a tag.</p>
<p>Next, we see something new compared to the previous GameObjectFactory from the Scrolling Shooter project. We switch based on the tag of the specification. There are three possible case statements that can be executed. One for “Background”, one for “Player” and a default as well.</p>
<p>For now, we just add code to the default option that calls the setTransform method on the GameObject instance and passes in a new Transform reference. In the next chapter we will extend Transform twice to make special versions for the player and the backgrounds. This is how we make sure that every object gets the Transform it needs.</p>
<p>Next, we loop around a for loop once for each component in the specification. And just as we did in the previous project we initialize the appropriate component at each case statement by calling either setGraphics or setMovement on the GameObject instance and passing in a new component of the appropriate type according to the specification.</p>
<p>Also note I have added all the case statements to handle all the other components although most of them are currently empty. This will make it easy to show where the new code goes in the next chapter.</p>
<h1>Coding a slightly commented-out game object</h1>
<p>The game is coming together nicely, and we can now turn our attention to the GameObject class. Much will look familiar to the previous project. Create a class called GameObject and add the following member variables.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.PointF;



import com.gamecodeschool.platformer.GOSpec.GameObjectSpec;



class GameObject {



private Transform mTransform;





private boolean mActive = true;

private String mTag;



private GraphicsComponent mGraphicsComponent;

private UpdateComponent mUpdateComponent;



}</pre><p>Check the highlighted import statement is correct for your project.</p>
<p>The members are almost the same as the previous project except we have an instance of an UpdateComponent replacing an instance of a MovementComponent.</p>
<p>Next, add the following methods which are used to initialize the component-based and Transform instances that we just declared.</p><pre class="crayon-plain-tag">void setGraphics(GraphicsComponent g,

Context c,

GameObjectSpec spec,

PointF objectSize,

int pixelsPerMetre) {



mGraphicsComponent = g;

g.initialize(c, spec, objectSize, pixelsPerMetre);

}



void setMovement(UpdateComponent m) {

mUpdateComponent = m;

}



/*

Uncomment this code soon

void setPlayerInputTransform(PlayerInputComponent s) {

s.setTransform(mTransform);

}

*/



void setTransform(Transform t) {

mTransform = t;

}</pre><p>The methods we just coded are called from GameObjectFactory and pass in the specific instances of the GraphicsComponent, UpdateComponent and Transform.</p>
<p>Notice I have commented out setPlayerInputTransform as we haven’t coded this Transform extended class yet. Commenting it out will enable us to run the project at an earlier opportunity.</p>
<p>Add the rest of the methods to the GameObject class.</p><pre class="crayon-plain-tag">void draw(Canvas canvas, Paint paint, Camera cam) {

mGraphicsComponent.draw(canvas,

paint,

mTransform, cam);

}



void update(long fps, Transform playerTransform) {

mUpdateComponent.update(fps,

mTransform,

playerTransform);

}



boolean checkActive() {

return mActive;

}



String getTag() {

return mTag;

}



void setInactive() {

mActive = false;

}



Transform getTransform() {

return mTransform;

}



void setTag(String tag) {

mTag = tag;

}</pre><p>The code we just added includes the key update and draw methods which are called each frame and the familiar bunch of getter methods for getting data from the GameObject instance.</p>
<h1>Coding the GameState</h1>
<p>The GameState class holds multiple fastest times, and which level is being played. The GameState class also takes care of knowing (and sharing) the current state of paused, playing, drawing, thread running, etc.</p>
<p>Create a new class called GameState and add the member variables and constructor as shown next.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.content.SharedPreferences;



final class GameState {

private static volatile boolean

mThreadRunning = false;



private static volatile boolean mPaused = true;

private static volatile boolean mGameOver = true;

private static volatile boolean mDrawing = false;

private EngineController engineController;



private int mFastestUnderground;

private int mFastestMountains;

private int mFastestCity;

private long startTimeInMillis;



private int mCoinsAvailable;

private int coinsCollected;



private SharedPreferences.Editor editor;



private String currentLevel;



GameState(EngineController gs, Context context) {

engineController = gs;

SharedPreferences prefs = context

.getSharedPreferences("HiScore",

Context.MODE_PRIVATE);



editor = prefs.edit();

mFastestUnderground = prefs.getInt(

"fastest_underground_time", 1000);

mFastestMountains = prefs.getInt(

"fastest_mountains_time", 1000);

mFastestCity = prefs.getInt(

"fastest_city_time", 1000);

}

}</pre><p>We have Boolean variables to represent whether the game thread is running, the player has paused, the game is over or currently drawing. We also have an EngineController reference so GameState can reinitialize a game/level directly.</p>
<p>Next up we have three int variables to hold the fastest time on each of the three levels. The startTimeInMillis variable will be initialized each time a level is attempted to record the time the level was started so it is possible to calculate how long the level took.</p>
<p>There are two more int members to hold the number of coins it is possible to collect in a level and the number of coins actually collected. They are mCoinsAvailable and coinsCollected.</p>
<p>The final two members in the previous code is an instance of SharedPrefferences.Editor for writing new high scores and a String which will represent the current level to be played, City, Underground or Mountains.</p>
<p>Now add this quite a long list of getters and setters to the GameState class.</p>
<p>v</p><pre class="crayon-plain-tag">oid coinCollected() {

coinsCollected++;

}



int getCoinsRemaining() {

return mCoinsAvailable - coinsCollected;

}



void coinAddedToLevel() {

mCoinsAvailable++;

}



void resetCoins() {

mCoinsAvailable = 0;

coinsCollected = 0;

}



void setCurrentLevel(String level) {

currentLevel = level;

}



String getCurrentLevel() {

return currentLevel;

}



void objectiveReached() {

endGame();

}



int getFastestUnderground() {

return mFastestUnderground;

}



int getFastestMountains() {

return mFastestMountains;

}



int getFastestCity() {

return mFastestCity;

}</pre><p>A detailed description of each of the methods we just added would be somewhat laborious because they each do just one thing.</p>
<ul>
<li>Set a value(s)</li>
<li>Return a value</li>
<li>Call another method</li>
</ul>
<p>It is, however, well worth closely inspecting each method’s name to aid understanding as we proceed.</p>
<p>Next, add three more methods to the GameState class for starting a new game, getting the current time, and taking action when the player dies.</p><pre class="crayon-plain-tag">void startNewGame() {

// Don't want to be handling objects while

// clearing ArrayList and filling it up again

stopEverything();

engineController.startNewLevel();

startEverything();

startTimeInMillis = System.currentTimeMillis();

}



int getCurrentTime() {

long MILLIS_IN_SECOND = 1000;

return (int) ((System.currentTimeMillis()

- startTimeInMillis) / MILLIS_IN_SECOND);

}



void death() {

stopEverything();

SoundEngine.playPlayerBurn();

}</pre><p>The startNewGame method calls the stopEverything method. We will code the stopEverything method soon. The next line of code uses the GameController reference to call the startNewLevel method on the GameEngine class. Once the startNewLevel method has done its work we call the startEverything method (which we will code soon) to get things going again. The reason we do these three steps is that otherwise, we will be trying to update and draw objects at the same time as the GameEngine is also deleting and reinitializing them. This would be bound to cause a crash. The last thing we do in startNewGame is initialize the startTimeInMillis variable with the current time.</p>
<p>The getCurrentTime method shares the current time. Note that it takes the start time from the current time and divides the result by one thousand. This is because we want the player to see their time in seconds not milliseconds.</p>
<p>The death method simply calls stopEverything and then uses the SoundEngine to play a death sound.</p>
<p>Now code the endGame method and then we will discuss it.</p><pre class="crayon-plain-tag">private void endGame() {



stopEverything();

int totalTime =

((mCoinsAvailable - coinsCollected)

* 10)

+ getCurrentTime();



switch (currentLevel) {



case "underground":

if (totalTime &lt; mFastestUnderground) {

mFastestUnderground = totalTime;

// Save new time



editor.putInt("fastest_underground_time",

mFastestUnderground);



editor.commit();

}

break;

case "city":

if (totalTime &lt; mFastestCity) {

mFastestCity = totalTime;

// Save new time

editor.putInt("fastest_city_time",

mFastestCity);



editor.commit();

}

break;

case "mountains":

if (totalTime &lt; mFastestMountains) {

mFastestMountains = totalTime;

// Save new time

editor.putInt("fastest_mountains_time",

mFastestMountains);



editor.commit();

}

break;

}

}</pre><p>The first line of code in endGame calls stopEverything so the game engine will halt updating and drawing.</p>
<p>Next, a local variable, totalTime is declared and initialized. The total time (as you might remember from Chapter 22: Platform Game: Bob was in a hurry section) is calculated by the total time the player took added to a penalty for each coin that the player failed to collect.</p>
<p>Next in the endGame method we enter a switch block where the condition is the curremtLevel String. The first case is when the underground level has been played. The code uses an if statement to check if totalTime is less than mFastestUnderground. If it is then the player has a new fastest time. The editor.putInt and editor.commit methods of the SharedPrefferences.Editor instance are then used to save the new record for posterity.</p>
<p>The next two case blocks do the same thing for the city then the mountains levels.</p>
<p>Now code the final methods for the GameState class.</p><pre class="crayon-plain-tag">void stopEverything() {// Except the thread

mPaused = true;

mGameOver = true;

mDrawing = false;

}



private void startEverything() {

mPaused = false;

mGameOver = false;

mDrawing = true;

}



void stopThread() {

mThreadRunning = false;

}



boolean getThreadRunning() {

return mThreadRunning;

}



void startThread() {

mThreadRunning = true;

}



boolean getDrawing() {

return mDrawing;

}



boolean getPaused() {

return mPaused;

}



boolean getGameOver() {

return mGameOver;

}</pre><p>The final getters and setters control when the game engine does certain tasks like start/stop the thread and call update and/or draw. Familiarize yourself with their names and which members they interact with.</p>
<p>Let’s make some noise.</p>
<h1>Code the SoundEngine</h1>
<p>Fortunately, the SoundEngine class holds no surprises. This is essentially the exact same class as we coded in the Scrolling Shooter project. The only exceptions are that we load different sound effects and the methods which play the sound effects have different names and play different sounds. We have also made it a Singleton to avoid the long parameter lists that we had in the previous project when we passed a SoundEngine reference into so many other classes/methods.</p>
<p>Add the following code for the member variables and the getInstance method.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.content.res.AssetFileDescriptor;

import android.content.res.AssetManager;

import android.media.AudioAttributes;

import android.media.AudioManager;

import android.media.SoundPool;

import android.os.Build;



import java.io.IOException;



class SoundEngine {

// for playing sound effects

private static SoundPool mSP;

private static int mJump_ID = -1;

private static int mReach_Objective_ID = -1;

private static  int mCoin_Pickup_ID = -1;

private static  int mPlayer_Burn_ID = -1;



private static SoundEngine ourInstance;



public static SoundEngine getInstance(Context context) {

ourInstance = new SoundEngine(context);

return ourInstance;

}

}</pre><p>The getInstance method provides access to the full functionality of the class as well as calling the constructor method to initialize all the sound effects into a SoundPool. Add the constructor method.</p><pre class="crayon-plain-tag">public SoundEngine(Context c){

// Initialize the SoundPool

if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.LOLLIPOP) {

AudioAttributes audioAttributes =

new AudioAttributes.Builder()

.setUsage(AudioAttributes.USAGE_MEDIA)

.setContentType(AudioAttributes

.CONTENT_TYPE_SONIFICATION)

.build();



mSP = new SoundPool.Builder()

.setMaxStreams(5)

.setAudioAttributes(audioAttributes)

.build();

} else {

mSP = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);

}

try {

AssetManager assetManager = c.getAssets();

AssetFileDescriptor descriptor;



// Prepare the sounds in memory

descriptor = assetManager.openFd("jump.ogg");

mJump_ID = mSP.load(descriptor, 0);



descriptor = assetManager.openFd("reach_objective.ogg");

mReach_Objective_ID = mSP.load(descriptor, 0);



descriptor = assetManager.openFd("coin_pickup.ogg");

mCoin_Pickup_ID = mSP.load(descriptor, 0);



descriptor = assetManager.openFd("player_burn.ogg");

mPlayer_Burn_ID = mSP.load(descriptor, 0);



} catch (IOException e) {

// Error

}

}

Now the sound files are loaded in to memory ready to play. Add the methods that play the sounds, as follows.

public static void playJump(){

mSP.play(mJump_ID,1, 1, 0, 0, 1);

}



public static void playReachObjective(){

mSP.play(mReach_Objective_ID,1, 1, 0, 0, 1);

}



public static void playCoinPickup(){

mSP.play(mCoin_Pickup_ID,1, 1, 0, 0, 1);

}



public static void playPlayerBurn(){

mSP.play(mPlayer_Burn_ID,1, 1, 0, 0, 1);

}</pre><p>These methods are public and static so are accessible from anywhere without an instance of SoundEngine.</p>
<p>Any class can now play any of the sound effects.</p>
<h1>Coding the physics engine (without collision)</h1>
<p>The PhysicsEngine class is responsible, first, for updating all the game objects and secondly for detecting and responding to collisions. This next code handles updating the game objects in the update method and we will code an empty detectCollisions method ready to add more code in Chapter 25.</p>
<p>Add the PhysicsEngine class and then we will discuss the code.</p><pre class="crayon-plain-tag">import android.graphics.PointF;

import android.graphics.RectF;

import java.util.ArrayList;



class PhysicsEngine {



void update(long fps,

ArrayList&lt;GameObject&gt; objects,

GameState gs) {



for (GameObject object : objects) {

object.update(fps,

objects.get(LevelManager.PLAYER_INDEX)

.getTransform());

}



detectCollisions(gs, objects);

}



private void detectCollisions(GameState gs,

ArrayList&lt;GameObject&gt; objects) {

// More code here soon

}

}</pre><p>The update method receives the current frames per second, an ArrayList full of all the GameObject references, and a reference to the current GameState. It then loops through all the GameObject instances calling each and every update method after first checking that the GameObject is active. Finally, the detectCollisions method is called although for now, we have left this method empty.</p>
<h1>Coding a Renderer</h1>
<p>As with many of the classes in this chapter. Renderer will be very similar to the earlier project, so we can zip through it and move on.</p>
<p>Create a new class called Renderer then add the following members and constructor.</p><pre class="crayon-plain-tag">class Renderer {

private Canvas mCanvas;

private SurfaceHolder mSurfaceHolder;

private Paint mPaint;



// Here is our new camera

private Camera mCamera;



Renderer(SurfaceView sh, Point screenSize){

mSurfaceHolder = sh.getHolder();

mPaint = new Paint();



// Initialize the camera

mCamera = new Camera(screenSize.x, screenSize.y);

}

}</pre><p>The Renderer has the Canvas, SurfaceHolder and Paint instances as we have come to expect. It also has a Camera instance called mCamera. We at last get to code the Camera class when we are done with Renderer.</p>
<p>In the constructor, the SurfaceHolder, Paint, and Camera instances are initialized.</p>
<p>Now add the getPixelsPerMetre and draw methods.</p>
<p>i</p><pre class="crayon-plain-tag">nt getPixelsPerMetre(){

return mCamera.getPixelsPerMetre();

}



void draw(ArrayList&lt;GameObject&gt; objects,

GameState gs,

HUD hud) {



if (mSurfaceHolder.getSurface().isValid()) {

mCanvas = mSurfaceHolder.lockCanvas();

mCanvas.drawColor(Color.argb(255, 0, 0, 0));



if(gs.getDrawing()) {

// Set the player as the center of the camera

mCamera.setWorldCentre(

objects.get(LevelManager

.PLAYER_INDEX)

.getTransform().getLocation());



for (GameObject object : objects) {

if (object.checkActive()) {

object.draw(mCanvas, mPaint,

mCamera);

}

}

}



hud.draw(mCanvas, mPaint, gs);



mSurfaceHolder.unlockCanvasAndPost(mCanvas);

}

}</pre><p>The getPixelsPerMetre method uses the instance of the Camera class to return the number of pixels that represent a virtual meter in the game world. We will code the Camera class including this method next.</p>
<p>The code in the draw method prepares the surface, checks it is currently OK to draw then sets the camera to whatever the player’s location is using the setWorldCentre method. We will code the Camera class including this method next. Then the code loops through all the objects checking which ones are active and drawing them. Then the HUD is drawn and the now familiar unlockCanvasAndPost method is called.</p>
<h1>Coding the camera</h1>
<p>This class is completely new to this project. The key to understanding it is to remember that all our game objects have sizes and positions in virtual meters. All the movement and collision detection will be done using these virtual meters. Here is the key-key point:</p>
<p>These virtual meters currently bare no relation to the pixels on the screen. The Camera class will know the screen’s resolution and translate these virtual meters into pixel coordinates. Not all game objects will be on the screen every frame. In fact, most game objects will not be visible, most frames.</p>
<p>Add a new class called Camera and add the following member variables and the constructor.</p><pre class="crayon-plain-tag">import android.graphics.PointF;

import android.graphics.Rect;



class Camera {



private PointF mCurrentCameraWorldCentre;

private Rect mConvertedRect;

private int mPixelsPerMetre;

private int mScreenCentreX;

private int mScreenCentreY;



Camera(int screenXResolution, int screenYResolution){

// Locate the centre of the screen

mScreenCentreX = screenXResolution / 2;

mScreenCentreY = screenYResolution / 2;



// How many metres of world space does

// the screen width show

// Change this value to zoom in and out

final int pixelsPerMetreToResolutionRatio = 48;

mPixelsPerMetre = screenXResolution /

pixelsPerMetreToResolutionRatio;



mConvertedRect = new Rect();

mCurrentCameraWorldCentre = new PointF();

}</pre><p>There are five, member variables as follows:</p>
<ul>
<li>The PointF mCurrentCameraWorldCentre instance will hold the central position (in virtual meters) the camera is centered on. This will be updated each frame and is the same as the position of the player.</li>
<li>The Rect mConvertedRect instance will hold the four converted points that have been translated from virtual meters to pixel coordinates. This is the Rect that will be used by all the graphics-related component classes in their draw methods when they call drawBitmap. Look back to the InanimateBlockGraphicsComponent section if you want to confirm this.</li>
<li>The int mPixelsPerMetre member is the number of pixels on the screen that represent one virtual metre.</li>
<li>The int mScreenCentreX member is the pixel coordinate of the central pixel, horizontally on the screen.</li>
<li>The int mScreenCentreY member is the pixel coordinate of the central pixel, horizontally on the screen.</li>
</ul>
<p>It is the way we calculate and combine these five values that makes the class do its magic.</p>
<p>Next, add the following getters and setters to the class.</p><pre class="crayon-plain-tag">int getPixelsPerMetreY(){

return mPixelsPerMetre;

}



int getyCentre(){

return mScreenCentreY;

}



float getCameraWorldCentreY(){

return mCurrentCameraWorldCentre.y;

}



// Set the camera to the player. Called each frame

void setWorldCentre(PointF worldCentre){

mCurrentCameraWorldCentre.x  = worldCentre.x;

mCurrentCameraWorldCentre.y  = worldCentre.y;

}



int getPixelsPerMetre(){

return mPixelsPerMetre;

}</pre><p>Four out of five of those methods simply return a value/reference to one of the members. We will see where they are used as we proceed. The setWorldCentre method however is more interesting. It receives a PointF reference as a parameter. The setWorldCentre method is called after the update method but before the draw method by GameEngine on every frame. The PointF that is passed in is the position of the Bob in the game world (in virtual metres).</p>
<p>This next method is the meat of the whole class and it uses all the members and the position of Bob to translate virtual metres into pixels. Notice that it receives the object’s horizontal and vertical positions (in virtual metres) as well as the objects width and height (also in virtual metres). Also notice it returns a Rect so that each game object’s graphics-related component class can use it in the call to drawBitmap. Add the worldToScreen method and then we will examine its body.</p><pre class="crayon-plain-tag">// Return a Rect of the screen coordinates

// relative to a world location

Rect worldToScreen(float objectX,

float objectY,

float objectWidth,

float objectHeight){



int left = (int) (mScreenCentreX -

((mCurrentCameraWorldCentre.x - objectX)

* mPixelsPerMetre));



int top =  (int) (mScreenCentreY -

((mCurrentCameraWorldCentre.y - objectY)

* mPixelsPerMetre));



int right = (int) (left + (objectWidth

* mPixelsPerMetre));



int bottom = (int) (top + (objectHeight

* mPixelsPerMetre));



mConvertedRect.set(left, top, right, bottom);



return mConvertedRect;

}</pre><p>Let’s go through the body a line at a time. The first line of code declares and initializes a local int variable called left.</p><pre class="crayon-plain-tag">int left = (int) (mScreenCentreX -

((mCurrentCameraWorldCentre.x - objectX)

* mPixelsPerMetre));</pre><p>The initialization code uses a cast, (int), to convert the float result to int. The calculation subtracts the objects horizontal position from the current focus of the camera which in turn is subtracted from the central horizontal pixel position. By multiplying the result by mPixelsPerMetre the world (virtual meter) positions are now a pixel coordinate. Note that at this stage we have only calculated the horizontal pixel position of one of four points.</p>
<p>This next line of code does the same thing except using the vertical values of the screen center, world center and object position.</p><pre class="crayon-plain-tag">int top =  (int) (mScreenCentreY -

((mCurrentCameraWorldCentre.y - objectY)

* mPixelsPerMetre));</pre><p>The next two lines of code use left then top in conjunction with the width and height (respectively) to calculate the right and bottom pixel coordinates (respectively).</p><pre class="crayon-plain-tag">int right = (int) (left + (objectWidth

* mPixelsPerMetre));



int bottom = (int) (top + (objectHeight

* mPixelsPerMetre));</pre><p>Let’s invent some hypothetical positions for the player and an example object so we can see those calculations in action.</p>
<p>Suppose that the player is at (top left corner) the world location of 120 virtual meters horizontally and 90 meters vertically. The player is 1 meter wide and 2 meters tall. There is a platform at the world location of 116 meters horizontally and 89 meters vertically. The platform is 1 meter by 1 meter in size. If our calculations are to do their job, then they need to convert these sizes and positions into screen coordinates where the platform is to the left of the player by four times as much as it is above the player. This exercise will assume the screen is 1920 pixels wide by 1080 pixels high. First let’s calculate the player’s pixel coordinates.</p>
<h2>Testing the formulas with hypothetical coordinates</h2>
<p>The formula for the player’s left (in English not in code) is as follows:</p>
<p>Remember that the world camera center coordinates are the same as the player’s top-left coordinates and are updated each frame after update but before draw is called.</p>
<p>We can see that the left of the player is drawn in the horizontal center of the screen, 960 pixels.</p>
<p>Now for the top variable using the player’s world coordinates.</p>
<p>We can now see that the player’s top-left coordinates on the screen is 960, 540. This is the center of a 1920 x 1080 screen. Wherever in the game world the player moves, because mCameraCurrentWorldCentre is updated with each frame, the player stays in the center of the screen.</p>
<p>Let’s look quickly at how the right and bottom values are calculated and then we can run the hypothetical platform coordinates through the same formulas.</p>
<p>Here is the formula for the right variable.</p>
<p>The bottom calculation uses the following formula:</p>
<p>The rectangle representing where Bob will be drawn will be at the following pixel coordinates:</p>
<p>Left: 960, Top: 540, Bottom: 1048, Right: 636.</p>
<p>The formula for the block’s left (in English not in code) is as follows:</p>
<p>&nbsp;</p>
<p>We can see that the left of the block is drawn in the horizontal center of the screen, 960 pixels.</p>
<p>Now for the top variable using the block’s world coordinates.</p>
<p>Let’s look quickly at how the right and bottom values are calculated. Here is the formula for the right variable.</p>
<p>Left pixel coordinate + (width in meters * pixels per meter)</p>
<p>The bottom calculation uses the following formula:</p>
<p>The rectangle representing where the block will be drawn will be at the following pixel coordinates:</p>
<p>Left: 960, Top: 540, Bottom: 1048, Right: 636.</p>
<p>Look closely at the results for converting the player’s and the other object’s world coordinates and you can see that they are within the scope of being able to accept them as correct. When we see hundreds of objects all neatly drawn in exactly the right place it will be certain the formulas work.</p>
<p>Finally, mConvertedRect is initialized with the four values using the set method and then returned to the calling code.</p><pre class="crayon-plain-tag">mConvertedRect.set(left, top, right, bottom);

return mConvertedRect;</pre><p>Try making up some more hypothetical object positions and calculating their pixel positions. Try some values that are some distance away (perhaps 50 meters) and notice how they are at a position that will not be seen on screen.</p>
<p>Now we have a system for converting all the floating-point world positions into integer pixel positions we can turn our attention to the HUD class.</p>
<h1>Coding the Hud</h1>
<p>The HUD in this game is no more complex than the previous game. We will define some Rect instances to draw the controls on the screen, we will rely on GameState to provide the time and fastest times for each level and we will make the button Rect ArrayList available so that GameEngine can pass then them to our two classes that require them to handle the player’s input.</p>
<p>Get started by adding a new class called HUD and add the following members and constructor method.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Point;

import android.graphics.Rect;



import java.util.ArrayList;



class HUD {

private Bitmap mMenuBitmap;



private int mTextFormatting;

private int mScreenHeight;

private int mScreenWidth;

final float ONE_THIRD = .33f;

final float TWO_THIRDS = .66f;



private ArrayList&lt;Rect&gt; mControls;



static int LEFT = 0;

static int RIGHT = 1;

static int JUMP = 2;



HUD(Context context, Point size){

mScreenHeight = size.y;

mScreenWidth = size.x;

mTextFormatting = size.x / 25;



prepareControls();



// Create and scale the bitmaps

mMenuBitmap = BitmapFactory

.decodeResource(context.getResources(),

R.drawable.menu);



mMenuBitmap = Bitmap

.createScaledBitmap(mMenuBitmap,

size.x, size.y, false);



}

}</pre><p>The class starts off with five members that we will use to control position and formatting of the parts of the HUD. Next there is an ArrayList for our Rect buttons and next there is the static variables LEFT, RIGHT and JUMP which the UIController (that we code next) and PlayerInputComponent (that we code next chapter) can use to identify what the player is trying to do.</p>
<p>In the constructor we initialize some of our formatting variables using the passed in screen resolution, call the prepareControls method and load and scale the Bitmap that is used for the menu background.</p>
<p>Now we can code the prepareControls method that we just called.</p><pre class="crayon-plain-tag">private void prepareControls(){

int buttonWidth = mScreenWidth / 14;

int buttonHeight = mScreenHeight / 12;

int buttonPadding = mScreenWidth / 90;





Rect left = new Rect(

buttonPadding,

mScreenHeight - buttonHeight - buttonPadding,

buttonWidth + buttonPadding,

mScreenHeight - buttonPadding);



Rect right = new Rect(

(buttonPadding * 2) + buttonWidth,

mScreenHeight - buttonHeight - buttonPadding,

(buttonPadding * 2) + (buttonWidth * 2),

mScreenHeight - buttonPadding);



Rect jump = new Rect(mScreenWidth - buttonPadding

- buttonWidth,

mScreenHeight - buttonHeight - buttonPadding,

mScreenWidth - buttonPadding,

mScreenHeight - buttonPadding);





mControls = new ArrayList&lt;&gt;();

mControls.add(LEFT,left);

mControls.add(RIGHT,right);

mControls.add(JUMP, jump);

}</pre><p>In the previous code, we initialize our remaining formatting members relative to the screen resolution in pixels. We then use them to position our three Rect objects that represent the buttons and then add them to the mControls ArrayList.</p>
<p>Next, add the draw method which just like the HUD in the previous project will be called each frame of the game to draw the HUD. Notice the usual suspects are passed in as parameters to enable the method to do its job.</p><pre class="crayon-plain-tag">void draw(Canvas c, Paint p, GameState gs){



if(gs.getGameOver()){



// Draw the mMenuBitmap screen

c.drawBitmap(mMenuBitmap, 0,0, p);



// draw a rectangle to highlight the text

p.setColor(Color.argb (100, 26, 128, 182));

c.drawRect(0,0, mScreenWidth,

mTextFormatting * 4, p);



// Draw the level names

p.setColor(Color.argb(255, 255, 255, 255));

p.setTextSize(mTextFormatting);

c.drawText("Underground",

mTextFormatting,

mTextFormatting * 2,

p);



c.drawText("Mountains",

mScreenWidth * ONE_THIRD

+ (mTextFormatting),

mTextFormatting * 2,

p);



c.drawText("City",

mScreenWidth * TWO_THIRDS

+ (mTextFormatting),

mTextFormatting * 2,

p);



// Draw the fastest times

p.setTextSize(mTextFormatting/1.8f);



c.drawText("BEST:" + gs.getFastestUnderground()

+" seconds",

mTextFormatting,

mTextFormatting*3,

p);



c.drawText("BEST:" + gs.getFastestMountains()

+" seconds", mScreenWidth * ONE_THIRD

+ mTextFormatting,

mTextFormatting * 3,

p);



c.drawText("BEST:" + gs.getFastestCity()

+ " seconds",

mScreenWidth * TWO_THIRDS + mTextFormatting,

mTextFormatting * 3,

p);



// draw a rectangle to highlight the large text

p.setColor(Color.argb (100, 26, 128, 182));

c.drawRect(0,mScreenHeight - mTextFormatting * 2,

mScreenWidth,

mScreenHeight,

p);



p.setColor(Color.argb(255, 255, 255, 255));

p.setTextSize(mTextFormatting * 1.5f);

c.drawText("DOUBLE TAP A LEVEL TO PLAY",

ONE_THIRD + mTextFormatting * 2,

mScreenHeight - mTextFormatting/2,

p);

}

// else block follows next



}</pre><p>The method is long and might seem complicated at first glance but there is nothing we haven’t seen before. There is one thing to note, however. All the code is wrapped in an if block with a condition of gs.getGameOver. So, all the code we just added runs when the game is over. We will add the else block which follows this if block in a moment.</p>
<p>The code inside the if block draws the background, level names, and fastest times as well as the message to tell the player how to start the game. Clearly, we don’t want these things on the screen while the game is being played.</p>
<p>Still, inside the draw method add the else block that follows the if block which will execute while the game is being played.</p><pre class="crayon-plain-tag">...

// else block follows next

else {

// draw a rectangle to highlight the text

p.setColor(Color.argb (100, 0, 0, 0));

c.drawRect(0,0, mScreenWidth,

mTextFormatting,

p);



// Draw the HUD text

p.setTextSize(mTextFormatting/1.5f);

p.setColor(Color.argb(255, 255, 255, 255));

c.drawText("Time:" + gs.getCurrentTime()

+ "+" + gs.getCoinsRemaining() * 10,

mTextFormatting / 4,

mTextFormatting / 1.5f,

p);





drawControls(c, p);

}</pre><p>In the else block, we draw a transparent rectangle across the top of the screen which has the effect of highlighting the text that is drawn on top of it. Then we draw the current time. The slightly convoluted formula (gs.getCoinsRemaining() * 10) has the effect of calculating (and displaying) the time penalty based on how many coins the player still needs to collect. The final line of code in the draw method (but still inside the else block) calls the drawControls method. This is separated out purely to stop the method getting any longer than it already is.</p>
<p>Here are the final two methods of the HUD class. Add the drawControls and getControls method.</p><pre class="crayon-plain-tag">private void drawControls(Canvas c, Paint p){

p.setColor(Color.argb(100,255,255,255));



for(Rect r : mControls){

c.drawRect(r.left, r.top, r.right, r.bottom, p);

}



// Set the colors back

p.setColor(Color.argb(255,255,255,255));

}





ArrayList&lt;Rect&gt; getControls(){

return mControls;

}</pre><p>The drawControls method loops through the mControls ArrayList and draws each button as a transparent rectangle. The getControls method simply returns a reference to mControls. GameEngine will use this method to pass mControls to the other classes that need it.</p>
<h1>Coding the UIController class</h1>
<p>This class will have the same purpose as the class of the same name did in the previous project. It will also look very similar too.</p>
<p>Add a new class called UIController and add the member variables, constructor and addObserver method.</p>
<p>i</p><pre class="crayon-plain-tag">mport android.graphics.Point;

import android.graphics.Rect;

import android.view.MotionEvent;



import java.util.ArrayList;



class UIController implements InputObserver {



private float mThird;



private boolean initialPress = false;



UIController(GameEngineBroadcaster b, Point size) {

// Add as an observer

addObserver(b);



mThird = size.x / 3;

}





void addObserver(GameEngineBroadcaster b) {

b.addObserver(this);

}

}</pre><p>The float mThird variable will help us to divide the screen up vertically into thirds. The player will then be able to tap a portion of the screen to choose the level that they want to play. The initialPress Boolean is used in a workaround to avoid a bug/glitch. Sometimes when the game ends the menu will immediately register the player’s touch causing a new level to start instantly rather than allowing them to view the menu screen at their leisure. By ignoring the very first touch we avoid this problem.</p>
<p>This is a hack and not a good solution to go into a finished game. Unfortunately, the solution would require at least another chapter and I am running out of space. In chapter 26 I suggest some resources to continue your learning. Be sure to look into the State pattern to improve all the projects and as a solution for this hack.</p>
<p>In the constructor, we call the addObserver method and initialize the mThird variable to a third of the screen’s width. In the addObserver method the code uses the GameEngineBroadcaster reference to add an observer to GameEngine.</p>
<p>We need to add an observer each time a new game is started, and the game objects are rebuilt because the observer list is cleared. The addObserver method allows us to re-add an observer rather than just add it in the constructor.</p>
<p>Now add the handleInput method which receives the MotionEvent, the GameState and the ArrayList which contains the button positions.</p><pre class="crayon-plain-tag">@Override

public void handleInput(MotionEvent event,

GameState gameState,

ArrayList&lt;Rect&gt; buttons) {



int i = event.getActionIndex();

int x = (int) event.getX(i);



int eventType = event.getAction()

&amp; MotionEvent.ACTION_MASK;



if (eventType == MotionEvent.ACTION_UP ||

eventType == MotionEvent.ACTION_POINTER_UP) {



// If game is over start a new game

if (gameState.getGameOver() &amp;&amp; initialPress) {



if (x &lt; mThird) {

gameState.setCurrentLevel("underground");

gameState.startNewGame();

} else if (x &gt;= mThird &amp;&amp; x &lt; mThird * 2) {

gameState.setCurrentLevel("mountains");

gameState.startNewGame();

} else if (x &gt;= mThird * 2) {

gameState.setCurrentLevel("city");

gameState.startNewGame();

}

}

initialPress = !initialPress;

}

}</pre><p>As we did in the previous project we handle input by accessing the event at the index which triggered the current action. There is an if – else if – else if structure where the code detects which level was pressed. These are the only touches that need to be handled. The buttons will be handled by the PlayerController component class. After an ACTION_UP has been detected, notice also that the rest of the code is wrapped in an if condition that tests whether the game is over and initialPress is false. Outside this structure, all ACTION_UP events will switch the value of initialPress. This means that the last stray touch of game-play won’t dismiss the menu screen as soon as it starts.</p>
<h1>Code the Activity</h1>
<p>This class is just like the one we have been coding for virtually the entire book. Take a look at the code and then add this class to your project.</p><pre class="crayon-plain-tag">import android.app.Activity;

import android.graphics.Point;

import android.os.Bundle;

import android.view.Display;



public class GameActivity extends Activity {



GameEngine mGameEngine;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);



Display display = getWindowManager()

.getDefaultDisplay();



Point size = new Point();

display.getSize(size);

mGameEngine = new GameEngine(this, size);

setContentView(mGameEngine);

}



@Override

protected void onResume() {

super.onResume();

mGameEngine.startThread();

}



@Override

protected void onPause() {

super.onPause();

mGameEngine.stopThread();

}

}</pre><p>Everything is very familiar except you can see that I have renamed the resume and pause methods of the GameEngine class to startThread and stopThread respectively.</p>
<p>Now we can code the GameEngine class (including startThread and stopThread) and we will then be one small step away from running our hard work from the last two chapters.</p>
<h1>How to Code the GameEngine</h1>
<p>Now we get to the class that glues all the others together. In the code that follows we will declare and use an instance of LevelManager that we will code immediately after GameEngine. All the rest of the code will, at last, be error-free and nearly ready to execute.</p>
<p>Add the GameEngine class, its members, and the constructor as shown next.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.graphics.Point;

import android.util.Log;

import android.view.MotionEvent;

import android.view.SurfaceView;



import java.util.concurrent.CopyOnWriteArrayList;



class GameEngine extends SurfaceView

implements Runnable,

GameEngineBroadcaster,

EngineController {



private Thread mThread = null;

private long mFPS;



private GameState mGameState;

UIController mUIController;



// This ArrayList can be accessed from either thread

private CopyOnWriteArrayList&lt;InputObserver&gt;

inputObservers = new CopyOnWriteArrayList();



HUD mHUD;

LevelManager mLevelManager;

PhysicsEngine mPhysicsEngine;

Renderer mRenderer;



public GameEngine(Context context, Point size) {

super(context);

// Prepare the bitmap store and sound engine

BitmapStore bs = BitmapStore.getInstance(context);

SoundEngine se = SoundEngine.getInstance(context);



// Initialize all the significant classes

// that make the engine work

mHUD = new HUD(context, size);

mGameState = new GameState(this, context);

mUIController = new UIController(this, size);

mPhysicsEngine = new PhysicsEngine();

mRenderer = new Renderer(this, size);

mLevelManager = new LevelManager(context,

this, mRenderer.getPixelsPerMetre());



}

}</pre><p>There are a few new things happening in the code you just saw. First notice that we need to import the CopyOnWriteArrayList class. This is a version of the ArrayList class that works simultaneously on multiple threads without crashing the game. This structure will be used to hold the InputObservers. CopyOnWriteArrayList is slower than the regular ArrayList class but as it is holding just two items that are accessed infrequently (compared to the GameObject instances) it won’t cause a performance issue. The GameObject instances will be held in a regular ArrayList.</p>
<p>Notice as usual we have the members such as mThread and mFPS for our main game loop and measuring the frames per second. We also declare instances for many of the classes we have been slaving over for the past two chapters.</p>
<p>In the constructor, we initialize all the instances. Look at the way we initialize our two Singletons (BitmapStore and SoundEngine) using the getInstance method. The other initializations are just as we have seen before and should expect based on the classes we have been coding. The exception is the instance of LevelManager. Look at the parameters we pass in, a Context, this, and the number of pixels per meter (supplied by the Renderer class). We will see how we put all these things into action shortly. Let’s finish the GameEngine class.</p>
<p>Code the startNewLevel method and the addObserver method.</p><pre class="crayon-plain-tag">public void startNewLevel() {

// Clear the bitmap store

BitmapStore.clearStore();

// Clear all the observers and add the UI observer back

// When we call buildGameObjects the

// player's observer will be added too

inputObservers.clear();

mUIController.addObserver(this);

mLevelManager.setCurrentLevel(mGameState.getCurrentLevel());

mLevelManager.buildGameObjects(mGameState);

}



// For the game engine broadcaster interface

public void addObserver(InputObserver o) {

inputObservers.add(o);

}</pre><p>First, the static method Bitmap.clearStore is used to make sure there are no Bitmap instances already in the store. Then, the inputObservers ArrayList is cleared. The reason we need to do this each new game/level attempt is because each call to buildGameObjects deletes any existing game objects and rebuilds new ones to suit the current level. This includes the player that will be composed of a PlayerInputController component class that will have registered as an input observer. Therefore, if we leave the old input observers in the ArrayList then there will be a reference to an object which doesn’t exist. Calling it will cause an instant crash.</p>
<p>After we have cleared the observers for the reason just stated we then need to add the UIController instance’s observer by calling addObserver. The UIController instance remains the same throughout the life of the application but we must add it to each level of course because we have just cleared it.</p>
<p>To end the method, we call the setCurrentLevel and buildGameObjects methods of the soon-to-be-coded LevelManager class.</p>
<p>The addObserver method allows the InputObservers to register themselves and be added to the inputObservers ArrayList.</p>
<p>Next, add the run method.</p><pre class="crayon-plain-tag">@Override

public void run() {

while (mGameState.getThreadRunning()) {



long frameStartTime = System.currentTimeMillis();



if (!mGameState.getPaused()) {

mPhysicsEngine.update(mFPS,

mLevelManager.getGameObjects(),

mGameState);

}



mRenderer.draw(mLevelManager.getGameObjects(),

mGameState,

mHUD);



long timeThisFrame = System.currentTimeMillis()

- frameStartTime;



if (timeThisFrame &gt;= 1) {

final int MILLIS_IN_SECOND = 1000;

mFPS = MILLIS_IN_SECOND / timeThisFrame;

}

}

}</pre><p>Most of this we have seen before, but this is what happens in run, step by step:</p>
<ul>
<li>The current time is stored in frameStartTime.</li>
<li>If the game is not currently paused, then the PhysicsEngine instance’s update method is called.</li>
<li>The Renderer instance’s draw method is called</li>
<li>The amount of time that the previous two steps took is calculated and stored in timeThisFrame</li>
<li>The current frame rate is calculated and stored in mFPS ready for use during the next frame of the game loop.</li>
</ul>
<p>&nbsp;</p>
<p>Add the onTouchEvent method along with the stopThread and startThread methods.</p><pre class="crayon-plain-tag">@Override

public boolean onTouchEvent(MotionEvent motionEvent) {

for (InputObserver o : inputObservers) {

o.handleInput(motionEvent,

mGameState,

mHUD.getControls());

}

return true;

}



public void stopThread() {

mGameState.stopEverything();

mGameState.stopThread();

try {

mThread.join();

} catch (InterruptedException e) {

Log.e("Exception",

"stopThread()" + e.getMessage());

}

}



public void startThread() {

mGameState.startThread();

mThread = new Thread(this);

mThread.start();

}</pre><p>The onTouchEvent method loops through all the registered observers calling their handleInput method.</p>
<p>The stopThread method stops the thread (and everything else) via the GameState instance.</p>
<p>The startThread method starts the thread using the GameState instance.</p>
<p>Now we can move on to the final class for this chapter.</p>
<h1>Coding the LevelManager class</h1>
<p>We are nearly there. Coding this class will leave us with an executable project!</p>
<p>Create a new class called LevelManager and add the following members and the constructor.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.graphics.PointF;

import android.util.Log;



import com.gamecodeschool.platformer.GOSpec.*;

import com.gamecodeschool.platformer.Levels.*;



import java.util.ArrayList;



final class LevelManager {



static int PLAYER_INDEX = 0;

private ArrayList&lt;GameObject&gt; objects;

private Level currentLevel;

private GameObjectFactory factory;



LevelManager(Context context,

GameEngine ge,

int pixelsPerMetre){



objects = new ArrayList&lt;&gt;();

factory = new GameObjectFactory(context,

ge,

pixelsPerMetre);

}</pre><p>First, be aware of the two highlighted import statements that will need checking/correcting to your full package name.</p>
<p>We can tell we are getting close because we have declared the ArrayList that will hold all the GameObject instances (objects) and an instance of GameObjectFactory that will build them all.</p>
<p>We also have an instance of Level called currentLevel ready to be filled up with all the alpha-numeric characters that represent our level designs. The other member, PLAYER_INDEX is static and will help us insure that we keep a check on the position of the player in the objects ArrayList. In the constructor, objects and factory are initialized.</p>
<p>Add the setCurrentLevel method.</p><pre class="crayon-plain-tag">void setCurrentLevel(String level){

switch (level) {

case "underground":

currentLevel = new LevelUnderground();

break;



case "city":

currentLevel = new LevelCity();

break;



case "mountains":

currentLevel = new LevelMountains();

break;

}

}

}</pre><p>This method allows the UIController class to change the current level by passing in a String which the code in the method body uses to create a new Level reference of one of the extended classes (LevelUnderground, LevelCity or LevelMountains).</p>
<p>The next code is long but not difficult. We glimpsed some of it (the comments) before in the earlier section Create the levels. Very similar to previous project it just adds a case to create the appropriate type of object based on the alpha-numeric character that is returned by the nested for loops which go through the level design a character at a time. Objects that aren’t available yet are commented out for later convenience.</p>
<p>Add the buildGameObjects method.</p><pre class="crayon-plain-tag">void buildGameObjects(GameState gs){

// Backgrounds 1, 2, 3(City, Underground, Mountain...)

// p = Player

// g = Grass tile

// o = Objective

// m = Movable platform

// b = Brick tile

// c = mine Cart

// s = Stone pile

// l = coaL

// n = coNcrete

// a = lAmpost

// r = scoRched tile

// w = snoW tile

// t = stalacTite

// i = stalagmIte

// d = Dead tree

// e = snowy trEe

// x = Collectable

// z = Fire

// y = invisible death_invisible



gs.resetCoins();

objects.clear();

ArrayList&lt;String&gt; levelToLoad = currentLevel.getTiles();



for(int row = 0; row &lt; levelToLoad.size(); row++ )

{

for(int column = 0;

column &lt; levelToLoad.get(row).length();

column++){



PointF coords = new PointF(column, row);



switch (levelToLoad.get(row)

.charAt(column)){



case '1':

//objects.add(factory.create(

// new BackgroundCitySpec(),

// coords));

break;



case '2':

//objects.add(factory.create(

// new BackgroundUndergroundSpec(),

// coords));

break;



case '3':

//objects.add(factory.create(

// new BackgroundMountainSpec(),

// coords));

break;



case 'p':

//objects.add(factory.create(new

// PlayerSpec(),

// coords));

// Remember the location of

// the player

//PLAYER_INDEX = objects.size()-1;

break;



case 'g':

objects.add(factory.create(

new GrassTileSpec(),

coords));

break;



case 'o':

objects.add(factory.create(

new ObjectiveTileSpec(),

coords));

break;



case 'm':

//objects.add(factory.create(

// new MoveablePlatformSpec(),

// coords));

break;



case 'b':

objects.add(factory.create(

new BrickTileSpec(),

coords));

break;



case 'c':

objects.add(factory.create(

new CartTileSpec(),

coords));

break;



case 's':

objects.add(factory.create(

new StonePileTileSpec(),

coords));

break;



case 'l':

objects.add(factory.create(

new CoalTileSpec(),

coords));

break;



case 'n':

objects.add(factory.create(

new ConcreteTileSpec(),

coords));

break;



case 'a':

objects.add(factory.create(

new LamppostTileSpec(),

coords));

break;



case 'r':

objects.add(factory.create(

new ScorchedTileSpec(),

coords));

break;



case 'w':

objects.add(factory.create(

new SnowTileSpec(),

coords));

break;



case 't':

objects.add(factory.create(

new StalactiteTileSpec(),

coords));

break;



case 'i':

objects.add(factory.create(

new StalagmiteTileSpec(),

coords));

break;



case 'd':

objects.add(factory.create(

new DeadTreeTileSpec(),

coords));

break;



case 'e':

objects.add(factory.create(

new SnowyTreeTileSpec(),

coords));

break;



case 'x':

objects.add(factory.create(

new CollectibleObjectSpec(),

coords));

gs.coinAddedToLevel();

break;



case 'z':

//objects.add(factory.create(

// new FireTileSpec(),

// coords));



break;



case 'y':

objects.add(factory.create(

new

InvisibleDeathTenByTenSpec(),

coords));



break;





case '.':

// Nothing to see here

break;



default:

Log.e("Unhandled item in level",

"row:"+row

+ " column:"+column);

break;

}



}



}



}</pre><p>&nbsp;</p>
<p>Each case starts with objects.add… and then calls the create method of the GameObjectFactory instance passing in the specification class of the new object to create and the coordinates at which to create it. The GameObjectFactory class returns the newly created object of the desired type and it is added to the objects ArrayList. All the specifications where we haven’t yet coded all the component classes are commented out to avoid errors/crashes.</p>
<p>Add the final method to the LevelManager class.</p><pre class="crayon-plain-tag">ArrayList&lt;GameObject&gt; getGameObjects(){

return objects;

}</pre><p>This method returns a reference to the ArrayList that holds all the GameObject instances. You might remember this was called from the main game loop (run method) in the GameEngine class.</p>
<h1>Running the game</h1>
<p>If you execute the game, you will see the menu.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09779_23_03.png"><img class="aligncenter size-full wp-image-16617" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09779_23_03.png" alt="B09779_23_03" width="1210" height="580" /></a></p>
<p>The menu allows you to start each of the three levels. But as there is currently no way to complete or fail a level you will need to quit the game and restart it if you want to see the progress on all three.</p>
<p>This is the City level so far.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09779_23_04.png"><img class="aligncenter size-full wp-image-16618" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09779_23_04.png" alt="B09779_23_04" width="1072" height="534" /></a></p>
<p>This is the Underground level so far.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09779_23_05.png"><img class="aligncenter size-full wp-image-16619" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09779_23_05.png" alt="B09779_23_05" width="1088" height="512" /></a></p>
<p>This is the Mountains level so far.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09779_23_06.png"><img class="aligncenter size-full wp-image-16620" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09779_23_06.png" alt="B09779_23_06" width="1072" height="515" /></a></p>
<p>Note the camera is centered around 0,0 because PLAYER_INDEX equals zero and the first object in the objects ArrayList is at 0,0. You could count the characters in the level designs and then change PLAYER_INDEX in the LevelManager class to equal this number. Then the camera will focus on it and you can see more of each level when you run the game. When the player is added to the game the camera will center around Bob.</p>
<h1>Summary</h1>
<p>That was a big chapter, but much was achieved. We were introduced to the Java HashMap class and the Singleton pattern which together enabled us to code the BitmapStore class to save memory by avoiding duplicate copies of Bitmap instances. We coded the component classes for all the platforms that Bob will walk on as well as the decorative component classes that will handle things like trees and stalagmites.</p>
<p>We coded a new GameObjectFactory that was like the previous project except it handles multiple different types of Transform. We saw and added the code for the level designs. They are represented by extending a parent Level class.</p>
<p>We also coded the slightly familiar GameObject, GameState, SoundEngine, PhysicsEngine, and Renderer classes.</p>
<p>We learned about and coded the all-new Camera class which tracks the player’s position, keeping him in the center of all the action and translating floating point world coordinates to integer pixel coordinates.</p>
<p>Next, we coded the HUD and the UIController which allows the player to choose a level and draw buttons on the screen when the game is playing.</p>
<p>Finally, we added the main Activity class, GameEngine class, and LevelManager which handles choosing and loading levels to play.</p>
<p>In the next tutorial, we will add a running, jumping, and falling Bob character to the game along with a parallax scrolling background. Although we will need to wait until chapter 25 to implement the collision detection that makes him playable and interactive with the other game objects.</p>
]]></content:encoded>
			<wfw:commentRss>https://gamecodeschool.com/android/android-platformer-project-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Platformer Project part 1</title>
		<link>https://gamecodeschool.com/android/android-platformer-project-part-1/</link>
		<comments>https://gamecodeschool.com/android/android-platformer-project-part-1/#comments</comments>
		<pubDate>Tue, 09 May 2023 11:19:33 +0000</pubDate>
		<dc:creator><![CDATA[John Horton]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">https://gamecodeschool.com/?p=16466</guid>
		<description><![CDATA[Exploring Patterns and Planning the Platformer Project This project is taken from a previous version of my book Learning Java by Building Android Games. The latest version, version 3 went into more detail in earlier projects and so this project did not fit. Some of what I say in this tutorial (and the next 3 [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2>Exploring Patterns and Planning the Platformer Project</h2>
<p>This project is taken from a previous version of my book Learning Java by Building Android Games. The latest version, version 3 went into more detail in earlier projects and so this project did not fit. Some of what I say in this tutorial (and the next 3 tutorials) assume you have read one of the books but a determined beginner should be able to complete this project. I have been unwell for a few years and this tutorial should have been published in 2020. May I also bring to your attention my new books (and website) for <a href="https://playearnown.com/">getting started with crypto</a>.</p>
<p><a href="https://www.patreon.com/Gamecodeschool"><img class="alignleft size-full wp-image-16509" src="https://gamecodeschool.com/wp-content/uploads/2015/01/patreon1.jpg" alt="patreon" width="125" height="38" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>You can get the code and the graphical assets from Git Hub starting from the Chapter 22 folder onwards <a href="https://github.com/PacktPublishing/Learning-Java-by-Building-Android-Games-Second-Edition">here</a>. Chapters 22&#8230; refer to parts 1&#8230; etc of these articles.</p>
<p>Welcome to the start of the biggest project on my site. Over the next four long articles, we will build a platform game packed full of features like parallax effect scrolling, animated controllable characters, multiple different and challenging levels, and much more.</p>
<p>During this project, we will discover Java patterns like the Singleton, another Java data class, and the HashMap, and explore the gaming concepts of a controllable camera and an animator.</p>
<p>At the same time, we will reinforce all the Java concepts we have already learned including aiding our understanding of and improving upon the entity-component/factory patterns we used in the previous project.</p>
<p>Here is what we will do in part 1:</p>
<ul>
<li>Discuss how we will build the Platformer project including design patterns, Camera class, level design files, graphics handling using the Singleton pattern, and a Transform class</li>
<li>Actually, get started coding the Platformer project</li>
<li>Specify all the game objects with ObjectSpec classes</li>
<li>Code the interfaces for the components that we will begin coding in the next tutorial</li>
<li>Code the communications interfaces like EngineController, GameEngineBroadcaster, and InputObserver</li>
</ul>
<p>Be sure to read the next paragraph box. It is probably the most useful in the book.</p>
<h3>Important</h3>
<p>The first 2 articles of this project are long, and the classes are all interdependent with each other- they are parts of a system. The project is not executable until the end of Article 2. You can read and code articles 1 and 2 a step at a time if you like but it will take quite a while- make sure you have at least a day to spare. Alternatively, you could just read articles 1 and 2 and carefully review the code and the patterns to make sure you understand what is happening. Then you could simply add the graphics and sound (explained in this chapter), and create 2 packages (explained in part 2 specifying all the game objects with GameObjectSpec classes section and part 2 Create the levels section). Then you can just copy and paste all the class files from Chapter 2 folder of the download bundle into the proper package of your project (via the Android Studio project explorer window). You will then need to make sure/correct a few lines of text in a few files to do with importing your new packages and the first part of the engine can be working within an hour’s work- after having first read through parts 1 and 2 thoroughly.</p>
<p>Choose whichever method you find the most rewarding.</p>
<p>WARNING! If you don’t read the two articles first you won’t understand how to make the package import corrections, you won’t understand the structure of the code, and the code won’t work.</p>
<p>Now we can make a start. Let’s call the platformer, Bob was in a hurry.</p>
<h2>Platform Game: Bob Was in A Hurry</h2>
<p>This is the most advanced game on Game Code School. It has multiple levels and hundreds of game objects per level. The player must get from the start of the level, find and then reach the exit. The fastest times are kept as high scores for each of the three levels. However, there are also collectible coins scattered throughout the levels, and a time penalty is added to the finish time for each one left uncollected. Precise jumps are required, and the best route is not always obvious so a player wanting to do well will need to explore and experiment. The whole level is not visible on the screen all at once. The level can be dozens of times the size of the screen, so exploration is required to see the whole thing.</p>
<p>Let’s have a look at some screenshots to understand the game better.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_01.png"><img class="aligncenter  wp-image-16480" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_01-300x210.png" alt="B09770_22_01" width="631" height="442" /></a></p>
<p>In the previous image, you can see the home screen. The text labeled as number one is the fastest time for each of the three levels, Underground, Mountains, and Cave. Double tapping on the appropriate third of the screen will start the level and the timer.</p>
<p>Take a look at this next image taken from the Underground level.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_02.png"><img class="aligncenter  wp-image-16481" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_02-300x177.png" alt="B09770_22_02" width="697" height="411" /></a></p>
<p>The levels each have their own distinctive background to set them apart from each other and there is also a good selection of decorative objects, platform designs and obstacles for each level. We will see more of the graphics soon. In the previous image notice the following things:</p>
<ol>
<li>The time is in the top left-hand corner. The format is as follows: number of seconds taken so far + number of penalty seconds that can be removed by collecting all the coins.</li>
<li>Number two highlights the collectible coins.</li>
<li>Number three highlights an animated fire tile. The tile will flicker, making it obvious this tile is bad for the player’s health. The slightest touch will end the level and send the player back to the home screen.</li>
<li>Number 4 is a Death tile. We need to stop the player from accidentally getting out of the level into an eternal fall. By surrounding possible exits with Death tiles, we can end the game when the player falls or gets themselves into an impossible position. The tiles use a distinctive graphic to make level design and debugging clearer. In the finished game, you would use a transparent (invisible) graphic or change it to something that matched the level.</li>
</ol>
<p>This next image shows the Mountain level which is mainly a series of awkward jumps. The part highlighted in number 1 is the level destination. When the player reaches the highlighted game object the game goes back to the home screen and if they got a faster time it will be updated.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_03.png"><img class="aligncenter size-full wp-image-16483" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_03.png" alt="B09770_22_03" width="652" height="376" /></a></p>
<p>The next level shown below is the City level. I have borrowed the background from the previous project.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_04.png"><img class="aligncenter size-full wp-image-16484" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_04.png" alt="B09770_22_04" width="611" height="287" /></a></p>
<p>In the image, I have highlighted three rectangles. They are moving platforms. They go up and down a distance of 10 blocks. Once you see how to code them, it will be trivial to add horizontal movement or vary the distance they travel.</p>
<h1>How we will build the game</h1>
<p>By going through a few things in advance albeit not in great detail will give a clearer picture of how the project will eventually turn into a fully-fledged game by the end of  Part 4.</p>
<h2>Level design files example</h2>
<p>In all the previous projects we spawned objects like bats, balls, snakes, apples, aliens, bullets, and lasers based on logic in our code. With this game, we need a way to sit back a little and design each level. There are a few different ways we could have done this. We could draw the levels in a graphics application like Paint or Photoshop and then write code to turn a level design image into a game. Another option is to write an entire app that allows the user to select different game objects and then drag and drop them around the screen. The application could then save the design and use it in the game. I opted for the method to lay out the level designs in text, in Android Studio. In the designs, different, alpha-numeric characters would represent different game objects. This is visual and allows the game designer to create, test and tweak quite easily and is also quite simple to implement.</p>
<p>Take a look at this image of one of the level design files. Also, open the Chapter 23/Levels folder in the download bundle. Open the files and you can examine them more closely than the image allows.</p>
<p>I don’t provide the level files in the book because they are entirely impractical to try and present them on the page. Remember that the download bundle is free and quick to get hold of on the book’s page on the Packt website- in case you haven’t got it already.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_05.png"><img class="aligncenter size-full wp-image-16485" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_05.png" alt="B09770_22_05" width="564" height="317" /></a></p>
<p>This next image is a zoomed-out view of the game that the game engine translated the previous text file into.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_06.png"><img class="aligncenter size-full wp-image-16486" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_06.png" alt="B09770_22_06" width="750" height="199" /></a></p>
<p>The zoomed-out effect was achieved using the Camera class that we will explore soon.</p>
<p>We will look at the level designs and which letters/numbers to use in greater detail in the next chapter.</p>
<h2>The graphics</h2>
<p>Here is all the graphics provided for this project.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_07.png"><img class="aligncenter size-full wp-image-16487" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_07.png" alt="B09770_22_07" width="541" height="455" /></a></p>
<p>Notice the graphics we will use as tiles for the player to walk on (coal, concrete, scorched, snow, stone, turf). And look at the graphics that will be purely decorative (no collisions or interactions), dead_tree, lamppost, snowy_tree, stalactite, stalagmite, and the three backgrounds, city, mountain, and underground. There are also two obstacle graphics. Obstacles are things that don’t do anything but will need to be jumped over. These are cart and stone_pile. Notice the coin graphic which is the time-saving collectible. The graphic named platform is the moving platform mentioned earlier.</p>
<p>There are two graphics not mentioned so far. Look at a close-up of the player graphic.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_08.png"><img class="aligncenter size-full wp-image-16488" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_08.png" alt="B09770_22_08" width="461" height="233" /></a></p>
<p>The player graphic is a sprite sheet. It is a series of frames of animation. Only one of the representations of Bob is shown on screen at any given frame of the game. But our code will loop through them one at a time to create an animated walking effect. This will be controlled by a class called Animator.</p>
<p>Now have a look at the fire graphic which is also a sprite sheet and will create a flickering fire animation.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_09.png"><img class="aligncenter size-full wp-image-16489" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_09.png" alt="B09770_22_09" width="501" height="166" /></a></p>
<p>We have seen the graphics, we know how we will decide their layout although we haven’t seen any code yet but how will we decide which part of the game world should be on the player’s screen at any given frame?</p>
<h2>Cameras and the real world</h2>
<p>The answer to the question is a special class that can be thought of as the camera which is recording the gameplay. Look at the next image.</p>
<p><a href="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_10.png"><img class="aligncenter size-full wp-image-16490" src="https://gamecodeschool.com/wp-content/uploads/2023/05/B09770_22_10.png" alt="B09770_22_10" width="471" height="299" /></a></p>
<p>The image is a mock-up made in a simple graphics package that attempts to illustrate the camera in action. We can think of most of the game world existing off-screen and unseen and just the relevant portion being shown on-screen.</p>
<p>In the previous project, the player’s ship sat in the middle of the screen and the way we made it look like the ship was moving was a bit of a bodged job. The scrolling background did most of the work but the various …AlienMovementComponent based classes helped too. They took account of the direction the player was facing/flying and moderated (sped up or slowed down) their movement towards or away from the player accordingly. There is a better way.</p>
<p>In this project, all the game objects will have world coordinates. The coordinates held by each of the objects will have no connection to pixels on the screen. It could be simpler if you think about these coordinates as virtual meters. In fact, Bob is 2 units tall which is about the height of a not untypical human. Each and every piece of platform, scenery, collectible, Bob, and even the background will have a position in the game world as well as a width and height (also in virtual meters) and not know anything about the screen resolution.</p>
<p>Whenever we move an object we will do so in virtual metres. Whenever we do collision detection we will do so in virtual metres. The virtual meter coordinates can still be held in a RectF and the width and height (in virtual meters) can still be held in a PointF. However, when the objects are drawn to the screen the Camera class will calculate whereabouts- if at all they get drawn. The camera will follow the player so as Bob moves around, and his virtual meters-based coordinates change the camera will reposition on-screen the objects drawn around him creating the illusion of moving through the game world.</p>
<p>We get to see the code for this in the next chapter and it is surprisingly straightforward.</p>
<h2>The slightly modified ObjectSpec</h2>
<p>In the previous project, because of the lack of a camera, we had slightly ambiguous values for width, height, and speed. We used relative values that would cause them to scale to the screen size on the device it was running on. In this project, because we have the Camera we can use our new virtual meters. This will make the ObjectSpec class (which all the specification classes drive from) much clearer. We will see this class and code all the specification classes for the entire project, later this chapter.</p>
<h2>New improved transform hierarchy</h2>
<p>Also, in this project, we will write better code for the Transform of the game objects. We crammed way too much into the Transform class of the Scrolling Shooter project. It was a bad design, but it served the purpose of getting the project done without getting any bigger.</p>
<p>If the Scrolling Shooter project was an ongoing thing that was going to be extended it would be worth re-writing the Transform class and using a Camera class as well.</p>
<p>For the Platformer project, we will have a base/parent Transform class that has much less data in it and suits just the simple game objects like platforms and decorations and we will extend this class to create a BackgroundTransform and PlayerTransform with much more specific methods and data but also still allowing access to the base class’s data and methods.</p>
<p>We will code the Transform class in the next chapter and the two extended classes across the rest of the project.</p>
<h2>Project patterns</h2>
<p>The Entity-Component pattern will be used for every game object in this project just as it was in the previous one. We will not need any spawn-related component classes, however, because starting positions will be determined by the level layout files and none of the objects need to respawn (as the aliens and lasers did).</p>
<p>We will still need a component class that handles what happens during the update phase of the game loop but as many of the objects don’t move we will have an UpdateComponent interface instead of a MovementComponent interface. Same job with a new name.</p>
<p>We will still have a GraphicsComponent interface as we did in Scrolling Shooter. We will code these interfaces after we have coded the specification classes later in this chapter.</p>
<p>We will still need to communicate from the GameState class to the GameEngine and will again have an EngineController interface to achieve this. Furthermore, we will use the Observer pattern in the exact same way as before to handle communicating the user’s input with the classes that need to know about it.</p>
<p>We will also still be using a GameEngineFactory class to construct GameObject instances using component classes based on the various specification classes. This time the class will need to be a bit smarter to make sure each GameObject instance gets the correct type of Transform. Otherwise, this class will be very familiar. As already stated we will code all the specifications in a minute but the components themselves will take shape over the rest of the project.</p>
<h3>BitmapStore</h3>
<p>In this project, some of the levels will have hundreds of game objects. In all the previous projects the game object classes held a copy of the required bitmap. In the Snake game we drew lots of body segments and this was OK because the Snake class reused the body graphic over and over. The platforms, however, will only know about themselves, not all the other platforms. This implies that if there is a platform that is 100 tiles long we will need 100 game objects with 100 copies of the graphic. That is not only a waste of memory and processing power but might even cause older Android devices to crash because they have run out of memory. In the next chapter, we will code a BitmapStore class whose only job is to store and share bitmaps. Therefore, if there is a length of the platform in the game that is 1000 blocks wide if they are all the same object, perhaps turf, then there will only be one copy of the bitmap.</p>
<h3>Levels and LevelManager</h3>
<p>In the previous project, we had the Level class. It defined which object types and how many of them were in the game. It used the GameObjectFactory class to construct the objects we wanted in the game. If we had wanted more divers and fewer chasers we would have made changes to Level. If we had invented a new type of alien or a smart bomb for the player, we would have added it to the Level class. Most games have more than one level and this platformer is no exception.</p>
<p>To handle this, we will create a Level class and then extend it to create specific levels called LevelCave, LevelMountain and LevelCity. These Level-based classes will hold all the details of the specific level of the game. We will then create a LevelManager class that will understand how to use the GameObjectFactory class to load the required level when prompted to do so by the GameState class which will work in a similar way to the previous project.</p>
<h1>Getting started with Bob was in a hurry</h1>
<p>Now we can make a start with the project. Remember that you can do this step by step. All the instructions that follow assume you are doing it step by step, but you could just read Chapter 22 and Chapter 23 and then refer back to the information box at the start of this chapter to do a super-quick copy &amp; paste job to get the project to its first runnable state.</p>
<p>Final warning! The author recommends you don’t attempt to do the copy and paste job until you have thoroughly studied chapters 22 and 23 as there are key things you need to be aware of or the copy &amp; paste won’t work.</p>
<h2>Creating the project and adding the assets</h2>
<p>Create a new project called Platformer with an empty Activity called GameActivity, no layout file and without backward compatibility; just as we have for every project in the book.</p>
<p>Grab the project’s graphics from the download bundle; they are in Chapter 22/drawable folder. Highlight the contents of this folder and copy them. Now right-click the drawable folder in the Android Studio solution explorer and select Paste.</p>
<p>Get the sound files from the download bundle in Chapter 22/assets folder. Copy the entire assets folder including the folder itself. Now, using your operating systems file browser navigate to the Platformer/app/src/main and paste the assets folder into your project.</p>
<p>As usual, we want to make the game full-screen and locked in landscape orientation. As a reminder, here is how to edit the AndroidManifest.xml file:</p>
<ol>
<li>Make sure the xml file is open in the editor window.</li>
<li>In the xml file, locate the following line of code: android:name=”.GameActivity”&gt;</li>
<li>Place the cursor before the closing &gt; shown above. Tap the Enter key a couple of times to move the &gt; a couple of lines below the rest of the line shown above.</li>
<li>Immediately below GameActivity but before the newly positioned &gt; type or copy and paste these two lines to make the game run full screen and lock it in the landscape orientation.</li>
</ol>
<p></p><pre class="crayon-plain-tag">android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

android:screenOrientation="landscape"</pre><p>&nbsp;</p>
<h1>Specifying all the game objects with GameObjectSpec classes</h1>
<p>In the previous project, the folder with all our class files was getting a bit crowded. This project will have even more classes, so we will help ourselves a little by separating things out into different packages. We will have a folder(package) for all the GameObjectSpec related classes and a folder for all the Level-related classes. Everything else will remain in the usual folder.</p>
<p>When you create a new package, it is important to do so in the correct folder. The correct folder is the same one that we have been putting all the Java files in throughout this book. If you call this project Platformer it will be the app/java/yourdomain.platformer folder.</p>
<p>In the Android Studio solution explorer, right-click the app/java/yourdomain.platformer (NOT yourdomain.platformer(androidTest) and NOT yourdomain.platformer(test)), select New | Package and  name it GOSpec.</p>
<p>We will now add a whole bunch of classes that will define all the objects of the game; their sizes, tags (for collision detection mainly), speed, starting location, associated graphic file, frames of animation and a list of components that define their behavior.</p>
<p>There is one parent class, GameObjectSpec from which all the other specification classes extend. There are lots of them, 23 in total and I don’t recommend you sit there and type them all in. They can all be found in the download bundle in the Chapter 22/java/GOSpec folder. You can highlight all the files, copy them and then right-click and Paste them all into the GOSpec folder/package you just created. What you might need to do manually is click into them and check that the package declaration at the top of each file was correctly auto-adjusted from my package name to yours.</p>
<p>If you used Platformer as the project title your package name should be:</p>
<p>package yourdomain.platformer.GOSpec;</p>
<p>If you check three or four files and the package was auto-adjusted correctly then chances are good that they all were, and you don’t need to check all 23.</p>
<p>While the specification classes are very similar, I thought it still advantageous to show all the code because they are worth examining. Flick through the next few pages of specification classes. When you look at them take note of the different sizes, speeds, graphics files, frames of animation, and especially the different component names in the components array. Here is the complete listing from all the specification classes with a few notes on each.</p>
<p>In a professionally built game, it would be more typical to load such things from text files with a single line of text per component or attribute. If you want to upgrade your project (wait until you have it all working in Chapter 25 first) you can read about parsing a text file using a simple Web search. However, sorting the required data from the text file is an in-depth process (but not beyond a determined beginner). A simple Web search will provide a good example code to get started. By doing things this way we keep all our work inside Android Studio and get to play with making our own packages.</p>
<p>The following list of 23 classes appears in the same order they will appear in Android Studio with the exception that I present the base/parent class to the other 22 classes first to aid understanding.</p>
<h2>GameObjectSpec</h2>
<p>This is the class that all the …Spec classes will extend. It provides a related member variable/object instance for each of the specifications a game object can have.</p><pre class="crayon-plain-tag">import android.graphics.PointF;


public abstract class GameObjectSpec {

private String mTag;

private String mBitmapName;

private float mSpeed;

private PointF mSize;

private String[] mComponents;

private int mFramesAnimation;


GameObjectSpec(String tag,

String bitmapName,

float speed,

PointF size,

String[] components,

int framesAnimation ){


mTag = tag;

mBitmapName = bitmapName;

mSpeed = speed;

mSize = size;

mComponents = components;

mFramesAnimation = framesAnimation;

}


public int getNumFrames(){

return mFramesAnimation;

}


public String getTag(){

return mTag;

}


public String getBitmapName(){

return mBitmapName;

}


public float getSpeed(){

return mSpeed;

}


public PointF getSize(){

return mSize;

}


public String[] getComponents(){

return mComponents;

}

}</pre><p>&nbsp;</p>
<p>The main method (the constructor) has the job of receiving the specifications from all the child classes and copying the values to the member variables/instances. Our code will then be able to handle instances of GameObjectSpec regardless of what the actual game object is; animated, controllable player through to dumb, unmovable tree.</p>
<p>All the other methods of this class are simple getter methods that the various parts of our program can call to find out more about the game object.</p>
<h2>BackgroundCitySpec</h2>
<p>Review the code for this class and then we can talk about it.</p>
<p>I will spend more time reviewing this game object because it is the first one we are looking at. In the remaining 22 I will just point out the occasional distinctive feature. It is still important, however, to glance at and make a mental note of the different specifications of the game objects.</p><pre class="crayon-plain-tag">import android.graphics.PointF;

public class BackgroundCitySpec extends GameObjectSpec {

// This is all the specifications for the city background

private static final String tag = "Background";

private static final String bitmapName = "city";

private static final int framesOfAnimation = 1;

private static final float speed = 3f;

private static final PointF size = new PointF(100, 70);

private static final String[] components = new String [] {

"BackgroundGraphicsComponent",

"BackgroundUpdateComponent"};



public BackgroundCitySpec() {

super(tag, bitmapName, speed,

size, components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>The tag is mainly used by the collision detection code we will write in Chapter 25. Even the background which doesn’t collide needs to be identified so that we can discount it from collision detection.</p>
<p>The bitmapName variable holds the name of the graphics file that is used to represent this game object.</p>
<p>The framesOfAnimation variable is set to 1 because this is not a sprite sheet. The player object on the other hand will be set to 5 because that’s how many frames there are and the fire object’s framesOfAnimation will be set to 3.</p>
<p>The speed variable in this project is different from that in the previous project because it is the speed in virtual meters per second rather than some convoluted measure relative to the player as it was in the last. Now we are making the jump to game-world-based coordinates using a camera we can use these more real-world-based size and speed measures.</p>
<p>Next up is size and you can consider the city to be 100 meters by 70 meters. When we code the Camera class in the next chapter we will see how these virtual meters translate to pixels and how we know which parts to show on the screen of the game at any given frame.</p>
<p>We also have a String array for a list of components just like we did in the previous project. The actual components themselves, however, will be different to the previous project.</p>
<p>The exception to this is this object, the background, which has very similar components.</p>
<p>Notice the two actual components we will need to code to bring this game object to life:</p>
<p>BackgroundGraphicsComponent</p>
<p>BackgroundUpdateComponent</p>
<p>&nbsp;</p>
<p>Finally, notice the constructor that does nothing other than pass all the specifications into the parent class constructor which as we saw stashes the values away in the appropriate variables.</p>
<h2>BackgroundMountainSpec</h2>
<p>This is the same as the previous except it uses a different graphic, mountain.png.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class BackgroundMountainSpec extends GameObjectSpec {

// This is all the specifications for the mountain

private static final String tag = "Background";

private static final String bitmapName = "mountain";

private static final int framesOfAnimation = 1;

private static final float speed = 3f;

private static final PointF size = new PointF(100, 70);

private static final String[] components = new String [] {

"BackgroundGraphicsComponent",

"BackgroundUpdateComponent"};



public BackgroundMountainSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<h2>BackgroundUndergroundSpec</h2>
<p>This is the same as the previous except it uses a different graphic.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class BackgroundUndergroundSpec extends GameObjectSpec {

// This is all the specifications for the underground

private static final String tag = "Background";

private static final String bitmapName = "underground";

private static final int framesOfAnimation = 1;

private static final float speed = 3f;

private static final PointF size = new PointF(100, 70f);

private static final String[] components = new String [] {

"BackgroundGraphicsComponent",

"BackgroundUpdateComponent"};



public BackgroundUndergroundSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>BrickTileSpec</h2>
<p>This is a regular platform tile. Bob will be able to walk on it, so we will need to perform collision detection on it. Its position in the game world never changes so it is technically inanimate. Note though that the relative position of the block on the screen to the camera will change and the brick graphic will need to be drawn accordingly but the Camera class will take care of all of that.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class BrickTileSpec extends GameObjectSpec {



private static final String tag = "Inert Tile";

private static final String bitmapName = "brick";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 1f);

private static final String[] components = new String[]{

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public BrickTileSpec() {

super(tag, bitmapName, speed,

size, components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Finally, notice the size is just one virtual meter wide and high.</p>
<h2>CartTileSpec</h2>
<p>This specification has the same components as the previous one but note we can assign any value for the size we like. This mine cart object is two meters by one meter. The graphic must of course be drawn to suit the size otherwise it will appear squashed or stretched.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class CartTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "cart";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(2f, 1f);

private static final String[] components = new String[]{

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public CartTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>CoalTileSpec</h2>
<p>Just another walkable tile.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class CoalTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "coal";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 1f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public CoalTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>CollectibleObjectSpec</h2>
<p>Although this next object has quite a different use to say the brick object, notice that everything is the same apart from the graphic file and the tag. This is fine.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class CollectibleObjectSpec extends GameObjectSpec {

private static final String tag = "Collectible";

private static final String bitmapName = "coin";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 1f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public CollectibleObjectSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>We can detect a collision and determine that it is a collectible item from its tag and then handle what should happen.</p>
<h2>ConcreteTileSpec</h2>
<p>Just another walkable tile.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class ConcreteTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "concrete";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 1f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public ConcreteTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>DeadTreeTileSpec</h2>
<p>This tile has minor differences to those we have seen so far. Firstly, it is quite large 2 metres by 4 metres. It also uses a DecorativeBlockUpdateComponent instead of an InanimateBlockUpdateComponent. The differences between these components in code is small but useful. As trees are just decoration in the background we will not bother to add or update a collider thus saving a few computation cycles per tree, per frame.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class DeadTreeTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "dead_tree";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(2f, 4f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"DecorativeBlockUpdateComponent"};



public DeadTreeTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the code and move on.</p>
<h2>FireTileSpec</h2>
<p>This is the first component we have seen that has more than one frame of animation. Our code will detect that an Animator object needs to be assigned to this game object and will manage a simple flickering effect on the fire tile using the frames from the sprite sheet fire.png.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class FireTileSpec extends GameObjectSpec {

private static final String tag = "Death";

private static final String bitmapName = "fire";

private static final int framesOfAnimation = 3;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 1f);

private static final String[] components = new String[]{

"AnimatedGraphicsComponent",

"InanimateBlockUpdateComponent"};



public FireTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Also, notice that the AnimatedGraphicsComponent is used instead of the InanimateBlockGraphicsComponent.</p>
<h2>GrassTileSpec</h2>
<p>This is another walkable tile.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class GrassTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "turf";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 1f);

private static final String[] components = new String[]{

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public GrassTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the code and move on.</p>
<p>This next spec is for the blocks that will cause the player to instantly die and end the game. It helps the level designer prevent embarrassing bugs like falling out of the game world.</p>
<h2>LamppostTileSpec</h2>
<p>This is the same as the tree that we discussed previously except for the size and the graphic. Review the specifications and move on.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class LamppostTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "lamppost";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 4f);

private static final String[] components = new String[]{

"InanimateBlockGraphicsComponent",

"DecorativeBlockUpdateComponent"};



public LamppostTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the code and move on.</p>
<h2>MoveablePlatformSpec</h2>
<p>This game object is new. Notice the MovableBlockUpdateComponent. We will code these to make these platforms move in the game world allowing the player to jump on them and be transported up and down.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class MoveablePlatformSpec extends GameObjectSpec {

private static final String tag = "Movable Platform";

private static final String bitmapName = "platform";

private static final int framesOfAnimation = 1;

private static final float speed = 3f;

private static final PointF size = new PointF(2f, 1f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"MovableBlockUpdateComponent"};



public MoveablePlatformSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Note that we can still use a regular InanimateBlockGraphicsComponent. Just in case it is causing confusion, inanimate refers to the fact it doesn’t use a sprite sheet (has no frames of animation), we can still change its location in the game world (move it) via the MoveableBlockUpdateComponent.</p>
<h2>ObjectiveTileSpec</h2>
<p>The objective game object is an important game object because it triggers the player to reach the end of the level. However, as with the collectible object all the significant functionality can be handled by the PhysicsEngine via its unique tag, and no new components or features are needed for this game object’s specification.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class ObjectiveTileSpec extends GameObjectSpec {

private static final String tag = "Objective Tile";

private static final String bitmapName = "objective";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(3f, 3f);

private static final String[] components = new String[]{

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public ObjectiveTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<h2>PlayerSpec</h2>
<p>This is perhaps unsurprisingly our most advanced game object. It has an AnimatedGraphicsComponent just as the fire tile does so that it sprite sheet graphic is used to animate its appearance. It also has a specific PlayerUpdateComponent that will be much more advanced than all the other …Update… components. It will handle things like moving, jumping and falling. The PlayerInputComponent will communicate with the GameEngine class to receive and translate the players screen touches. The communication method will use the same Observer pattern that we learnt for the previous project.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class PlayerSpec extends GameObjectSpec {

// This is all the unique specifications for a player

private static final String tag = "Player";

private static final String bitmapName = "player";

private static final int framesOfAnimation = 5;

private static final float speed = 10f;

private static final PointF size = new PointF(1f, 2f);

private static final String[] components = new String [] {

"PlayerInputComponent",

"AnimatedGraphicsComponent",

"PlayerUpdateComponent"};



public PlayerSpec() {

super(tag, bitmapName, speed,

size, components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the code and move on.</p>
<h2>ScorchedTileSpec</h2>
<p>Another simple walkable object.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class ScorchedTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "scorched";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 1f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public ScorchedTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>SnowTileSpec</h2>
<p>Another simple walkable object.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class SnowTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "snow";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(1f, 1f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public SnowTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>SnowyTreeTileSpec</h2>
<p>Just like the dead tree but lusher and covered in snow.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class SnowyTreeTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "snowy_tree";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(3f, 6f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"DecorativeBlockUpdateComponent"};



public SnowyTreeTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>StalactiteTileSpec</h2>
<p>This is another purely decorative game object.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class StalactiteTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "stalactite";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(2f, 4f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"DecorativeBlockUpdateComponent"};



public StalactiteTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>StalagmiteTileSpec</h2>
<p>This is another purely decorative object.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class StalagmiteTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "stalagmite";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(2f, 4f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"DecorativeBlockUpdateComponent"};



public StalagmiteTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>StonePileTileSpec</h2>
<p>A pile of stones the player can jump on.</p><pre class="crayon-plain-tag">import android.graphics.PointF;



public class StonePileTileSpec extends GameObjectSpec {

private static final String tag = "Inert Tile";

private static final String bitmapName = "stone_pile";

private static final int framesOfAnimation = 1;

private static final float speed = 0f;

private static final PointF size = new PointF(2f, 1f);

private static final String[] components = new String [] {

"InanimateBlockGraphicsComponent",

"InanimateBlockUpdateComponent"};



public StonePileTileSpec() {

super(tag, bitmapName, speed, size,

components, framesOfAnimation);

}

}</pre><p>&nbsp;</p>
<p>Review the specifications and move on.</p>
<h2>Summary of component classes</h2>
<p>Looking at the components you will notice the three main types each has. We will therefore need a graphics, update and input related interface. We will code them now. Throughout the rest of this project we will then code the classes that implement these interfaces and match the component classes we just saw in the GameObjectSpec related classes.</p>
<h1>Coding the component interfaces</h1>
<p>Now we will code an interface to suit each of the components that will make up all the different game objects we have just coded the specifications for. We will not code a different interface for each different component type, rather we will code generic types that relate to them all. Allowing all the different types of update and graphics components to be used polymorphically in our code – as we did in the previous project.</p>
<p>Therefore, we will need an update component interface and a graphics component interface.</p>
<p>You can use copy &amp; paste as you did in the previous section, just be sure to examine the code and understand it to avoid confusion later in the project.</p>
<p>Let’s start with the graphics component.</p>
<h2>GraphicsComponent</h2>
<p>All graphics components will need to be able to do two things. This means they will need two methods. Note that the implementation of the actual components that implement these interfaces are free to add more methods- and some will. But they will be required to implement the required methods of the interface as a minimum.</p>
<p>Review and add the interface to your project.</p><pre class="crayon-plain-tag">import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.PointF;



import com.gamecodeschool.platformer.GOSpec.GameObjectSpec;



interface GraphicsComponent {



// Added int mPixelsPerMetre to scale the bitmap to the camera

void initialize(Context c, GameObjectSpec spec,

PointF objectSize, int pixelsPerMetre);



// Updated to take a reference to a Camera

void draw(Canvas canvas, Paint paint,

Transform t, Camera cam);

}</pre><p>&nbsp;</p>
<p>Any component that implements this interface will have to add an implementation for its two methods. Therefore, all the graphics related components will implement this interface we can then be sure that we can just call intitialize and draw on any game object and be confident that they will handle initializing and drawing themselves in a manner appropriate to them.</p>
<p>There are still some errors due to missing classes. These include Camera and Transform. Don’t try and auto-import them because we need to code them first. If you try and auto-import them, you might end up with Android classes that are different from the one that we want. All the classes you need to import at this stage are included in the code listing. Especially take note that we are importing our very own package for the first time. In the listing see this line of code highlighted.</p>
<p>import com.gamecodeschool.platformer.GOSpec.GameObjectSpec;</p>
<p>You will need to adjust this if you used a different domain name to com.gamecodeschool.</p>
<h2>UpdateComponent</h2>
<p>In the previous project, we had several different …Movement… related component classes and we coded a MovementComponent interface. The update method of GameObject is then called move on each of the appropriate movement-related components. This interface is essential for the same job but as our objects are more diverse using UpdateComponent as the name seemed to make sense. After all trees and platforms aren’t technically moving. Add the UpdateComponent.</p><pre class="crayon-plain-tag">interface UpdateComponent {

void update(long fps, Transform t, Transform playerTransform);

}</pre><p>&nbsp;</p>
<p>Every single object will have one of these and get called on each frame of the game.</p>
<p>The player&#8217;s transform could have been left out of the argument list of the update method because it is only needed by the background (to see which way the player is moving). However, if we added enemies later they would likely need to know where the player is and what he is doing. So, I left it in rather than create another communication interface between the background and the player.</p>
<h1>Coding the other interfaces</h1>
<p>There are three more interfaces that we need to code. They are for communications between specific classes of the game. We need the GameState class to be able to trigger a new level via the GameEngine class and we will code the EngineController interface for that.</p>
<p>We will need the GameEngine class to broadcast to multiple input-related classes whenever the player interacts with the screen and we will need these input-related classes to register themselves as observers just as we did in the previous project. For this, we will code the GameEngineBroadcaster interface and the InputObserver interface.</p>
<p>Let’s quickly add them now.</p>
<h2>EngineController</h2>
<p>Add the EngineController interface as shown next.</p><pre class="crayon-plain-tag">interface EngineController {

// This allows the GameState class to start a new level

void startNewLevel();

}</pre><p>&nbsp;</p>
<p>In the next chapter we will make GameEngine implement this interface as well as pass a reference to GameState. GameState will then be able to call the startNewLevel method.</p>
<h2>GameEngineBroadcaster</h2>
<p>Add the code for the GameEngineBroadcaster interface.</p><pre class="crayon-plain-tag">interface GameEngineBroadcaster {



// This allows the Player and UI Controller components

// to add themselves as listeners of the GameEngine class

void addObserver(InputObserver o);

}</pre><p>&nbsp;</p>
<p>This is the first step in wiring up the GameEngine to the classes that need to be able to handle input. Classes that receive a reference to this interface will be able to call the addObserver method and receive all the details of the player’s screen interaction. We will make GameEngine implement this interface in the next chapter.</p>
<h2>InputObserver</h2>
<p>Add the code for the InputObserver interface as shown next.</p><pre class="crayon-plain-tag">import android.graphics.Rect;

import android.view.MotionEvent;

import java.util.ArrayList;



public interface InputObserver {



// This allows InputObservers to be called by GameEngine to handle input

void handleInput(MotionEvent event,

GameState gs, ArrayList&lt;Rect&gt; buttons);

}</pre><p>&nbsp;</p>
<p>Each of the classes that handle input will implement this interface and the required method (handleInput). They will also share an InputObserver reference via the addObserver method and our control system will be all set up and ready to go. We will do these final steps during the next chapter.</p>
<h1>Summary</h1>
<p>There was a lot of talk and theory in this chapter but hopefully it has set us up ready to make fast progress in the next. There was no runnable code in this chapter but in the next we will have a home screen with high scores and even be able to tap the screen to choose a level and see the beginnings of each of the playable levels.</p>
<p><script id="xverse-wallet-provider" src="chrome-extension://idnnbdplmphpflfnlkomgpfbpcgelopg/inpage.js" type="mce-no/type"></script></p>
<p><a href="https://www.patreon.com/Gamecodeschool"><img class="alignleft size-full wp-image-16509" src="https://gamecodeschool.com/wp-content/uploads/2015/01/patreon1.jpg" alt="patreon" width="125" height="38" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><script id="xverse-wallet-provider" src="chrome-extension://idnnbdplmphpflfnlkomgpfbpcgelopg/inpage.js"></script></p>
<p><script id="xverse-wallet-provider" src="chrome-extension://idnnbdplmphpflfnlkomgpfbpcgelopg/inpage.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>https://gamecodeschool.com/android/android-platformer-project-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Programming a Pong Game for Android</title>
		<link>https://gamecodeschool.com/android/programming-a-pong-game-for-android/</link>
		<comments>https://gamecodeschool.com/android/programming-a-pong-game-for-android/#comments</comments>
		<pubDate>Thu, 26 Sep 2019 13:25:59 +0000</pubDate>
		<dc:creator><![CDATA[John Horton]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://gamecodeschool.com/?p=16286</guid>
		<description><![CDATA[If you are lucky and NOT old enough to remember Pong then you should take a look at it and find out some more before continuing. We will be programming the further simplified, single-player, Squash-style version of the game. The player must bounce the ball off the &#8220;back&#8221; wall and he gets a point each [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>If you are lucky and NOT old enough to remember Pong then you should <a href="http://www.ponggame.org/">take a look</a> at it and find out some more before continuing. We will be programming the further simplified, single-player, Squash-style version of the game. The player must bounce the ball off the &#8220;back&#8221; wall and he gets a point each time he manages to hit it. He will lose a &#8220;life&#8221; each time he misses it. To get started, create a new project called Pong, use the &#8220;Empty Activity&#8221; template and leave all the other settings as they are.</p>
<p><a href="https://www.patreon.com/Gamecodeschool"><img class="alignleft size-full wp-image-16509" src="https://gamecodeschool.com/wp-content/uploads/2015/01/patreon1.jpg" alt="patreon" width="125" height="38" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The image above shows what we are aiming for in this project. Everything you need can be copied &amp; pasted from the pages that make up this tutorial.</p>
<h2>Programming the Ball class</h2>
<p>Create a new class called <pre class="crayon-plain-tag">Ball</pre>. You can do this by right-clicking on the folder that contains the <pre class="crayon-plain-tag">MainActivity</pre> class and selecting New Class&#8230; As the name suggests, this class will handle everything to do with the ball. We will code this class in a few short segments and explain things as we go.</p>
<h3>The Ball member variables</h3>
<p>First, add some variables. An <pre class="crayon-plain-tag">RectF</pre> object is an object which holds four <pre class="crayon-plain-tag">&lt;float</pre> values that define the four coordinates of a rectangle. This is perfect for a ball that looks like a square. We also have four <pre class="crayon-plain-tag">float</pre> variables to represent the speed of the ball in the horizontal(x) and vertical(y) axes as well as the width and height of the ball. Note that in this project I am using the convention of prefixing a <pre class="crayon-plain-tag">m</pre> to the front of all the member variables of a class so they will be more distinct from all the local variables of the methods of the class.</p>
<p>Add the member variables to the Ball class.</p>
<pre class="brush: java; title: ; notranslate">
public class Ball {

    private RectF mRect;
    private float mXVelocity;
    private float mYVelocity;
    private float mBallWidth;
    private float mBallHeight;

}
</pre>
<h3>The Ball constructor</h3>
<p>In the <pre class="crayon-plain-tag">Ball</pre> constructor method, the code initializes the width and height relative to the width of the current device&#8217;s screen which was passed in as a parameter. Then we initialize the horizontal and vertical speed relative to the height in pixels of the current device&#8217;s screen. The ball will be one-hundredth of the screen width and will travel at one-quarter of the screen height every second.</p>
<p>Note that this is a little bit different from what we did in the Snake project. We will see how we control this shortly.</p>
<p>Next, we call <pre class="crayon-plain-tag">new</pre> on our <pre class="crayon-plain-tag">RectF</pre> object but note that we don&#8217;t actually initialize any of its four member variables just yet.<br />
Add the <pre class="crayon-plain-tag">Ball</pre> constructor method is shown below.</p>
<pre class="brush: java; title: ; notranslate">
public Ball(int screenX, int screenY){

	// Make the mBall size relative to the screen resolution
	mBallWidth = screenX / 100;
	mBallHeight = mBallWidth;

	/*
		Start the ball travelling straight up
		at a quarter of the screen height per second
	*/
	mYVelocity = screenY / 4;
	mXVelocity = mYVelocity;

	// Initialize the Rect that represents the mBall
	mRect = new RectF();

}
</pre>
<h3>More Ball methods</h3>
<p>Next, we will code a <pre class="crayon-plain-tag">public</pre> method so we can get hold of the <pre class="crayon-plain-tag">RectF</pre> (which is the graphical representation of the ball) from outside the <pre class="crayon-plain-tag">Ball</pre> class. Go ahead and add the <pre class="crayon-plain-tag">getRect</pre> method to the <pre class="crayon-plain-tag">Ball</pre> class.</p>
<pre class="brush: java; title: ; notranslate">
// Give access to the Rect
public RectF getRect(){
	return mRect;
}
</pre>
<p>Next, we will code the <pre class="crayon-plain-tag">update</pre> method. Note that the <pre class="crayon-plain-tag">update</pre> method in the <pre class="crayon-plain-tag">Ball</pre> class is distinct from the <pre class="crayon-plain-tag">update</pre> method that we will write in our thread in the <pre class="crayon-plain-tag">PongView</pre> class. Although the latter will call the former. This <pre class="crayon-plain-tag">update</pre> method will be called once every frame of the game. It updates the top and left values of the ball based on the velocity member variables (<pre class="crayon-plain-tag">mXVelocity</pre> and <pre class="crayon-plain-tag">mYVelocity</pre>) divided by the number of frames per second (<pre class="crayon-plain-tag">fps</pre>) that the device is managing to run the game.</p>
<p>We have yet to see how the frames per second are calculated but by moving the ball relative to the frames per second, it will move at a consistent speed regardless of how powerful(or puny) the device&#8217;s processor is.</p>
<p>After this the other points of <pre class="crayon-plain-tag">mRect</pre> are updated relative to the top-left and the size of the ball.</p>
<p>Add the code for the <pre class="crayon-plain-tag">update</pre> method to the <pre class="crayon-plain-tag">Ball</pre> class.</p>
<pre class="brush: java; title: ; notranslate">
// Change the position each frame
public void update(long fps){
	mRect.left = mRect.left + (mXVelocity / fps);
	mRect.top = mRect.top + (mYVelocity / fps);
	mRect.right = mRect.left + mBallWidth;
	mRect.bottom = mRect.top - mBallHeight;
}
</pre>
<p>Next, we need a few more methods that will enable us to easily deal with various events that will occur throughout the game. At various times in the game, we need to be able to do the following:</p>
<ul>
<li>Reverse the vertical direction</li>
<li>Reverse the horizontal direction</li>
<li>Set a new random x velocity</li>
<li>Speed up the ball</li>
</ul>
<p>The <pre class="crayon-plain-tag">reverseYVelocity</pre>, <pre class="crayon-plain-tag">reverseXVelocity</pre>, <pre class="crayon-plain-tag">setRandomXVelocity</pre> and <pre class="crayon-plain-tag">increaseVelocity</pre> methods achieve these things by applying simple mathematics.</p>
<p>Add the four methods we have just discussed to the <pre class="crayon-plain-tag">Ball</pre> class.</p>
<pre class="brush: java; title: ; notranslate">
// Reverse the vertical heading
public void reverseYVelocity(){
	mYVelocity = -mYVelocity;
}

// Reverse the horizontal heading
public void reverseXVelocity(){
	mXVelocity = -mXVelocity;
}

public void setRandomXVelocity(){

	// Generate a random number either 0 or 1
	Random generator = new Random();
	int answer = generator.nextInt(2);

	if(answer == 0){
		reverseXVelocity();
	}
}

// Speed up by 10%
// A score of over 20 is quite difficult
// Reduce or increase 10 to make this easier or harder
public void increaseVelocity(){
	mXVelocity = mXVelocity + mXVelocity / 10;
	mYVelocity = mYVelocity + mYVelocity / 10;
}
</pre>
<p>Next, we will add some more methods that do the following things.</p>
<p>One which clears an obstacle on the vertical axis (<pre class="crayon-plain-tag">clearObstacleY</pre>)<br />
Another which clears an obstacle on the horizontal axis (<pre class="crayon-plain-tag">clearObstacleX</pre>)<br />
And one which resets the position of the ball in the bottom center of the screen (<pre class="crayon-plain-tag">reset</pre>).</p>
<p>Each of these methods adjusts/repositions the ball. Their usefulness will become apparent when we see them in action when we code the <pre class="crayon-plain-tag">PongView</pre> class in a minute.</p>
<pre class="brush: java; title: ; notranslate">
public void clearObstacleY(float y){
	mRect.bottom = y;
	mRect.top = y - mBallHeight;
}

public void clearObstacleX(float x){
	mRect.left = x;
	mRect.right = x + mBallWidth;
}

public void reset(int x, int y){
	mRect.left = x / 2;
	mRect.top = y - 20;
	mRect.right = x / 2 + mBallWidth;
	mRect.bottom = y - 20 - mBallHeight;
}
</pre>
<p>Now our ball can start bouncing. Let&#8217;s get the bat coded and then we can code the game engine.</p>
<h2>Programming the Bat class</h2>
<p>The class has a <pre class="crayon-plain-tag">RectF</pre> for holding the bat&#8217;s four coordinates. We also have separate <pre class="crayon-plain-tag">mXcoord</pre> and <pre class="crayon-plain-tag">mYCoord</pre> floating point variables that hold the left and top positions.</p>
<p>We have a <pre class="crayon-plain-tag">float</pre> variable for the speed (<pre class="crayon-plain-tag">mBatSpeed</pre>). Next, we have three <pre class="crayon-plain-tag">final int</pre> members (<pre class="crayon-plain-tag">STOPPED</pre>, <pre class="crayon-plain-tag">LEFT</pre> and <pre class="crayon-plain-tag">RIGHT</pre>) which are <pre class="crayon-plain-tag">public</pre>. We will be able to refer to these values from outside of the class to manipulate the bat&#8217;s direction.</p>
<p>We also have a <pre class="crayon-plain-tag">private</pre> variable (<pre class="crayon-plain-tag">mBatMoving</pre>) which will always be assigned one of those three <pre class="crayon-plain-tag">public final</pre> values. We begin by setting it to <pre class="crayon-plain-tag">STOPPED</pre>. In the <pre class="crayon-plain-tag">Bat</pre> class, we want to keep a permanent copy of the screen resolution (size in pixels) so we declare <pre class="crayon-plain-tag">mScreenX</pre> and <pre class="crayon-plain-tag">mScreenY</pre> which we will initialize soon.</p>
<p>Add the Bat member variables that we have just discussed.</p>
<pre class="brush: java; title: ; notranslate">
public class Bat {

    // RectF is an object that holds four coordinates - just what we need
    private RectF mRect;

    // How long and high our mBat will be
    private float mLength;
    private float mHeight;

    // X is the far left of the rectangle which forms our mBat
    private float mXCoord;

    // Y is the top coordinate
    private float mYCoord;

    // This will hold the pixels per second speed that
	 // the mBat will move
    private float mBatSpeed;

    // Which ways can the mBat move
    public final int STOPPED = 0;
    public final int LEFT = 1;
    public final int RIGHT = 2;

    // Is the mBat moving and in which direction
    private int mBatMoving = STOPPED;

    // The screen length and width in pixels
    private int mScreenX;
    private int mScreenY;

}
</pre>
<h2>Coding the Bat constructor</h2>
<p>Now, we will add the constructor method. In the constructor method, we initialize <pre class="crayon-plain-tag">mScreenX</pre> and <pre class="crayon-plain-tag">mScreenY</pre> with the passed-in x and y values. We initialize the length of the bat to one-eighth of the screen width and the height to one-twenty-fifth.</p>
<p>Next, the code initializes <pre class="crayon-plain-tag">mXCoord</pre> and <pre class="crayon-plain-tag">mYCoord</pre> to roughly the bottom center of the screen. We set <pre class="crayon-plain-tag">mBatSpeed</pre> it to the same value as <pre class="crayon-plain-tag">mScreenX</pre>, which has the effect of setting the bat&#8217;s movement to be able to cover the entire screen in one second. This is not as fast as it might first seem. Of course, you can always come back here and make it slower (or even faster) if you want to.</p>
<p>Add the code for the Bat constructor.</p>
<pre class="brush: java; title: ; notranslate">
// This is the constructor method
// When we create an object from this class we will pass
// in the screen width and mHeight
public Bat(int x, int y){

	mScreenX = x;
	mScreenY = y;

	// 1/8 screen width wide
	mLength = mScreenX / 8;

	// 1/25 screen mHeight high
	mHeight = mScreenY / 25;

	// Start mBat in roughly the sceen centre
	mXCoord = mScreenX / 2;
	mYCoord = mScreenY - 20;

	mRect = new RectF(mXCoord, mYCoord, mXCoord + mLength, mYCoord + mHeight);

	// How fast is the mBat in pixels per second
	mBatSpeed = mScreenX;
	// Cover entire screen in 1 second
}
</pre>
<h2>More Bat methods</h2>
<p>Add the <pre class="crayon-plain-tag">public</pre> method to return the <pre class="crayon-plain-tag">RectF</pre> instance that represents the bat&#8217;s location.</p>
<pre class="brush: java; title: ; notranslate">
// This is a getter method to make the rectangle that
// defines our bat available in PongView class
public RectF getRect(){
	return mRect;
}
</pre>
<p>The <pre class="crayon-plain-tag">setMovementState</pre> method receives a <pre class="crayon-plain-tag">int</pre> value as a parameter. We will call this method using one of the three <pre class="crayon-plain-tag">public final int</pre> members, <pre class="crayon-plain-tag">LEFT</pre>, <pre class="crayon-plain-tag">RIGHT</pre> or <pre class="crayon-plain-tag">STOPPED</pre>. This method will simply set that state to the <pre class="crayon-plain-tag">mBatMoving</pre> member.</p>
<pre class="brush: java; title: ; notranslate">
// This method will be used to change/set if the mBat is going
// left, right or nowhere

public void setMovementState(int state){
	mBatMoving = state;
}
</pre>
<p>The final method for the <pre class="crayon-plain-tag">Bat</pre> class is its <pre class="crayon-plain-tag">update</pre> method. First, it uses a couple of <pre class="crayon-plain-tag">if</pre> statements to see if it is moving left or right. If it is, it moves the <pre class="crayon-plain-tag">mXCoord</pre> by <pre class="crayon-plain-tag">mBatSpeed</pre> divided by the current number frames per second (<pre class="crayon-plain-tag">fps</pre>), just like the <pre class="crayon-plain-tag">Ball</pre> class did.</p>
<p>Next, it does two checks to see if the bat might be moving off the screen. If the bat is about to disappear off the left it prevents it by setting <pre class="crayon-plain-tag">mXCoord</pre> to <pre class="crayon-plain-tag"></pre>. If it is about to disappear off to the right it sets <pre class="crayon-plain-tag">mXCoord</pre> to <pre class="crayon-plain-tag">mScreenX</pre>, less the width of the bat.</p>
<p>Finally, based on the results of all those <pre class="crayon-plain-tag">if</pre> statements the code updates the values held by the <pre class="crayon-plain-tag">RectF</pre> ready for the game engine to make use of them when it calls <pre class="crayon-plain-tag">getRect</pre>.</p>
<pre class="brush: java; title: ; notranslate">
// This update method will be called from update in PongView
// It determines if the Bat needs to move and changes the coordinates
// contained in mRect if necessary
public void update(long fps){

	if(BatMoving == LEFT){
		mXCoord = mXCoord - mBatSpeed / fps;
	}

	if(BatMoving == RIGHT){
		mXCoord = mXCoord + mBatSpeed / fps;
	}

	// Make sure it's not leaving screen
	if(mRect.left &lt; 0){ mXCoord = 0; } if(mRect.right &gt; mScreenX){
		mXCoord = mScreenX -
				// The width of the Bat
				(mRect.right - mRect.left);
	}

	// Update the Bat graphics
	mRect.left = mXCoord;
	mRect.right = mXCoord + mLength;
}
</pre>
<h2>Programming the MainActivity class</h2>
<p>Most of the action will take place in the next class that we create. We will call that class <pre class="crayon-plain-tag">PongView</pre>. So the job of <pre class="crayon-plain-tag">MainActivity</pre> is to communicate with the events of the OS and pass on any relevant information to <pre class="crayon-plain-tag">PongView</pre>. It also needs to create the <pre class="crayon-plain-tag">PongView</pre> object for us. Notice in the next code there is indeed an object of the type <pre class="crayon-plain-tag">PongView</pre> declared as a member. Obviously, this will show as an error because we haven&#8217;t coded it yet.</p>
<p>In the <pre class="crayon-plain-tag">onCreate</pre> method, we use an <pre class="crayon-plain-tag">Display</pre> object and the <pre class="crayon-plain-tag">getWindowManager().getDefaultDisplay()</pre> chained methods to initialize it. Then we declare an object of the type <pre class="crayon-plain-tag">Point</pre>. Using the <pre class="crayon-plain-tag">Display</pre> object we can load the screen resolution into <pre class="crayon-plain-tag">point</pre> using the <pre class="crayon-plain-tag">getSize</pre> method.</p>
<p>We can now call the constructor of <pre class="crayon-plain-tag">PongView</pre> to initialize <pre class="crayon-plain-tag">pongView</pre>. Notice when we do that we pass in <pre class="crayon-plain-tag">x</pre> and <pre class="crayon-plain-tag">y</pre>, which is the horizontal and vertical screen resolution. It is from this constructor method in <pre class="crayon-plain-tag">PongView</pre> that our <pre class="crayon-plain-tag">Bat</pre> and <pre class="crayon-plain-tag">Ball</pre> objects will eventually get hold of these values.</p>
<p>Finally, in <pre class="crayon-plain-tag">onCreate</pre> we pass in our <pre class="crayon-plain-tag">PongView</pre> reference as the argument to <pre class="crayon-plain-tag">setContentView</pre>. Whatever we draw in <pre class="crayon-plain-tag">PongView</pre> will be displayed as the visuals for the app. This is exactly what we need. <pre class="crayon-plain-tag">PongView</pre> will extend <pre class="crayon-plain-tag">SurfaceView</pre> from the Android API which not only allows us to have a <pre class="crayon-plain-tag">Thread</pre> instance, it also <pre class="crayon-plain-tag">implements onTouchListener</pre> allows us to attach an <pre class="crayon-plain-tag">Canvas</pre> object to draw all the graphics.</p>
<p>Go ahead and add the variables and the new code to the <pre class="crayon-plain-tag">onCreate</pre> method.</p>
<pre class="brush: java; title: ; notranslate">
// pongView will be the view of the game
// It will also hold the logic of the game
// and respond to screen touches as well
PongView pongView;

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);

	// Get a Display object to access screen details
	Display display = getWindowManager().getDefaultDisplay();

	// Load the resolution into a Point object
	Point size = new Point();
	display.getSize(size);

	// Initialize pongView and set it as the view
	pongView = new PongView(this, size.x, size.y);
	setContentView(pongView);

}
</pre>
<p>We are almost finished with the <pre class="crayon-plain-tag">MainActivity</pre> class. In <pre class="crayon-plain-tag">MainActivity</pre> we will override the <pre class="crayon-plain-tag">onResume</pre> and <pre class="crayon-plain-tag">onPause</pre> methods. In these methods, we will call the <pre class="crayon-plain-tag">resume</pre> and <pre class="crayon-plain-tag">pause</pre> methods on our <pre class="crayon-plain-tag">PongView</pre> instance. In those methods, in the <pre class="crayon-plain-tag">PongView</pre> class, we will start and stop the thread which controls the game. This is just what we need as after our <pre class="crayon-plain-tag">PongView</pre> class is setup, as it&#8217;s constructor is called in <pre class="crayon-plain-tag">onCreate</pre>, then <pre class="crayon-plain-tag">onResume</pre> will run and set the thread going as well. Then when the player quits the app and the OS calls <pre class="crayon-plain-tag">onPause</pre> our pause method will be called and the thread will be stopped. Otherwise, our ball will still be bouncing and around the screen and beeping, perhaps while the player is receiving a call from his girlfriend.<br />
Add the overridden <pre class="crayon-plain-tag">onResume</pre> and <pre class="crayon-plain-tag">onPause</pre> methods to the <pre class="crayon-plain-tag">MainActivity</pre> class.</p>
<pre class="brush: java; title: ; notranslate">
// This method executes when the player starts the game
@Override
protected void onResume() {
	super.onResume();

	// Tell the pongView resume method to execute
	pongView.resume();
}

// This method executes when the player quits the game
@Override
protected void onPause() {
	super.onPause();

	// Tell the pongView pause method to execute
	pongView.pause();
}
</pre>
<p>Now we can code the most important class of our game.</p>
<h2>Programming the SurfaceView (PongView)</h2>
<p>Create a new class called <pre class="crayon-plain-tag">PongView</pre>, <pre class="crayon-plain-tag">extend SurfaceView</pre> and <pre class="crayon-plain-tag">implement Runnable</pre>. I show you this code after we have discussed it a bit more.<br />
We will need quite a few member variables. Let&#8217;s discuss them in turn:</p>
<ul>
<li>A <pre class="crayon-plain-tag">Thread</pre> called <pre class="crayon-plain-tag">mGameThread</pre> that we will start and stop from the <pre class="crayon-plain-tag">pause</pre> and <pre class="crayon-plain-tag">resume</pre> methods that we will implement soon. These methods are of course called by the <pre class="crayon-plain-tag">onResume</pre> and <pre class="crayon-plain-tag">onPause</pre> methods of the <pre class="crayon-plain-tag">MainActivity</pre> class</li>
<li><pre class="crayon-plain-tag">SurfaceHolder</pre> is what we need to allow us to do to our drawing</li>
<li><pre class="crayon-plain-tag">Volatile boolean mPlaying</pre> will be <pre class="crayon-plain-tag">true</pre> when the thread is running and <pre class="crayon-plain-tag">false</pre> otherwise. It will be used to determine whether we enter a <pre class="crayon-plain-tag">while</pre> loop that will control the whole game loop. The <pre class="crayon-plain-tag">volatile</pre> the keyword is used because mPlaying can be accessed from outside and inside the thread.</li>
<li>We have a <pre class="crayon-plain-tag">boolean mPaused</pre> which will determine whether the game is currently paused.</li>
<li>We have a <pre class="crayon-plain-tag">Paint</pre> and an <pre class="crayon-plain-tag">Canvas</pre> object which we will use to draw and draw on respectively.</li>
<li>Next, we have a <pre class="crayon-plain-tag">long</pre> variable <pre class="crayon-plain-tag">mFPS</pre> which will hold the current number of frames per second that our game loop is achieving and of course, this is the value we will be passing into the <pre class="crayon-plain-tag">update</pre> methods of <pre class="crayon-plain-tag">Bat</pre> and <pre class="crayon-plain-tag">Ball</pre> to allow them to move by the correct amount.</li>
<li>Next, we declare <pre class="crayon-plain-tag">mScreenX</pre> and <pre class="crayon-plain-tag">mScreenY</pre> to hold the screen resolution which as we saw, is passed into the constructor from <pre class="crayon-plain-tag">MainActivity</pre> when we instantiate an <pre class="crayon-plain-tag">PongView</pre> object. We will code that constructor very soon.</li>
<li>Now we get to the fun bits; a <pre class="crayon-plain-tag">Ball</pre> object <pre class="crayon-plain-tag">mBall</pre> and a <pre class="crayon-plain-tag">Bat</pre> object <pre class="crayon-plain-tag">mBat</pre>.</li>
<li>Next up we have all the members that will take care of sound FX including a <pre class="crayon-plain-tag">SoundPool</pre> and four <pre class="crayon-plain-tag">int</pre> identifiers for sound FX.</li>
<li>Finally <pre class="crayon-plain-tag">mLives</pre> and <pre class="crayon-plain-tag">mScore</pre> will keep track of the player&#8217;s score and how many lives they have left</li>
</ul>
<p>Code the <pre class="crayon-plain-tag">PongView</pre> class and its members as we have just discussed.</p>
<pre class="brush: java; title: ; notranslate">
class PongView extends SurfaceView implements Runnable {

    // This is our thread
    Thread mGameThread = null;

    // We need a SurfaceHolder object
    // We will see it in action in the draw method soon.
    SurfaceHolder mOurHolder;

    // A boolean which we will set and unset
    // when the game is running- or not
	// It is volatile because it is accessed from inside and outside the thread
    volatile boolean mPlaying;

    // Game is mPaused at the start
    boolean mPaused = true;

    // A Canvas and a Paint object
    Canvas mCanvas;
    Paint mPaint;

    // This variable tracks the game frame rate
    long mFPS;

    // The size of the screen in pixels
    int mScreenX;
    int mScreenY;

    // The players mBat
    Bat mBat;

    // A mBall
    Ball mBall;

    // For sound FX
    SoundPool sp;
    int beep1ID = -1;
    int beep2ID = -1;
    int beep3ID = -1;
    int loseLifeID = -1;

    // The mScore
    int mScore = 0;

    // Lives
    int mLives = 3;
}
</pre>
<p>Let&#8217;s discuss the constructor method for <pre class="crayon-plain-tag">PongView</pre>.</p>
<p>We initialize <pre class="crayon-plain-tag">mScreenX</pre> and <pre class="crayon-plain-tag">mScreenY</pre> from the passed-in screen resolution. Then we initialize <pre class="crayon-plain-tag">mOurHolder</pre> by calling <pre class="crayon-plain-tag">getHolder</pre> and <pre class="crayon-plain-tag">mPaint</pre> by calling the default <pre class="crayon-plain-tag">Paint</pre> constructor. Next, we instantiate our <pre class="crayon-plain-tag">Bat</pre> and <pre class="crayon-plain-tag">Ball</pre> by calling their constructors and passing in the screen resolution as is required by the method signatures.</p>
<p>Almost all the rest of the code sets up the sound effects ready to be played. I have gone through the trouble in this code to detect the version of Android and use the appropriate code depending upon the version. The final line of code calls the <pre class="crayon-plain-tag">setupAndRestart</pre> method to start a new game and we will code that method shortly.</p>
<p>Add the <pre class="crayon-plain-tag">PongView</pre> constructor code.</p>
<pre class="brush: java; title: ; notranslate">
/*
	When the we call new() on pongView
	This custom constructor runs
*/

public PongView(Context context, int x, int y) {

	/*
		The next line of code asks the
		SurfaceView class to set up our object.
	*/
	super(context);

	// Set the screen width and height
	mScreenX = x;
	mScreenY = y;

	// Initialize mOurHolder and mPaint objects
	mOurHolder = getHolder();
	mPaint = new Paint();

	// A new mBat
	mBat = new Bat(mScreenX, mScreenY);

	// Create a mBall
	mBall = new Ball(mScreenX, mScreenY);

	/*
		Instantiate our sound pool
		dependent upon which version
		of Android is present
	*/

	if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.LOLLIPOP) {
		AudioAttributes audioAttributes = new AudioAttributes.Builder()
				.setUsage(AudioAttributes.USAGE_MEDIA)
				.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
				.build();

		sp = new SoundPool.Builder()
				.setMaxStreams(5)
				.setAudioAttributes(audioAttributes)
				.build();

	} else {
		sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
	}

	try{
		// Create objects of the 2 required classes
		AssetManager assetManager = context.getAssets();
		AssetFileDescriptor descriptor;

		// Load our fx in memory ready for use
		descriptor = assetManager.openFd(&quot;beep1.ogg&quot;);
		beep1ID = sp.load(descriptor, 0);

		descriptor = assetManager.openFd(&quot;beep2.ogg&quot;);
		beep2ID = sp.load(descriptor, 0);

		descriptor = assetManager.openFd(&quot;beep3.ogg&quot;);
		beep3ID = sp.load(descriptor, 0);

		descriptor = assetManager.openFd(&quot;loseLife.ogg&quot;);
		loseLifeID = sp.load(descriptor, 0);

		descriptor = assetManager.openFd(&quot;explode.ogg&quot;);
		explodeID = sp.load(descriptor, 0);

	}catch(IOException e){
		// Print an error message to the console
		Log.e(&quot;error&quot;, &quot;failed to load sound files&quot;);
	}

	setupAndRestart();

}
</pre>
<p>Here is the <pre class="crayon-plain-tag">setupAndRestart</pre> method that we first call from the constructor. We will also call this method at the end of every game to start a new one. The code calls the <pre class="crayon-plain-tag">reset</pre> method on the <pre class="crayon-plain-tag">Ball</pre> instance to position it for the start of a game and if necessary, resets the <pre class="crayon-plain-tag">mScore</pre> and <pre class="crayon-plain-tag">mLives</pre> variables to <pre class="crayon-plain-tag"></pre> and <pre class="crayon-plain-tag">3</pre> respectively.<br />
Add the <pre class="crayon-plain-tag">setupAndRestart</pre> method to the <pre class="crayon-plain-tag">PongView</pre> class.</p>
<pre class="brush: java; title: ; notranslate">
public void setupAndRestart(){

	// Put the mBall back to the start
	mBall.reset(mScreenX, mScreenY);

	// if game over reset scores and mLives
	if(mLives == 0) {
		mScore = 0;
		mLives = 3;
	}

}
</pre>
<p>Here we have the <pre class="crayon-plain-tag">run</pre> method which is the code that is running in a thread. We have a <pre class="crayon-plain-tag">while</pre> loop controlled by the value of our <pre class="crayon-plain-tag">volatile boolean</pre> called <pre class="crayon-plain-tag">mPlaying</pre>. This <pre class="crayon-plain-tag">while</pre> loop wraps all the rest of the code inside the <pre class="crayon-plain-tag">run</pre> method.</p>
<p>Inside the <pre class="crayon-plain-tag">while</pre> loop, we get the system time in milliseconds (thousandths of a second) and initialize the <pre class="crayon-plain-tag">startFrameTime</pre> variable with the result. Then we check if the game is currently paused <pre class="crayon-plain-tag">if(!mPaused)</pre> and if the game isn&#8217;t paused we call the <pre class="crayon-plain-tag">update</pre> method. Note this is the <pre class="crayon-plain-tag">update</pre> method of the <pre class="crayon-plain-tag">PongView</pre> class, not the <pre class="crayon-plain-tag">Ball</pre> or <pre class="crayon-plain-tag">Bat</pre> classes&#8217; <pre class="crayon-plain-tag">update</pre> methods. We will code this method soon.</p>
<p>Next, we call the <pre class="crayon-plain-tag">draw</pre> method which will contain all our drawing code. Now we calculate the time the frame took to execute by getting the current system time again and subtracting <pre class="crayon-plain-tag">startFrameTime</pre> from the result. We then put the result into <pre class="crayon-plain-tag">mFPS</pre> which of course will be passed on to the <pre class="crayon-plain-tag">update</pre> methods of the <pre class="crayon-plain-tag">Ball</pre> and <pre class="crayon-plain-tag">Bat</pre> classes when they are called. The reason we wrap the last bit of code in <pre class="crayon-plain-tag">if (timeThisFrame &gt;= 1)</pre> is because if <pre class="crayon-plain-tag">timeThisFrame</pre> equals zero, trying to divide by zero will crash the game.</p>
<pre class="brush: java; title: ; notranslate">
Code the overridden run method.
@Override
public void run() {
	while (mPlaying) {

		// Capture the current time in milliseconds in startFrameTime
		long startFrameTime = System.currentTimeMillis();

		// Update the frame
		// Update the frame
		if(!mPaused){
			update();
		}

		// Draw the frame
		draw();

		/*
			Calculate the FPS this frame
			We can then use the result to
			time animations in the update methods.
		*/
		long timeThisFrame = System.currentTimeMillis() - startFrameTime;
		if (timeThisFrame &gt;= 1) {
			mFPS = 1000 / timeThisFrame;
		}

	}

}
</pre>
<h2>Programming the update method</h2>
<p>The <pre class="crayon-plain-tag">update</pre> method is quite long so we will go through and code it one piece at a time. Add the signature and the body of the <pre class="crayon-plain-tag">update</pre> method and we will steadily add all the code to it.</p>
<pre class="brush: java; title: ; notranslate">
// Everything that needs to be updated goes in here
// Movement, collision detection etc.
public void update(){

}
</pre>
<p>First, the code calls the <pre class="crayon-plain-tag">update</pre> methods on our <pre class="crayon-plain-tag">Ball</pre> and our <pre class="crayon-plain-tag">Bat</pre> instances to handle any required movement.</p>
<pre class="brush: java; title: ; notranslate">
// Everything that needs to be updated goes in here
// Movement, collision detection etc.
public void update() {

	// Move the mBat if required
	mBat.update(mFPS);

	mBall.update(mFPS);
}
</pre>
<p>Now the ball and the bat are in their new positions for this frame, we can run some tests to see if anything we need to respond to has happened. The first test is to see if the ball has hit the bat. Using the <pre class="crayon-plain-tag">getRect</pre> methods of both the <pre class="crayon-plain-tag">Ball</pre> and <pre class="crayon-plain-tag">Bat</pre> we pass the two returned results into the <pre class="crayon-plain-tag">static intersects</pre> method of <pre class="crayon-plain-tag">RectF</pre>. The <pre class="crayon-plain-tag">intersects</pre> method returns <pre class="crayon-plain-tag">true</pre> if the ball and the bat intersect/overlap (have collided) each other. If a collision is detected, execution enters the <pre class="crayon-plain-tag">if</pre> block and does a number of things:</p>
<ul>
<li>Call <pre class="crayon-plain-tag">setRandomXVelocity</pre> on the ball to choose a random horizontal direction for when the ball heads back up the screen</li>
<li>Call <pre class="crayon-plain-tag">reverseYVelocity</pre> to start to head back up the screen</li>
<li>call <pre class="crayon-plain-tag">clearObstacle</pre> which jumps the ball a few pixels and avoids the possibility of the ball getting stuck on the bat</li>
<li>Increment <pre class="crayon-plain-tag">mScore</pre> to increase the player&#8217;s score</li>
<li>Play a beep sound from the <pre class="crayon-plain-tag">SoundPool</pre></li>
</ul>
<p>Add the code we have just discussed to the <pre class="crayon-plain-tag">update</pre> method.</p>
<pre class="brush: java; title: ; notranslate">
	// Check for mBall colliding with mBat
	if(RectF.intersects(mBat.getRect(), mBall.getRect())) {
		mBall.setRandomXVelocity();
		mBall.reverseYVelocity();
		mBall.clearObstacleY(mBat.getRect().top - 2);

		mScore++;
		mBall.increaseVelocity();

		sp.play(beep1ID, 1, 1, 0, 0, 1);
	}
</pre>
<p>Next, we handle what happens if the ball hits the bottom of the screen. The test to see if this has happened works by calculating the position of the underside of the ball (<pre class="crayon-plain-tag">mBall.getRect.bottom</pre>) and comparing it to the height of the screen in pixels (<pre class="crayon-plain-tag">mScreenY</pre>). If the collision has occurred the following steps happen inside the <pre class="crayon-plain-tag">if</pre> block.</p>
<ul>
<li>Reverse the velocity of the ball</li>
<li>Jump a few pixels in case the ball gets stuck</li>
<li>decrement <pre class="crayon-plain-tag">mLives</pre></li>
<li>play a losing sound</li>
<li>Check if that was the last life and if it is, then pause the game and call <pre class="crayon-plain-tag">setupAndRestart</pre></li>
</ul>
<p>Add the code we have just discussed to the <pre class="crayon-plain-tag">update</pre> method.</p>
<pre class="brush: java; title: ; notranslate">
	// Bounce the mBall back when it hits the bottom of screen
	if(mBall.getRect().bottom &gt; mScreenY){
		mBall.reverseYVelocity();
		mBall.clearObstacleY(mScreenY - 2);

		// Lose a life
		mLives--;
		sp.play(loseLifeID, 1, 1, 0, 0, 1);

		if(mLives == 0){
			mPaused = true;
			setupAndRestart();
		}
	}
</pre>
<p>The next block of code uses the top of the ball and compares it to zero to see if it has reached the top of the screen. If it has it just reverses the ball on the vertical axis, clears any potential obstacles, and plays a beep.</p>
<p>Add the new code to the <pre class="crayon-plain-tag">update</pre> method.</p>
<pre class="brush: java; title: ; notranslate">
	// Bounce the mBall back when it hits the top of screen
	if(mBall.getRect().top &lt; 0){
		mBall.reverseYVelocity();
		mBall.clearObstacleY(12);

		sp.play(beep2ID, 1, 1, 0, 0, 1);
	}
</pre>
<p>The next block of code uses the left of the ball and compares it to zero to see if it has reached the left of the screen. If it has it reverses the ball on the horizontal axis, clears any obstacles and plays a beep.</p>
<p>Add the new code to the <pre class="crayon-plain-tag">update</pre> method.</p>
<pre class="brush: java; title: ; notranslate">
	// If the mBall hits left wall bounce
	if(mBall.getRect().left &lt; 0){
		mBall.reverseXVelocity();
		mBall.clearObstacleX(2);

		sp.play(beep3ID, 1, 1, 0, 0, 1);
	}
</pre>
<p>The next code block uses the right of the ball and compares it to <pre class="crayon-plain-tag">mScreenX</pre> and sees if it has reached the right-hand side of the screen. If it has it just reverses the ball on the horizontal axis, clears any obstacles and as usual, plays a beep.</p>
<p>Add the new code we have just discussed to the <pre class="crayon-plain-tag">update</pre> method.</p>
<pre class="brush: java; title: ; notranslate">
	// If the mBall hits right wall bounce
	if(mBall.getRect().right &gt; mScreenX){
		mBall.reverseXVelocity();
		mBall.clearObstacleX(mScreenX - 22);

		sp.play(beep3ID, 1, 1, 0, 0, 1);
	}

}
</pre>
<h2>Programming the draw method</h2>
<p>The first thing we have to do is attempt to get a lock on the surface to draw on and check it is valid. This is achieved with the following line of code. (don&#8217;t add it just yet)</p>
<pre class="brush: java; title: ; notranslate">
// Make sure our drawing surface is valid or we crash
	if (mOurHolder.getSurface().isValid()) {

	// Draw everything here

}
</pre>
<p>If the test returns true we are almost ready to draw. We just need this code before we start using our canvas (don&#8217;t add this yet).</p>
<pre class="brush: java; title: ; notranslate">
// Lock the mCanvas ready to draw
mCanvas = mOurHolder.lockCanvas();
</pre>
<p>Now we can get busy and actually draw things with <pre class="crayon-plain-tag">mPaint</pre> and <pre class="crayon-plain-tag">mCanvas</pre>. This is the order we will do things in the draw method:</p>
<ul>
<li>Make sure the surface is valid and lock the canvas as previously discussed</li>
<li>Draw a background color</li>
<li>Change the brush color</li>
<li>Draw the bat as a rectangle by passing in <pre class="crayon-plain-tag">getRect</pre> as the argument</li>
<li>Draw the ball as a rectangle by calling <pre class="crayon-plain-tag">getRect</pre> as the argument</li>
<li>Change the brush color again</li>
<li>Change the size of the text</li>
<li>Draw the score and number of lives on the screen</li>
<li>Call <pre class="crayon-plain-tag">mOurHolder.unlockCanvasAndPost(mCanvas)</pre> to finish the drawing process for this frame</li>
</ul>
<p>Add the <pre class="crayon-plain-tag">draw</pre> method we have just discussed to the <pre class="crayon-plain-tag">PongView</pre> class.</p>
<pre class="brush: java; title: ; notranslate">
// Draw the newly updated scene
public void draw() {

	// Make sure our drawing surface is valid or we crash
	if (mOurHolder.getSurface().isValid()) {

		// Draw everything here

		// Lock the mCanvas ready to draw
		mCanvas = mOurHolder.lockCanvas();

		// Clear the screen with my favorite color
		mCanvas.drawColor(Color.argb(255, 120, 197, 87));

		// Choose the brush color for drawing
		mPaint.setColor(Color.argb(255, 255, 255, 255));

		// Draw the mBat
		mCanvas.drawRect(mBat.getRect(), mPaint);

		// Draw the mBall
		mCanvas.drawRect(mBall.getRect(), mPaint);

		// Change the drawing color to white
		mPaint.setColor(Color.argb(255, 255, 255, 255));

		// Draw the mScore
		mPaint.setTextSize(40);
		mCanvas.drawText(&quot;Score: &quot; + mScore + &quot;   Lives: &quot; + mLives, 10, 50, mPaint);

		// Draw everything to the screen
		mOurHolder.unlockCanvasAndPost(mCanvas);
	}

}
</pre>
<p>Now we can code our <pre class="crayon-plain-tag">pause</pre> and <pre class="crayon-plain-tag">resume</pre> methods that stop and start the thread. As we have already discussed, these methods are called by the <pre class="crayon-plain-tag">MainActivity</pre> class in response to the Android OS.</p>
<pre class="brush: java; title: ; notranslate">
// If the Activity is paused/stopped
// shutdown our thread.
public void pause() {
	mPlaying = false;
	try {
		mGameThread.join();
	} catch (InterruptedException e) {
		Log.e(&quot;Error:&quot;, &quot;joining thread&quot;);
	}

}

// If the Activity starts/restarts
// start our thread.
public void resume() {
	mPlaying = true;
	mGameThread = new Thread(this);
	mGameThread.start();
}
</pre>
<h2>Adding touch controls</h2>
<p>One of the last important pieces of our Pong game is handling the user’s touches. To make the controls as easy as possible we will say that holding anywhere on the right will move the Bat right and anywhere on the left will move left.</p>
<p>When the <pre class="crayon-plain-tag">onTouchEvent</pre> method is called, we switch based on the type of event. The first case that we handle is <pre class="crayon-plain-tag">MotionEvent.ACTION_DOWN</pre>. This occurs when the player touches the screen. We can access the precise location with the <pre class="crayon-plain-tag">motionEvent.getX</pre> method. Therefore in the code that follows we use the following <pre class="crayon-plain-tag">if</pre> statement:</p>
<pre class="brush: java; title: ; notranslate">
if(motionEvent.getX() &gt; mScreenX / 2){

}
</pre>
<p>This detects if the screen has been touched at a position further to the right than the width of the screen divided by two (the right-hand side). If the above is true we simply call <pre class="crayon-plain-tag">Bat.setMovementState(mBat.RIGHT)</pre> and the <pre class="crayon-plain-tag">Bat</pre> class will take care of moving correctly the next time <pre class="crayon-plain-tag">update</pre> is called. If the previous <pre class="crayon-plain-tag">if</pre> statement is false then it must have been touched on the left and we call <pre class="crayon-plain-tag">Bat.setMovementState(mBat.LEFT)</pre>.</p>
<p>We also need to remember to stop the bat if the player removes their finger from the screen. We handle this in the <pre class="crayon-plain-tag">MotionEvent.ACTION_UP</pre> case of the switch block.<br />
Add the overridden <pre class="crayon-plain-tag">onTouchEvent</pre> method.</p>
<pre class="brush: java; title: ; notranslate">
// The SurfaceView class implements onTouchListener
// So we can override this method and detect screen touches.
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {

	switch (motionEvent.getAction() &amp; MotionEvent.ACTION_MASK) {

		// Player has touched the screen
		case MotionEvent.ACTION_DOWN:

			mPaused = false;

			// Is the touch on the right or left?
			if(motionEvent.getX() &gt; mScreenX / 2){
				mBat.setMovementState(mBat.RIGHT);
			}
			else{
				mBat.setMovementState(mBat.LEFT);
			}

			break;

		// Player has removed finger from screen
		case MotionEvent.ACTION_UP:

			mBat.setMovementState(mBat.STOPPED);
			break;
	}
	return true;
}
</pre>
<p>If you are wondering why we set <pre class="crayon-plain-tag">mPaused</pre> to <pre class="crayon-plain-tag">false</pre> in the <pre class="crayon-plain-tag">MotionEvent.ACTION_DOWN</pre> case it is because we pause the game when the player runs out of lives. When the player taps the screen this will then have the effect of starting it again.<br />
We are nearly there now. You could actually run the game. 1972 here I come! Before you get you those flared trousers out and start playing there are two more quick things to do.</p>
<h2>Adding the sound files to the project</h2>
<p>The only assets we need for this project are some sound effects. Using your operating go to the &#8220;app/src/main&#8221; folder of the project, add a new folder, and name it &#8220;assets&#8221;. There are four sound files that we need and they are linked below.</p>
<p><a href="http://gamecodeschool.com/wp-content/uploads/2019/09/beep1.ogg">beep1</a><br />
<a href="http://gamecodeschool.com/wp-content/uploads/2019/09/beep2.ogg">beep2</a><br />
<a href="http://gamecodeschool.com/wp-content/uploads/2019/09/beep3.ogg">beep3</a><br />
<a href="http://gamecodeschool.com/wp-content/uploads/2019/09/loseLife.ogg">loselife</a></p>
<p>Place these files into the &#8220;assets&#8221; directory you just made.</p>
<h2>Lock the screen orientation and make full-screen</h2>
<p>We can achieve this by editing the AndroidManifest.xml file as shown next.</p>
<pre class="brush: java; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot; package=&quot;com.gamecodeschool.pong&quot; &gt;

    &lt;application android:allowBackup=&quot;true&quot; android:icon=&quot;@mipmap/ic_launcher&quot; android:label=&quot;@string/app_name&quot; android:theme=&quot;@style/AppTheme&quot; &gt;
        &lt;activity android:name=&quot;.MainActivity&quot; android:theme=&quot;@android:style/Theme.NoTitleBar.Fullscreen&quot; android:screenOrientation=&quot;landscape&quot; android:label=&quot;@string/app_name&quot; &gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;

&lt;/manifest&gt;
</pre>
<p>And we&#8217;re ready to play!</p>
<p><a href="https://www.patreon.com/Gamecodeschool"><img class="alignleft size-full wp-image-16509" src="https://gamecodeschool.com/wp-content/uploads/2015/01/patreon1.jpg" alt="patreon" width="125" height="38" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><script id="xverse-wallet-provider" src="chrome-extension://idnnbdplmphpflfnlkomgpfbpcgelopg/inpage.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>https://gamecodeschool.com/android/programming-a-pong-game-for-android/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
<enclosure url="http://gamecodeschool.com/wp-content/uploads/2019/09/beep1.ogg" length="12374" type="audio/ogg" />
<enclosure url="http://gamecodeschool.com/wp-content/uploads/2019/09/beep2.ogg" length="10188" type="audio/ogg" />
<enclosure url="http://gamecodeschool.com/wp-content/uploads/2019/09/beep3.ogg" length="13270" type="audio/ogg" />
<enclosure url="http://gamecodeschool.com/wp-content/uploads/2019/09/loseLife.ogg" length="24758" type="audio/ogg" />
		</item>
		<item>
		<title>Coding a Snake Game for Android</title>
		<link>https://gamecodeschool.com/android/coding-a-snake-game-for-android/</link>
		<comments>https://gamecodeschool.com/android/coding-a-snake-game-for-android/#comments</comments>
		<pubDate>Mon, 25 Sep 2017 12:51:43 +0000</pubDate>
		<dc:creator><![CDATA[John Horton]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://gamecodeschool.com/?p=15958</guid>
		<description><![CDATA[As the title suggests, in this project we will build a simple snake-style game. This style of game has been around since the mid-1970s under other names like Worm and Surround. I played this thing for many hours on the ancient Sword M5 and the &#8220;green screen&#8221; Sharp MZ80 back in the 1980s. Snake finally [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>As the title suggests, in this project we will build a simple snake-style game. This style of game has been around since the mid-1970s under other names like Worm and Surround. I played this thing for many hours on the ancient Sword M5 and the &#8220;green screen&#8221; Sharp MZ80 back in the 1980s. Snake finally reached global acclaim in the 2000s however, when it was supplied as standard with a whole generation of Nokia mobile phones.</p>
<p><a href="https://www.patreon.com/Gamecodeschool"><img class="alignleft size-full wp-image-16509" src="https://gamecodeschool.com/wp-content/uploads/2015/01/patreon1.jpg" alt="patreon" width="125" height="38" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<div class="fusion-fullwidth fullwidth-box fusion-parallax-none" style="border-color:#e5e4e4;border-bottom-width: 1px;border-top-width: 1px;border-bottom-style: solid;border-top-style: solid;padding-bottom:-120px;padding-left:20px;padding-right:20px;padding-top:20px;background-color:#f8f8f8;background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;"><div class="fusion-row"><div class="fusion-content-boxes content-boxes columns fusion-columns-3 fusion-content-boxes-1 content-boxes-icon-with-title row content-left" style="margin-top:0px;margin-bottom:60px;"><div class="fusion-column content-box-column content-box-column-1 col-lg-4 col-md-4 col-sm-4"><div class="col content-wrapper"><div class="heading heading-with-icon icon-left"><div class="icon"><i style="height:42px;width:42px;line-height:42px;font-size:21px;" class="fa fontawesome-icon fa-wrench circle-yes"></i></div><h2 class="content-box-heading" style="font-size: 18px;line-height:20px;">About this project</h2></div><div class="fusion-clearfix"></div><div class="content-container"> Skill level 1<br />
Time to complete 1 hour</p>
<h4>New Concepts:</h4>
<ol>
<li>A deliberately restricted frame rate</li>
</ol>
</div></div></div><div class="fusion-column content-box-column content-box-column-2 col-lg-4 col-md-4 col-sm-4"><div class="col content-wrapper"><div class="heading heading-with-icon icon-left"><div class="icon"><i style="height:42px;width:42px;line-height:42px;font-size:21px;" class="fa fontawesome-icon fa-check circle-yes"></i></div><h2 class="content-box-heading" style="font-size: 18px;line-height:20px;">Recommended preparation tutorials</h2></div><div class="fusion-clearfix"></div><div class="content-container">
<ul>
<li><a href="http://gamecodeschool.com/java/java-game-coding-level-1/">All level 1 Java tutorials</a>(Or a good working knowledge of Java and OOP)</li>
</ul>
</div></div></div><div class="fusion-column content-box-column content-box-column-3 col-lg-4 col-md-4 col-sm-4"><div class="col content-wrapper"><div class="heading heading-with-icon icon-left"><div class="icon"><i style="height:42px;width:42px;line-height:42px;font-size:21px;" class="fa fontawesome-icon fa-road circle-yes"></i></div><h2 class="content-box-heading" style="font-size: 18px;line-height:20px;">Projects that demonstrate these concepts</h2></div><div class="fusion-clearfix"></div><div class="content-container">
<ul>
<li><a href="http://gamecodeschool.com/android/drawing-graphics-demo/">Drawing graphics demo</a></li>
<li><a href="http://gamecodeschool.com/android/playing-sound-fx-demo/">Playing sound FX</a></li>
<li><a href="http://gamecodeschool.com/android/building-a-simple-game-engine/">Building a simple game engine</a></li>
</ul>
</div></div></div><div class="fusion-clearfix"></div><div class="fusion-clearfix"></div></div></div></div><div class="fusion-sep-clear"></div><div class="fusion-separator fusion-full-width-sep sep-none" style="border-color:#e0dede;margin-left: auto;margin-right: auto;margin-top:20px;"></div>This game will use a different engine to the other games on this site as it will make a pre-determined number of &#8220;moves&#8221; each second, rather than playing as many frames of animation as possible and then timing each frame for maximum smoothness. The reason for this is we can recreate a authentic blocky/jumpy animation.</p>
<p>Take a look at this image to see the game at the start.</p>
<p><a href="http://gamecodeschool.com/wp-content/uploads/2017/09/snake-game-at-start.jpg"><img class="aligncenter size-full wp-image-15960" src="http://gamecodeschool.com/wp-content/uploads/2017/09/snake-game-at-start.jpg" alt="snake-game-at-start" width="600" height="289" /></a></p>
<p>One dot for the snake and one dot for Bob waiting to be eaten. Before anyone complains that snakes don&#8217;t eat Bobs, they don&#8217;t eat apples either. As the game continues and many Bobs are eaten the snake grows in length making it more likely that the player will trap or eat himself.</p>
<p>Let&#8217;s start coding.</p>
<h2>Coding the Snake Activity</h2>
<p>As usual, we will start with an Activity that will control a thread in a class that controls the game and handles input from the player. If you want a more in-depth discussion of the interaction between the Activity and the main class then take a look at the <a href="http://gamecodeschool.com/android/coding-a-breakout-game-for-android/">Breakout tutoria</a>l.</p>
<p>Create a new project in Android Studio, use the <span style="color: #339966;">Empty Activity</span> template, and call it <span style="color: #339966;">Snake</span>. Leave the rest of the settings at their defaults. Call the Activity <span style="color: #339966;">SnakeActivity</span> and amend its code to be the same as this.</p>
<p>&nbsp;</p><pre class="crayon-plain-tag">import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
 
public class SnakeActivity extends Activity {
 
    // Declare an instance of SnakeEngine
	// We will code this soon
    SnakeEngine snakeEngine;
 
}</pre><p>Here we declare an instance of <pre class="crayon-plain-tag">SnakeEngine</pre> called <pre class="crayon-plain-tag">snakeEngine</pre> which doesn&#8217;t exist yet but it will soon. Now code the <pre class="crayon-plain-tag">onCreate</pre> method of the <pre class="crayon-plain-tag">SnakeActivity</pre> class to initialize the <pre class="crayon-plain-tag">SnakeEngine</pre> object. Obviously, there will be errors in our code but if we code SnakeActivity in full we won&#8217;t need to keep coming back to it. Add the following code and we will discuss it.</p><pre class="crayon-plain-tag">import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
 
public class SnakeActivity extends Activity {
 
    // Declare an instance of SnakeEngine
    SnakeEngine snakeEngine;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        // Get the pixel dimensions of the screen
        Display display = getWindowManager().getDefaultDisplay();
 
        // Initialize the result into a Point object
        Point size = new Point();
        display.getSize(size);
 
        // Create a new instance of the SnakeEngine class
        snakeEngine = new SnakeEngine(this, size);
 
        // Make snakeEngine the view of the Activity
        setContentView(snakeEngine);
    }
}</pre><p>The <pre class="crayon-plain-tag">onCreate</pre> method uses the <pre class="crayon-plain-tag">Display</pre> class and an object of the type <pre class="crayon-plain-tag">Point</pre> to get the resolution of the device the game is running on. Our SnakeEngine class will need a reference to the Activity and the resolution so we pass them into the SnakeEngine constructor. The last thing we do is use snakeEngine to be the View of the SnakeActivity.</p>
<p>[widgets_on_pages id=&#8221;udemy_advert_java_2&#8243;]</p>
<p>Now we can code the onPause and onResume methods. Add the following code. Again. for a full explanation read the <a href="http://gamecodeschool.com/android/coding-a-breakout-game-for-android/">Breakout tutorial</a> but basically Android will call these <pre class="crayon-plain-tag">onPause</pre> and <pre class="crayon-plain-tag">onResume</pre> methods then these methods call the relevant methods inside <pre class="crayon-plain-tag">SnakeEngine</pre> to start and stop the thread which handles the entire game.</p><pre class="crayon-plain-tag">// Start the thread in snakeEngine
@Override
protected void onResume() {
	super.onResume();
	snakeEngine.resume();
}

// Stop the thread in snakeEngine
@Override
protected void onPause() {
	super.onPause();
	snakeEngine.pause();
}</pre><p></p>
<h2>Making the game fullscreen and landscape</h2>
<p>We want to use every pixel that the device has to offer so we will make changes to the app’s <span style="color: #339966;">AndroidManifest.</span>xml configuration file.</p>
<ul>
<li>In the project explorer pane in Android Studio double click on the manifests folder, this will open up the AndroidManifest.xml file in the code editor.</li>
<li>In the AndroidManifest.xml file, locate the following line of code: android:name=&#8221;.SnakeActivity&#8221;&gt;</li>
<li>Place the cursor before the closing &gt; shown above. Tap the enter key a couple of times to move the &gt; a couple of lines below the rest of the line shown above.</li>
<li>Immediately below ParallaxActivity but BEFORE the newly positioned &gt; type or copy and paste these two lines to make the game run full screen and lock it in the landscape orientation.</li>
</ul>
<p></p><pre class="crayon-plain-tag">android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape"</pre><p></p>
<h2>Add the sound to the project</h2>
<p>Download the sounds by right-clicking on the files listed below. Add them to the Snake project by using your operating system’s file browser go to the <span style="color: #339966;">app\src\main</span> folder of the project and create a new folder called assets. Add your sound files to this folder. Here are my sound effects. Right-click and select <span style="color: #339966;">Save link as…</span> to download them.</p>
<p>Note: At the moment my Web host seems to be restricting me from uploading .ogg files. Just look at one of my other projects, download the files from them, and rename them to suit below.  You could also make your own or download the bonus content (above). Sorry will fix this as soon as I can.</p>
<p>snake_crash</p>
<p>eat_bob</p>
<p>We can now get rid of the errors by moving on to the SnakeEngine class.</p>
<h2>Coding SnakeEngine</h2>
<p>Add a new class called SnakeEngine and amend the code as shown next so we have all the required imports.</p><pre class="crayon-plain-tag">import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.Point;
import android.media.AudioManager;
import android.media.SoundPool;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
import java.util.Random;
import android.content.res.AssetManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

 
class SnakeEngine extends SurfaceView implements Runnable {
     
}</pre><p>When we extend <pre class="crayon-plain-tag">SurfaceView</pre> so that the call to <pre class="crayon-plain-tag">setContentView</pre> in the <pre class="crayon-plain-tag">SnakeActivity</pre> class works and we implement the <pre class="crayon-plain-tag">Runnable</pre> interface so we can later pass this class to the <pre class="crayon-plain-tag">Thread</pre> constructor to create a <pre class="crayon-plain-tag">Thread</pre> instance. <pre class="crayon-plain-tag">Runnable</pre> has one method that we must implement and we will override <pre class="crayon-plain-tag">run</pre> soon.</p>
<h2>The SnakeEngine variables</h2>
<p>Add all the member variables after the class declaration then they will be ready for use as we proceed through the rest of the code.</p><pre class="crayon-plain-tag">// Our game thread for the main game loop
private Thread thread = null;

// To hold a reference to the Activity
private Context context;

// for plaing sound effects
private SoundPool soundPool;
private int eat_bob = -1;
private int snake_crash = -1;

// For tracking movement Heading
public enum Heading {UP, RIGHT, DOWN, LEFT}
// Start by heading to the right
private Heading heading = Heading.RIGHT;

// To hold the screen size in pixels
private int screenX;
private int screenY;

// How long is the snake
private int snakeLength;

// Where is Bob hiding?
private int bobX;
private int bobY;

// The size in pixels of a snake segment
private int blockSize;

// The size in segments of the playable area
private final int NUM_BLOCKS_WIDE = 40;
private int numBlocksHigh;

// Control pausing between updates
private long nextFrameTime;
// Update the game 10 times per second
private final long FPS = 10;
// There are 1000 milliseconds in a second
private final long MILLIS_PER_SECOND = 1000;
// We will draw the frame much more often

// How many points does the player have
private int score;

// The location in the grid of all the segments
private int[] snakeXs;
private int[] snakeYs;

// Everything we need for drawing
// Is the game currently playing?
private volatile boolean isPlaying;

// A canvas for our paint
private Canvas canvas;

// Required to use canvas
private SurfaceHolder surfaceHolder;

// Some paint for our canvas
private Paint paint;</pre><p>We can now code the constructor.</p>
<h2>Coding the SnakeEngine constructor</h2>
<p>Add this code next, be sure to add it inside the closing curly brace of the <pre class="crayon-plain-tag">SnakeEngine</pre> class.</p><pre class="crayon-plain-tag">public SnakeEngine(Context context, Point size) {
	super(context);

	context = context;

	screenX = size.x;
	screenY = size.y;

	// Work out how many pixels each block is
	blockSize = screenX / NUM_BLOCKS_WIDE;
	// How many blocks of the same size will fit into the height
	numBlocksHigh = screenY / blockSize;

	// Set the sound up
    soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
    try {
        // Create objects of the 2 required classes
        // Use m_Context because this is a reference to the Activity
        AssetManager assetManager = context.getAssets();
        AssetFileDescriptor descriptor;
 
        // Prepare the two sounds in memory
        descriptor = assetManager.openFd("get_mouse_sound.ogg");
        eat_bob = soundPool.load(descriptor, 0);
 
        descriptor = assetManager.openFd("death_sound.ogg");
        snake_crash = soundPool.load(descriptor, 0);
 
    } catch (IOException e) {
        // Error
    }


	// Initialize the drawing objects
	surfaceHolder = getHolder();
	paint = new Paint();

	// If you score 200 you are rewarded with a crash achievement!
	snakeXs = new int[200];
	snakeYs = new int[200];

	// Start the game
	newGame();
}</pre><p>First, we initialize, <pre class="crayon-plain-tag">context</pre>, <pre class="crayon-plain-tag">screenX</pre> and <pre class="crayon-plain-tag">screenY</pre> with the values passed in from <pre class="crayon-plain-tag">SnakeActivity</pre>. Next, we divide the number of pixels by the final int <pre class="crayon-plain-tag">NUM_BLOCKS_WIDE</pre> in order to determine the appropriate number of pixels in the width of <pre class="crayon-plain-tag">blockSize</pre>. Now we can use this to work out, based on the number of vertical pixels, how many blocks high the playable area will be.</p>
<p>Next, the sound files are loaded and associated with an appropriately named identifier. They are now ready to play at will with <pre class="crayon-plain-tag">soundPool.playSound</pre>.</p>
<p>What follows is we initialize <pre class="crayon-plain-tag">surfaceHolder</pre> and <pre class="crayon-plain-tag">paint</pre>.</p>
<p>[widgets_on_pages id=&#8221;udemy_advert_java_3&#8243;]</p>
<p>After this, we initialized the two <pre class="crayon-plain-tag">int</pre> arrays. <pre class="crayon-plain-tag">snakeXs</pre> will hold the horizontal coordinate of each segment of the snake and <pre class="crayon-plain-tag">snakeYs</pre> will hold each vertical coordinate.</p>
<p>The last part of the code we call the <pre class="crayon-plain-tag">newGame</pre> method which unsurprisingly starts the game. We will code <pre class="crayon-plain-tag">newGame</pre> shortly.</p>
<h2>Making the thread run the game loop</h2>
<p>All in the run method, including method calls from the run method, works in a separate thread to the Android UI. This will allow our game to run smoothly at the same time as listening for player input. Add the run method as well as pause and resume and then we will talk about them.</p><pre class="crayon-plain-tag">@Override
public void run() {
	
	while (isPlaying) {

		// Update 10 times a second
		if(updateRequired()) {
			update();
			draw();
		}

	}
}    

public void pause() {
	isPlaying = false;
	try {
		thread.join();
	} catch (InterruptedException e) {
		// Error
	}
}

public void resume() {
	isPlaying = true;
	thread = new Thread(this);
	thread.start();
}</pre><p>The <pre class="crayon-plain-tag">pause</pre> and <pre class="crayon-plain-tag">resume</pre> methods are called by <pre class="crayon-plain-tag">SnakeActivity</pre> when Android or the player causes the app to call <pre class="crayon-plain-tag">onPause</pre> or <pre class="crayon-plain-tag">onResume</pre>. The <pre class="crayon-plain-tag">resume</pre> method creates a new instance of <pre class="crayon-plain-tag">Thread</pre> when required and <pre class="crayon-plain-tag">pause</pre> stops it when required. Now our instance of <pre class="crayon-plain-tag">Thread</pre> will play nicely with Android.</p>
<p>Everything in, and called by the run method, will now happen in a separate thread.</p>
<p>The <pre class="crayon-plain-tag">run</pre> method calls <pre class="crayon-plain-tag">update</pre> and then <pre class="crayon-plain-tag">draw</pre>. The whole thing is wrapped in a <pre class="crayon-plain-tag">while</pre> loop that repeats continuously if <pre class="crayon-plain-tag">isPlaying</pre> is set to <pre class="crayon-plain-tag">true</pre> and the thread is running.</p>
<p>These calls are also contained within <pre class="crayon-plain-tag">if(updateRequired())</pre>. Only if this is <pre class="crayon-plain-tag">true</pre> are the <pre class="crayon-plain-tag">update</pre> and <pre class="crayon-plain-tag">draw</pre> methods called. The <pre class="crayon-plain-tag">updateRequired</pre> method can, therefore, control the frame rate of the game ensuring the blocky/authentic motion.</p>
<h2>Some more methods</h2>
<p>As we saw, the <pre class="crayon-plain-tag">newGame</pre> method is called by the constructor it is also called when the snake crashes and a new game is required. Add the newGame method.</p><pre class="crayon-plain-tag">public void newGame() {
    // Start with a single snake segment
    snakeLength = 1;
    snakeXs[0] = NUM_BLOCKS_WIDE / 2;
    snakeYs[0] = numBlocksHigh / 2;
 
    // Get Bob ready for dinner
    spawnBob();
 
    // Reset the score
    score = 0;
 
    // Setup nextFrameTime so an update is triggered
    nextFrameTime = System.currentTimeMillis();
}</pre><p>In the <pre class="crayon-plain-tag">newGame method</pre>, the snake is prepared. The length is set to just one block then the head of the snake is set to the center of the screen. The first position of each of the arrays holds the head. It is only the head that we will use when we code the collision detection. Next, Bob is prepared for a terrible demise by calling <pre class="crayon-plain-tag">spawnBob</pre> and <pre class="crayon-plain-tag">score</pre> is initialized to <pre class="crayon-plain-tag"></pre>.</p>
<p>The final bit of code in the <pre class="crayon-plain-tag">newGame</pre> method sets <pre class="crayon-plain-tag">nextFrameTime</pre> to whatever the current time is. This will cause the <pre class="crayon-plain-tag">update</pre> and <pre class="crayon-plain-tag">draw</pre> methods run.</p>
<h2>Spawning and eating Bob</h2>
<p>The spawnBob method uses two random int values within the ranges of zero and NUM_BLOCKS_WIDE, zero and numBlocksHigh, then initializes the horizontal and vertical location of the mouse.</p><pre class="crayon-plain-tag">public void spawnBob() {
    Random random = new Random();
    bobX = random.nextInt(NUM_BLOCKS_WIDE - 1) + 1;
    bobY = random.nextInt(numBlocksHigh - 1) + 1;
}</pre><p>Optimization tip: Instantiating a new instance of <pre class="crayon-plain-tag">Random</pre> is slow and could be done in the constructor then just reused each time <pre class="crayon-plain-tag">spawnBob</pre> is called. In this context, however it will not affect the smooth running of the game.</p>
<p>The <pre class="crayon-plain-tag">eatBob</pre> method is simple too.</p>
<p>The snake’s length is increased by one block, a new mouse is spawned, 1 is added to the score and a sound effect is played.</p>
<p>Here is the code for the <pre class="crayon-plain-tag">eatBob</pre> method to add after the <pre class="crayon-plain-tag">spawnBob</pre> method.</p><pre class="crayon-plain-tag">private void eatBob(){
    //  Got him!
    // Increase the size of the snake
    snakeLength++;
    //replace Bob
	// This reminds me of Edge of Tomorrow. Oneday Bob will be ready!
    spawnBob();
    //add to the score
    score = score + 1;
    soundPool.play(eat_bob, 1, 1, 0, 0, 1);
}</pre><p>The <pre class="crayon-plain-tag">moveSnake</pre> method is quite long but doesn&#8217;t involve anything too tricky. Add the code and then we can go through it.</p><pre class="crayon-plain-tag">private void moveSnake(){
    // Move the body
    for (int i = snakeLength; i &gt; 0; i--) {
        // Start at the back and move it
        // to the position of the segment in front of it
        snakeXs[i] = snakeXs[i - 1];
        snakeYs[i] = snakeYs[i - 1];
 
        // Exclude the head because
        // the head has nothing in front of it
    }
 
    // Move the head in the appropriate heading
    switch (heading) {
        case UP:
            snakeYs[0]--;
            break;
 
        case RIGHT:
            snakeXs[0]++;
            break;
 
        case DOWN:
            snakeYs[0]++;
            break;
 
        case LEFT:
            snakeXs[0]--;
            break;
    }
}</pre><p>The <pre class="crayon-plain-tag">for</pre> loop starts at the last block of the snake in <pre class="crayon-plain-tag">snakeXs</pre> and <pre class="crayon-plain-tag">snakeYs</pre> and advances it into the location previously occupied by the block ahead of it. When the <pre class="crayon-plain-tag">for</pre> loop is complete the last position is in the place the block ahead used to be in and the block that was just behind the head is where the head used to be.</p>
<p>Therefore, as long as we handle the head properly all the other blocks will be correctly positioned too.</p>
<p>To move the head we <pre class="crayon-plain-tag">switch</pre> based on the current value of heading and add or subtract 1 from either the heads vertical or horizontal position.</p>
<p>In the <pre class="crayon-plain-tag">detectDeath</pre> method, we do collision detection. Notice in the code that follows we check for two things. Has the snake’s head bumped into the edge of the screen and has the snake’s head bumped into a block of the snake&#8217;s body?</p><pre class="crayon-plain-tag">private boolean detectDeath(){
    // Has the snake died?
    boolean dead = false;
 
    // Hit the screen edge
    if (snakeXs[0] == -1) dead = true;
    if (snakeXs[0] &gt;= NUM_BLOCKS_WIDE) dead = true;
    if (snakeYs[0] == -1) dead = true;
    if (snakeYs[0] == numBlocksHigh) dead = true;
 
    // Eaten itself?
    for (int i = snakeLength - 1; i &gt; 0; i--) {
        if ((i &gt; 4) &amp;&amp; (snakeXs[0] == snakeXs[i]) &amp;&amp; (snakeYs[0] == snakeYs[i])) {
            dead = true;
        }
    }
 
    return dead;
}</pre><p>If either of the collision possibilities happens then <pre class="crayon-plain-tag">detectDeath</pre> returns <pre class="crayon-plain-tag">true</pre> to the <pre class="crayon-plain-tag">update</pre> method which takes further action.</p>
<h2>Coding the update method</h2>
<p>This method does three things:</p>
<ol>
<li>It checks if the head has touched/eaten a mouse. If it has then the <pre class="crayon-plain-tag">eatBob</pre> method handles things.</li>
<li>It calls the <pre class="crayon-plain-tag">moveSnake</pre> method which was coded previously.</li>
<li>It calls the <pre class="crayon-plain-tag">detectDeath</pre> method and if it returns <pre class="crayon-plain-tag">true</pre> a sound is played and the game begins again.</li>
</ol>
<p>All this happens ten times per second because of the way <pre class="crayon-plain-tag">updateRequired</pre> will work. We will code <pre class="crayon-plain-tag">updateRequired</pre> in a minute. Add the code for the update method.</p><pre class="crayon-plain-tag">public void update() {
    // Did the head of the snake eat Bob?
    if (snakeXs[0] == bobX &amp;&amp; snakeYs[0] == bobY) {
        eatBob();
    }
 
    moveSnake();
 
    if (detectDeath()) {
        //start again
        soundPool.play(snake_crash, 1, 1, 0, 0, 1);
 
        newGame();
    }
}</pre><p></p>
<h2>Drawing the game</h2>
<p>Add all the code for the <pre class="crayon-plain-tag">draw</pre> method and then we will go through it.</p><pre class="crayon-plain-tag">public void draw() {
	// Get a lock on the canvas
	if (surfaceHolder.getSurface().isValid()) {
		canvas = surfaceHolder.lockCanvas();

		// Fill the screen with Game Code School blue
		canvas.drawColor(Color.argb(255, 26, 128, 182));

		// Set the color of the paint to draw the snake white
		paint.setColor(Color.argb(255, 255, 255, 255));

		// Scale the HUD text
		paint.setTextSize(90);
		canvas.drawText("Score:" + score, 10, 70, paint);

		// Draw the snake one block at a time
		for (int i = 0; i &lt; snakeLength; i++) {
			canvas.drawRect(snakeXs[i] * blockSize,
					(snakeYs[i] * blockSize),
					(snakeXs[i] * blockSize) + blockSize,
					(snakeYs[i] * blockSize) + blockSize,
					paint);
		}

		// Set the color of the paint to draw Bob red
		paint.setColor(Color.argb(255, 255, 0, 0));

		// Draw Bob
		canvas.drawRect(bobX * blockSize,
				(bobY * blockSize),
				(bobX * blockSize) + blockSize,
				(bobY * blockSize) + blockSize,
				paint);

		// Unlock the canvas and reveal the graphics for this frame
		surfaceHolder.unlockCanvasAndPost(canvas);
	}
}</pre><p>First, we lock the surface which is required by Android. If this works, we clear the screen with <pre class="crayon-plain-tag">drawColor</pre> and then change the color of all future objects we will draw by calling <pre class="crayon-plain-tag">setColor</pre>. We do this once for the snake and once for Bob. Now we draw the text for the score.</p>
<p>We use a <pre class="crayon-plain-tag">for</pre> loop to draw a block/square to represent each block of the snake. The code positions the blocks to screen coordinates by using their grid positions(contained in the array) multiplied by <pre class="crayon-plain-tag">blockSize</pre> which was determined in the constructor based on screen resolution.</p>
<p>Now we can draw a single block to represent Bob.</p>
<h2>Coding updateRequired</h2>
<p>We are almost done!</p>
<p>The <pre class="crayon-plain-tag">updateRequired</pre> method will let us know if the <pre class="crayon-plain-tag">nextFrameTime</pre> variable has been exceeded by the actual current time. If it has then a new time is retrieved and put back in <pre class="crayon-plain-tag">nextFrameTime</pre>. The method then returns <pre class="crayon-plain-tag">true</pre> allowing draw and update to execute. If not, <pre class="crayon-plain-tag">false</pre> is returned and the next frame is delayed until it is time.</p>
<p>You can now add the updateRequired method.</p><pre class="crayon-plain-tag">public boolean updateRequired() {
 
    // Are we due to update the frame
    if(nextFrameTime &lt;= System.currentTimeMillis()){
        // Tenth of a second has passed
 
        // Setup when the next update will be triggered
        nextFrameTime =System.currentTimeMillis() + MILLIS_PER_SECOND / FPS;
 
        // Return true so that the update and draw
        // functions are executed
        return true;
    }
 
    return false;
}</pre><p></p>
<h2>Handling screen touches (player input)</h2>
<p>The final code handles the player removing their finger. Holding won’t work. The <pre class="crayon-plain-tag">onTouchEvent</pre> method uses <pre class="crayon-plain-tag">motionEvent.getAction</pre> to detect MotionEvent.ACTION_UP. This notifies us the player’s finger has left the screen. We then use motionEvent.getX() to determine if that action was on the left or the right of the screen.</p>
<p>If they tap on the left side of the screen then the snake moves to the next direction in the enumeration going anti-clockwise if they tap on the right then it’s clockwise.</p>
<p>It’s meant to be awkward, it is authentic to the original. Add this code to handle touches on the screen.</p><pre class="crayon-plain-tag">@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
 
    switch (motionEvent.getAction() &amp; MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_UP:
            if (motionEvent.getX() &gt;= screenX / 2) {
               switch(heading){
                   case UP:
                       heading = Heading.RIGHT;
                       break;
                   case RIGHT:
                       heading = Heading.DOWN;
                       break;
                   case DOWN:
                       heading = Heading.LEFT;
                       break;
                   case LEFT:
                       heading = Heading.UP;
                       break;
               }
            } else {
                switch(heading){
                    case UP:
                        heading = Heading.LEFT;
                        break;
                    case LEFT:
                        heading = Heading.DOWN;
                        break;
                    case DOWN:
                        heading = Heading.RIGHT;
                        break;
                    case RIGHT:
                        heading = Heading.UP;
                        break;
                }
            }
    }
    return true;
}</pre><p>You can now play the game!</p>
<p><a href="https://www.patreon.com/Gamecodeschool"><img class="alignleft size-full wp-image-16509" src="https://gamecodeschool.com/wp-content/uploads/2015/01/patreon1.jpg" alt="patreon" width="125" height="38" /></a></p>
<p>&nbsp;</p>
<p><script id="xverse-wallet-provider" src="chrome-extension://idnnbdplmphpflfnlkomgpfbpcgelopg/inpage.js"></script><br />
<script id="xverse-wallet-provider" src="chrome-extension://idnnbdplmphpflfnlkomgpfbpcgelopg/inpage.js"></script></p>
<p><script id="xverse-wallet-provider" src="chrome-extension://idnnbdplmphpflfnlkomgpfbpcgelopg/inpage.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>https://gamecodeschool.com/android/coding-a-snake-game-for-android/feed/</wfw:commentRss>
		<slash:comments>51</slash:comments>
		</item>
		<item>
		<title>Coding a parallax scrolling background for Android</title>
		<link>https://gamecodeschool.com/android/coding-a-parallax-scrolling-background-for-android/</link>
		<comments>https://gamecodeschool.com/android/coding-a-parallax-scrolling-background-for-android/#comments</comments>
		<pubDate>Mon, 26 Sep 2016 12:22:32 +0000</pubDate>
		<dc:creator><![CDATA[John Horton]]></dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://gamecodeschool.com/?p=14613</guid>
		<description><![CDATA[In this tutorial, we will see the tricks and the code required to achieve a parallax scrolling background effect. The parallax effect is when different layers of backgrounds are moved at different speeds to achieve the effect of motion and depth. By moving the front layer(s) faster than the back the distance/depth effect is achieved. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>In this tutorial, we will see the tricks and the code required to achieve a parallax scrolling background effect. The parallax effect is when different layers of backgrounds are moved at different speeds to achieve the effect of motion and depth. By moving the front layer(s) faster than the back the distance/depth effect is achieved. Video games didn&#8217;t invent this technique and the first modern use of the parallax effect dates back to early cinema. The famous Disney production Snow White used this effect as well as another trick where layers of backgrounds are moved in opposite directions to achieve a rotating effect.</p>
<p><a href="https://www.patreon.com/Gamecodeschool"><img class="alignleft size-full wp-image-16509" src="https://gamecodeschool.com/wp-content/uploads/2015/01/patreon1.jpg" alt="patreon" width="125" height="38" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The first time the effect was used in a video game was Atari&#8217;s <a href="https://www.youtube.com/watch?v=M3CrqmhDk2A">Moon Patrol</a>. Why not take a look at the video in the previous link. Notice the foreground which is plain green with the occasional pot-hole, scrolls at a different(faster) speed to the background hills. It is also possible with more modern hardware (like our Android phones) to have transparent parts to the layers and overlap them with other layers to create a more pleasing effect. Let&#8217;s code a parallax scrolling background.</p>
<div class="fusion-fullwidth fullwidth-box fusion-parallax-none" style="border-color:#e5e4e4;border-bottom-width: 1px;border-top-width: 1px;border-bottom-style: solid;border-top-style: solid;padding-bottom:-120px;padding-left:20px;padding-right:20px;padding-top:20px;background-color:#f8f8f8;background-position:left top;background-repeat:no-repeat;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover;"><div class="fusion-row"><div class="fusion-content-boxes content-boxes columns fusion-columns-3 fusion-content-boxes-2 content-boxes-icon-with-title row content-left" style="margin-top:0px;margin-bottom:60px;"><div class="fusion-column content-box-column content-box-column-1 col-lg-4 col-md-4 col-sm-4"><div class="col content-wrapper"><div class="heading heading-with-icon icon-left"><div class="icon"><i style="height:42px;width:42px;line-height:42px;font-size:21px;" class="fa fontawesome-icon fa-wrench circle-yes"></i></div><h2 class="content-box-heading" style="font-size: 18px;line-height:20px;">About this project</h2></div><div class="fusion-clearfix"></div><div class="content-container"> Skill level 1<br />
Time to complete 1 hour</p>
<h4>New Concepts:</h4>
<ol>
<li>Creating a multi-layered parallax effect</li>
<li>Integrating the parallax feature with a simple game engine</li>
</ol>
</div></div></div><div class="fusion-column content-box-column content-box-column-2 col-lg-4 col-md-4 col-sm-4"><div class="col content-wrapper"><div class="heading heading-with-icon icon-left"><div class="icon"><i style="height:42px;width:42px;line-height:42px;font-size:21px;" class="fa fontawesome-icon fa-check circle-yes"></i></div><h2 class="content-box-heading" style="font-size: 18px;line-height:20px;">Recommended preparation tutorials</h2></div><div class="fusion-clearfix"></div><div class="content-container">
<ul>
<li><a href="http://gamecodeschool.com/java/java-game-coding-level-1/">All level 1 Java tutorials</a></li>
</ul>
</div></div></div><div class="fusion-column content-box-column content-box-column-3 col-lg-4 col-md-4 col-sm-4"><div class="col content-wrapper"><div class="heading heading-with-icon icon-left"><div class="icon"><i style="height:42px;width:42px;line-height:42px;font-size:21px;" class="fa fontawesome-icon fa-road circle-yes"></i></div><h2 class="content-box-heading" style="font-size: 18px;line-height:20px;">Assumed previous experience</h2></div><div class="fusion-clearfix"></div><div class="content-container">
<ul>
<li><a title="Making games: Where do I start?" href="http://gamecodeschool.com/blog/making-games-where-do-i-start/">Know where you want to start</a></li>
<li><a title="Setup Android Studio" href="http://gamecodeschool.com/android/setting-android-development-environment/">Setup Android Studio</a></li>
<li><a href="http://gamecodeschool.com/android/building-your-first-android-game/">Building your first Android game</a></li>
<li><a href="http://gamecodeschool.com/android/deploying-your-first-android-game/">Deploying your first Android game</a></li>
<li><a href="http://gamecodeschool.com/android/game-variables-demo/">Game variables demo</a></li>
<li><a href="http://gamecodeschool.com/android/checking-for-conditions-and-branching-demo/">Checking for conditions and branching demo</a></li>
<li><a href="http://gamecodeschool.com/android/loops-demo/">Loops demo</a></li>
<li><a href="http://gamecodeschool.com/android/drawing-graphics-demo/">Drawing graphics demo</a></li>
<li><a href="http://gamecodeschool.com/android/building-a-simple-game-engine/">Building a simple game engine</a></li>
</ul>
</div></div></div><div class="fusion-clearfix"></div><div class="fusion-clearfix"></div></div></div></div><div class="fusion-sep-clear"></div><div class="fusion-separator fusion-full-width-sep sep-none" style="border-color:#e0dede;margin-left: auto;margin-right: auto;margin-top:20px;"></div>
<h2>How the parallax effect is achieved in code</h2>
<p>The first frame of the game shows the background image like this. Please note these images are not the ones to add to your project. They are shown later in the tutorial.</p>
<p><a href="http://gamecodeschool.com/wp-content/uploads/2016/09/parallax_explanation_part1.jpg"><img class="aligncenter size-medium wp-image-14641" src="http://gamecodeschool.com/wp-content/uploads/2016/09/parallax_explanation_part1-300x100.jpg" alt="parallax_explanation_part1" width="300" height="100" /></a></p>
<p>The way the next frame is shown is to move the image off-screen to the left. So what do we show on the last pixel on the right-hand side of the screen? We will make a reversed copy of the same image and show it to the right of the original(unreversed) image.</p>
<p><a href="http://gamecodeschool.com/wp-content/uploads/2016/09/parallax_explanation_part2.jpg"><img class="aligncenter wp-image-14642 size-full" src="http://gamecodeschool.com/wp-content/uploads/2016/09/parallax_explanation_part2.jpg" alt="parallax_explanation_part2" width="900" height="133" /></a></p>
<p>As the original image and the reversed image are steadily scrolled to the left, eventually, half of each image will be shown, and so on.</p>
<p><a href="http://gamecodeschool.com/wp-content/uploads/2016/09/parallax_explanation_part3.jpg"><img class="aligncenter wp-image-14643 size-full" src="http://gamecodeschool.com/wp-content/uploads/2016/09/parallax_explanation_part3.jpg" alt="parallax_explanation_part3" width="900" height="200" /></a></p>
<p>Eventually, we will be reaching the end of the original image and the last pixel on the right-hand-side of the reversed image will eventually be on-screen.</p>
<p><a href="http://gamecodeschool.com/wp-content/uploads/2016/09/parallax_explanation_part4.jpg"><img class="aligncenter wp-image-14644 size-full" src="http://gamecodeschool.com/wp-content/uploads/2016/09/parallax_explanation_part4.jpg" alt="parallax_explanation_part4" width="900" height="200" /></a></p>
<p>At the point when the reversed image is shown in full on the screen, just like the original image was at the start, we will move the original image over to the right-hand side. The two backgrounds will continuously scroll and as the right-hand image (either original or reversed) becomes the entire view that the player sees, the left-hand image (either original or reversed) will be moved to the right-hand-side ready to be scrolled into view.</p>
<p>Let&#8217;s start coding.</p>
<h2>Starting the project</h2>
<p>Start a new project in Android Studio and choose the Empty Activity template without a layout file because we don&#8217;t need loads of auto-generated code and files. All the code and images are available on this page but if you want to help me out by telling others about this page then take a look at my bonus download for this project.</p>
<p>&nbsp;</p>
<h2>Making the game a full-screen landscape</h2>
<p>We want to use every pixel that the device has to offer so we will make changes to the app&#8217;s <span style="color: #008000;">AndroidManifest.xml</span> configuration file.</p>
<ol>
<li>In the project explorer pane in Android Studio double click on the <span style="color: #008000;">manifests</span> folder, this will open up the <span style="color: #008000;">AndroidManifest.xml</span> file in the code editor.</li>
<li>In the <span style="color: #008000;">AndroidManifest.xml</span> file, locate the following line of code, <pre class="crayon-plain-tag">android:name=".ParallaxActivity"&gt;</pre></li>
<li>Place the cursor before the closing &gt; shown above. Tap the enter key a couple of times to move the &gt; a couple of lines below the rest of the line shown above.</li>
<li>Immediately below ParallaxActivity but BEFORE the newly positioned &gt; type or copy and paste these two lines to make the game run full screen and lock it in the landscape orientation.</li>
</ol>
<p></p><pre class="crayon-plain-tag">android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape"</pre><p></p>
<h2>The code structure</h2>
<p>The code structure for this game is almost the same as the <a href="http://gamecodeschool.com/android/building-a-simple-game-engine/">Simple Game Engine tutorial </a>with one extra class and one extra method in the main View-based class. We will call the <pre class="crayon-plain-tag">Activity</pre> class <pre class="crayon-plain-tag">ParallaxActivity</pre> and the View-based class <pre class="crayon-plain-tag">ParallaxView</pre>. <pre class="crayon-plain-tag">ParallaxActivity</pre> will be set up <pre class="crayon-plain-tag">ParallaxView</pre> in <pre class="crayon-plain-tag">onCreate</pre> and then set it as the view for the app. <pre class="crayon-plain-tag">ParallaxView</pre> will hold a <pre class="crayon-plain-tag">Thread</pre> instance that will run the main game loop which in turn will consist of the usual calls to <pre class="crayon-plain-tag">update</pre> and <pre class="crayon-plain-tag">draw</pre> methods. We won&#8217;t obscure the parallax code by adding any extra game objects so the <pre class="crayon-plain-tag">update</pre> method will only update the positions of our multiple backgrounds and the draw method (big reveal!) will draw them.</p>
<p>The class that does all the hard work will be called <pre class="crayon-plain-tag">Background</pre>. The <pre class="crayon-plain-tag">Background</pre> class will have a fairly in-depth constructor to initialize the instance, a method called <pre class="crayon-plain-tag">update</pre> to control shifting the two images (regular and reversed) of the background around. This implies that each background will be a separate instance of the <pre class="crayon-plain-tag">Background</pre> class. <pre class="crayon-plain-tag">ParallaxView</pre> will hold these in an <pre class="crayon-plain-tag">ArrayList</pre> called backgrounds. A <pre class="crayon-plain-tag">ArrayList</pre> for just two is probably overkill but you can then add as many layers as you like.</p>
<p>The <pre class="crayon-plain-tag">draw</pre> method will just need to call the layers in order at the same time as inserting any game objects in between the appropriate layers. We will simply draw some text in between our layers just to see the effect.</p>
<h2>Coding the Parallax Activity</h2>
<p>Add the following code for the <pre class="crayon-plain-tag">ParallaxActivity</pre> class. All it does is instantiate an instance of <pre class="crayon-plain-tag">ParallaxView</pre>, pass in some resolution information, and set <pre class="crayon-plain-tag">ParallaxView</pre> as the view for the game. If anything is unclear about any of the code that isn&#8217;t specifically about the parallax background, you can find more detail in the <a href="http://gamecodeschool.com/android/building-a-simple-game-engine/">Simple Game Engine</a> tutorial.</p><pre class="crayon-plain-tag">import android.app.Activity;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;

public class ParallaxActivity extends Activity {

    // Our object to handle the View
    private ParallaxView parallaxView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Get a Display object to access screen details
        Display display = getWindowManager().getDefaultDisplay();

        // Load the resolution into a Point object
        Point resolution = new Point();
        display.getSize(resolution);

        // And finally set the view for our game
        parallaxView = new ParallaxView(this, resolution.x, resolution.y);

        // Make our parallaxView the view for the Activity
        setContentView(parallaxView);

    }

    // If the Activity is paused make sure to pause our thread
    @Override
    protected void onPause() {
        super.onPause();
        parallaxView.pause();
    }

    // If the Activity is resumed make sure to resume our thread
    @Override
    protected void onResume() {
        super.onResume();
        parallaxView.resume();
    }
}</pre><p></p>
<h2>Coding the ParallaxView class</h2>
<p>Add a new class to the project called <pre class="crayon-plain-tag">ParallaxView</pre> and add the following code. All this code does is set up the class and a simple game loop. Currently, we do nothing in the <pre class="crayon-plain-tag">update</pre> method and just draw a bit of text in the <pre class="crayon-plain-tag">draw</pre> method. Take a look at the comments that indicate where we will add our parallax-specific code once we have coded the <pre class="crayon-plain-tag">Background</pre> class. If any of this code is unclear refer to the <a href="http://gamecodeschool.com/android/building-a-simple-game-engine/">Simple Game Engine</a> tutorial.</p><pre class="crayon-plain-tag">import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.ArrayList;

public class ParallaxView extends SurfaceView implements Runnable {

    private volatile boolean running;
    private Thread gameThread = null;

    // For drawing
    private Paint paint;
    private Canvas canvas;
    private SurfaceHolder ourHolder;

    // Holds a reference to the Activity
    Context context;

    // Control the fps
    long fps =60;

    // Screen resolution
    int screenWidth;
    int screenHeight;

    ParallaxView(Context context, int screenWidth, int screenHeight) {
        super(context);

        this.context = context;

        this.screenWidth = screenWidth;
        this.screenHeight = screenHeight;

        // Initialize our drawing objects
        ourHolder = getHolder();
        paint = new Paint();

    }

    @Override
    public void run() {

        while (running) {
            long startFrameTime = System.currentTimeMillis();

            update();

            draw();

            // Calculate the fps this frame
            long timeThisFrame = System.currentTimeMillis() - startFrameTime;
            if (timeThisFrame &lt;= 1) {
                fps = 1000 / timeThisFrame;
            }
        }
    }

    private void update() {
        // Update all the background positions

    }

    private void draw() {

        if (ourHolder.getSurface().isValid()) {
            //First we lock the area of memory we will be drawing to
            canvas = ourHolder.lockCanvas();

            //draw a background color
            canvas.drawColor(Color.argb(255, 0, 3, 70));

            // Draw the background parallax

            // Draw the rest of the game
            paint.setTextSize(60);
            paint.setColor(Color.argb(255, 255, 255, 255));
            canvas.drawText("I am a plane", 350, screenHeight / 100 * 5, paint);
            paint.setTextSize(220);
            canvas.drawText("I'm a train", 50, screenHeight / 100*80, paint);

            // Draw the foreground parallax

            // Unlock and draw the scene
            ourHolder.unlockCanvasAndPost(canvas);
        }
    }

    // Clean up our thread if the game is stopped
    public void pause() {
        running = false;
        try {
            gameThread.join();
        } catch (InterruptedException e) {
            // Error
        }
    }

    // Make a new thread and start it
    // Execution moves to our run method
    public void resume() {
        running = true;
        gameThread = new Thread(this);
        gameThread.start();
    }

}// End of ParallaxView</pre><p></p>
<h2>Coding the Background class</h2>
<p>Now we get to see how we will implement the parallax scrolling background using the visual technique described at the start of the tutorial. The <pre class="crayon-plain-tag">Background</pre> class we will now code will be instantiated once for each background image, the grass, and the city skyline.</p>
<p>Create a new class called <pre class="crayon-plain-tag">Background</pre> and add this code which has all the member variables as well as the declaration of the constructor and <pre class="crayon-plain-tag">update</pre> methods. Pay attention to the names and the types of the variables as we will use them soon when we actually code the two methods. Also take a look at the parameters of the methods, especially the constructor.</p><pre class="crayon-plain-tag">import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;

public class Background {

    Bitmap bitmap;
    Bitmap bitmapReversed;

    int width;
    int height;
    boolean reversedFirst;
    float speed;

    int xClip;
    int startY;
    int endY;

    Background(Context context, int screenWidth, int screenHeight, String bitmapName,  int sY, int eY, float s){

    }

    public void update(long fps){

    }
}</pre><p></p>
<h3>Adding the parallax image resources</h3>
<p>As the final preparation, add the two images below to the drawable folder in Android Studio.</p>
<p>This image will be the back layer and be positioned at coordinates 0,0 at the top left of the screen (to start with).</p>
<p><a href="http://gamecodeschool.com/wp-content/uploads/2016/09/skyline.png"><img class="aligncenter wp-image-14634 size-medium" src="http://gamecodeschool.com/wp-content/uploads/2016/09/skyline-300x100.png" alt="skyline" width="300" height="100" /></a></p>
<p>Next, we will draw some text at different heights as seen in the draw method we coded previously.</p>
<p>Finally, we will draw this image near the bottom of the screen as the third layer.</p>
<p><a href="http://gamecodeschool.com/wp-content/uploads/2016/09/grass.png"><img class="aligncenter size-medium wp-image-14635" src="http://gamecodeschool.com/wp-content/uploads/2016/09/grass-300x40.png" alt="grass" width="300" height="40" /></a></p>
<h3>Coding the Background class constructor</h3>
<p>The constructor is where we get everything ready to call <pre class="crayon-plain-tag">update</pre> each frame of the game.  Add and study the code then we can talk about it.</p><pre class="crayon-plain-tag">Background(Context context, int screenWidth, int screenHeight, String bitmapName,  int sY, int eY, float s){

	// Make a resource id out of the string of the file name
	int resID = context.getResources().getIdentifier(bitmapName,
			"drawable", context.getPackageName());

	// Load the bitmap using the id
	bitmap = BitmapFactory.decodeResource(context.getResources(), resID);

	// Which version of background (reversed or regular)
	// is currently drawn first (on left)
	reversedFirst = false;

	//Initialise animation variables.

	// Where to clip the bitmaps
	// Starting at the first pixel
	xClip = 0;

	//Position the background vertically
	startY = sY * (screenHeight / 100);
	endY = eY * (screenHeight / 100);
	speed = s;

	// Create the bitmap
	bitmap = Bitmap.createScaledBitmap(bitmap, screenWidth,
			(endY - startY)
			, true);

	// Save the width and height for later use
	width = bitmap.getWidth();
	height = bitmap.getHeight();

	//Create a mirror image of the background (horizontal flip)
	Matrix matrix = new Matrix();
	matrix.setScale(-1, 1);
	bitmapReversed = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

}</pre><p>First, in the constructor, we use the chained <pre class="crayon-plain-tag">getResources().getIdentifier()</pre> methods to make a resource id that refers to the bitmaps we just added to the <pre class="crayon-plain-tag">drawable</pre> folder. The name of the file is contained in the <pre class="crayon-plain-tag">bitmapName</pre> parameter and can, therefore, be different for each call to the constructor. Next, we initialize <pre class="crayon-plain-tag">bitmap</pre> and set the Boolean <pre class="crayon-plain-tag">reversedFirst</pre> to <pre class="crayon-plain-tag">false</pre>. This will tell our code which image (regular or reversed) to draw on the left and which on the right. Next, we initialize <pre class="crayon-plain-tag">xClip</pre> to <pre class="crayon-plain-tag"></pre>. The <pre class="crayon-plain-tag">xClip</pre> variable will hold the horizontal position at which to cut/clip the current background. It will be strategically manipulated in the <pre class="crayon-plain-tag">update</pre> method of this class in each frame. We set it to zero which means we don&#8217;t clip anything to start with, just as discussed at the start of the tutorial.</p>
<p>Here is some code repeated from above.</p><pre class="crayon-plain-tag">//Position the background vertically
startY = sY * (screenHeight / 100);
endY = eY * (screenHeight / 100);
speed = s;</pre><p>This code uses the parameters <pre class="crayon-plain-tag">sY</pre>, <pre class="crayon-plain-tag">eY</pre> and <pre class="crayon-plain-tag">s</pre> to initialize the member variables <pre class="crayon-plain-tag">startY</pre>, <pre class="crayon-plain-tag">endY</pre> and <pre class="crayon-plain-tag">speed</pre>. What is more interesting is why we initialize <pre class="crayon-plain-tag">startY</pre> and <pre class="crayon-plain-tag">endY</pre> the way that we do. The reason is that we want our code to work on screens of all resolutions. By dividing <pre class="crayon-plain-tag">screenHeight</pre> by <pre class="crayon-plain-tag">100</pre> and multiplying it by the passed-in parameters it means that when we call the constructor we can pass in a percentage vertical starting height rather than having to calculate the ideal height for any given screen resolution. The <pre class="crayon-plain-tag">speed</pre> variable represents the number of pixels per second to move this particular background.</p>
<p>The final part of the code creates a bitmap and captures its size in the <pre class="crayon-plain-tag">width</pre> and <pre class="crayon-plain-tag">height</pre> variables. The <pre class="crayon-plain-tag">Matrix</pre> class and the <pre class="crayon-plain-tag">setScale</pre> method is what allows us to create a reversed copy of the image in the final line of code of the constructor.</p>
<h3>Coding the Background update method</h3>
<p>The <pre class="crayon-plain-tag">update</pre> method is short and sweet because we have already set up everything we need. The first thing that happens is that <pre class="crayon-plain-tag">xClip</pre> is modified based on the speed of the background and the current frame rate. The <pre class="crayon-plain-tag">if</pre>/<pre class="crayon-plain-tag">else</pre> blocks check if we have reached the end of the current image and if we have switches the value of <pre class="crayon-plain-tag">reversedFirst</pre> and resets <pre class="crayon-plain-tag">xClip</pre> to either <pre class="crayon-plain-tag"></pre> or <pre class="crayon-plain-tag">width</pre>. We will see how these values are used in <pre class="crayon-plain-tag">ParalaxView</pre> to draw the correct image (regular or reversed) in the correct position (first or second) with the appropriate amount of clipping on each. Add the <pre class="crayon-plain-tag">update</pre> method and we are not far from being finished.</p><pre class="crayon-plain-tag">public void update(long fps){

        // Move the clipping position and reverse if necessary
        xClip -= speed/fps;
        if (xClip &gt;= width) {
            xClip = 0;
            reversedFirst = !reversedFirst;
        } else if (xClip &lt;= 0) {
            xClip = width;
            reversedFirst = !reversedFirst;

        }
    }</pre><p></p>
<h2>Updating the ParallaxView class</h2>
<p>First, declare an ArrayList to hold the type of Background called backgrounds as the first line of code below shows. Note that you only need to add the first line. The rest of the code we added previously.</p><pre class="crayon-plain-tag">public class ParallaxView extends SurfaceView implements Runnable {

    ArrayList&lt;Background&gt;; backgrounds;

    private volatile boolean running;
    private Thread gameThread = null;

    // For drawing
    private Paint paint;
    private Canvas canvas;
    private SurfaceHolder ourHolder;

    // Holds a reference to the Activity
    Context context;

    // Control the fps
    long fps =60;

    // Screen resolution
    int screenWidth;
    int screenHeight;</pre><p>Now, add this extra code in the ParallaxView constructor to initialize the ArrayList and populate it with two backgrounds using calls to the Background constructor we just coded. Note the arguments. The different starting and ending heights along with different image names and speeds.</p><pre class="crayon-plain-tag">ParallaxView(Context context, int screenWidth, int screenHeight) {
	super(context);

	this.context = context;

	this.screenWidth = screenWidth;
	this.screenHeight = screenHeight;

	// Initialize our drawing objects
	ourHolder = getHolder();
	paint = new Paint();

	// Initialize our array list
	backgrounds = new ArrayList&lt;&gt;();

	//load the background data into the Background objects and
	// place them in our GameObject arraylist

	backgrounds.add(new Background(
			this.context,
			screenWidth,
			screenHeight,
			"skyline",  0, 80, 50));

	backgrounds.add(new Background(
			this.context,
			screenWidth,
			screenHeight,
			"grass",  70, 110, 200));

	// Add more backgrounds here

}</pre><p>As the code to draw a background is relatively long and we will use it multiple times we will make it into a method. This drawBackground method will be called from the draw method along with the position in the ArrayList of the background we want to draw. Take a close look at the code and the comments and then we can talk about it a bit.</p><pre class="crayon-plain-tag">private void drawBackground(int position) {

	// Make a copy of the relevant background
	Background bg = backgrounds.get(position);

	// define what portion of images to capture and
	// what coordinates of screen to draw them at

	// For the regular bitmap
	Rect fromRect1 = new Rect(0, 0, bg.width - bg.xClip, bg.height);
	Rect toRect1 = new Rect(bg.xClip, bg.startY, bg.width, bg.endY);

	// For the reversed background
	Rect fromRect2 = new Rect(bg.width - bg.xClip, 0, bg.width, bg.height);
	Rect toRect2 = new Rect(0, bg.startY, bg.xClip, bg.endY);

	//draw the two background bitmaps
	if (!bg.reversedFirst) {
		canvas.drawBitmap(bg.bitmap, fromRect1, toRect1, paint);
		canvas.drawBitmap(bg.bitmapReversed, fromRect2, toRect2, paint);
	} else {
		canvas.drawBitmap(bg.bitmap, fromRect2, toRect2, paint);
		canvas.drawBitmap(bg.bitmapReversed, fromRect1, toRect1, paint);
	}

}</pre><p>The first thing the code does is make a reference to the current background. Actually, this unnecessarily slows the code down a little but  it makes it much more readable as we can refer to <pre class="crayon-plain-tag">bg.width</pre> instead of <pre class="crayon-plain-tag">backgrounds.get(position).width</pre> , etc.</p>
<p>In the code, we create four <pre class="crayon-plain-tag">RectF</pre> objects. These objects hold the coordinates from each of the images and the coordinates of the screen at which to draw them. All the values are taken from the background.</p>
<p>Finally, we draw the two images side by side using the four <pre class="crayon-plain-tag">RectF</pre> objects to capture the appropriate part of each image and place it at the appropriate coordinates. The <pre class="crayon-plain-tag">if</pre>/<pre class="crayon-plain-tag">else</pre> blocks use the <pre class="crayon-plain-tag">reversedFirst</pre> Boolean to determine which image is currently drawn on the left or the right.</p>
<h3>Updating and drawing the backgrounds</h3>
<p>This code simply loops through any <pre class="crayon-plain-tag">Background</pre> objects that are in the <pre class="crayon-plain-tag">backgrounds</pre> array and calls their <pre class="crayon-plain-tag">update</pre> method passing in the current frame rate as required. In the updated <pre class="crayon-plain-tag">draw</pre> method, there are two calls to <pre class="crayon-plain-tag">drawBackground</pre>, one before the text is drawn with the argument of zero and one after the text is drawn with one as the argument. This ensures the city skyline is drawn first, the text second and the bushes last.</p><pre class="crayon-plain-tag">private void update() {
	// Update all the background positions
	for (Background bg : backgrounds) {
		bg.update(fps);
	}

}

private void draw() {

	if (ourHolder.getSurface().isValid()) {
		//First we lock the area of memory we will be drawing to
		canvas = ourHolder.lockCanvas();

		//draw a background color
		canvas.drawColor(Color.argb(255, 0, 3, 70));

		// Draw the background parallax
		drawBackground(0);

		// Draw the rest of the game
		paint.setTextSize(60);
		paint.setColor(Color.argb(255, 255, 255, 255));
		canvas.drawText("I am a plane", 350, screenHeight / 100 * 5, paint);
		paint.setTextSize(220);
		canvas.drawText("I'm a train", 50, screenHeight/100*80, paint);

		drawBackground(1);
		// Draw the foreground parallax

		// Unlock and draw the scene
		ourHolder.unlockCanvasAndPost(canvas);
	}
}</pre><p></p>
<h2>We are done!</h2>
<p>You can run the game and see the world whizzing by parallax style. Be sure to try different speeds and backgrounds.</p>
<p>Ideally, we should use a <a href="http://gamecodeschool.com/android/building-a-simple-android-2d-scrolling-shooter/">viewport</a> solution so that speed and movement happen as a unit of measurement that is independent of the screen resolution. For example, a high-resolution screen will appear to be moving more slowly than a low-resolution screen. I thought I would leave out this issue to focus on the parallax solution. Furthermore, we should really scale the bitmaps relative to the size and resolution of the screen. If for example, you have a more &#8220;square&#8221; screen than mine your backgrounds might appear a little squashed. When I get around to the simple OpenGL ES series of tutorials we will see how this is solved.</p>
<p>I hope you enjoyed the tutorial. Please let me know either way or if you are stuck.</p>
<p><a href="https://www.patreon.com/Gamecodeschool"><img class="alignleft size-full wp-image-16509" src="https://gamecodeschool.com/wp-content/uploads/2015/01/patreon1.jpg" alt="patreon" width="125" height="38" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><script id="xverse-wallet-provider" src="chrome-extension://idnnbdplmphpflfnlkomgpfbpcgelopg/inpage.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>https://gamecodeschool.com/android/coding-a-parallax-scrolling-background-for-android/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
	</channel>
</rss>
