-
Game Development Tutorial Unit 4 - Day 5: The Android Game Framework
-
(Updated for Android 5.0)
Welcome to Day 5 of Unit 4: Android Game Development.
In the previous 4 lessons, we discussed much about Android development. Now, we begin building our game framework.
Our plan is to create a general framework that allows our game to interact smoothly with Android. Once we have done that, you will be able to create your own games on top of this framework, and I will demonstrate how to do that by developing the Robot game (from the previous Units) on Android.
As this framework is very general, you can write it once, add to it, and reuse it in various projects.
In the previous 4 lessons, we discussed much about Android development. Now, we begin building our game framework.
Our plan is to create a general framework that allows our game to interact smoothly with Android. Once we have done that, you will be able to create your own games on top of this framework, and I will demonstrate how to do that by developing the Robot game (from the previous Units) on Android.
As this framework is very general, you can write it once, add to it, and reuse it in various projects.
Our Framework is Based on 'The Beginner's Guide to Android Game Development'
![]() |
The framework developed below is reproduced from a book that I have written called The Beginner's Guide to Android Game Development. If you would like to explore the topics covered here in much more depth, I would really appreciate it if you purchased a copy. I believe that it will greatly aid your understanding of the why behind the code we write.
Click Here to Learn More Click Here for E-Book Information Note 2: The source code in the book (all downloadable for free at jamescho7.com/book) is available under the open source MIT License. This means that you can use the code without restriction in your games, in your blogs, etc. Please click here to learn more about the license. |
Notes on changes: Previously, this tutorial series used an open source framework from a different book on this topic (Beginning Android Games by Mario Zechner of LibGDX) as I had used it when creating my first Android game. There was a bit of misunderstanding previously where Mario mistakenly thought that I was not giving him credit, but we were able to clear things up. Since then, I have been approached to write my own book on this topic, so I did, and I created a brand new framework in the process which is developed below.
For anyone who wants to learn more about Android game development, Mario's book remains a great resource with a slightly different emphasis from my own. My book aims to help the absolute beginner create things one step at a time, starting from the simplest programs. Mario's book, on the other hand, is slightly more technical and assumes that you have a strong background in Java, but it really goes into great detail to give you complete control over each component of the games you make.
For anyone who wants to learn more about Android game development, Mario's book remains a great resource with a slightly different emphasis from my own. My book aims to help the absolute beginner create things one step at a time, starting from the simplest programs. Mario's book, on the other hand, is slightly more technical and assumes that you have a strong background in Java, but it really goes into great detail to give you complete control over each component of the games you make.
Creating the Game Project
We will begin by creating a generic Android Game project (that we can use as the basic structure of all our future games).
1. Open up Eclipse.
2. Go to File >> New >> Android Application Project.
3. Enter the Application Name: AndroidGame, Project Name: AndroidGame, and Package Name: com.yourname.androidgame. Press next.
1. Open up Eclipse.
2. Go to File >> New >> Android Application Project.
3. Enter the Application Name: AndroidGame, Project Name: AndroidGame, and Package Name: com.yourname.androidgame. Press next.
4. Uncheck the Create custom launcher icon and Create activity options in the next page. As we will not be running this project as an application, we do not need either.
Now we are ready to begin developing.
Creating the Interface
Our Android game will require the following interfaces:
1. A Game interface that ties every other interface together.
2. An Audio Interface that relies on (3.) a Music interface (for large audio files) and (4.) a Sound interface (for small audio files).
5. A Graphics interface that relies on (6.) an Image interface.
7. A Screen interface for displaying/changing game screens.
8. A FileIO interface for reading and writing files.
9. An Input Interface to take user input.
We will also create A Pool class to collect objects together.
Some of the code developed here is self-explanatory, the purpose of the some others can be deduced with some thought, and the rest might require a thorough explanation. As I demonstrate what goes into each interface, I will only explain what I feel is new and worth explaining.
1. A Game interface that ties every other interface together.
2. An Audio Interface that relies on (3.) a Music interface (for large audio files) and (4.) a Sound interface (for small audio files).
5. A Graphics interface that relies on (6.) an Image interface.
7. A Screen interface for displaying/changing game screens.
8. A FileIO interface for reading and writing files.
9. An Input Interface to take user input.
We will also create A Pool class to collect objects together.
Some of the code developed here is self-explanatory, the purpose of the some others can be deduced with some thought, and the rest might require a thorough explanation. As I demonstrate what goes into each interface, I will only explain what I feel is new and worth explaining.
1. The "Game" Interface
In your AndroidGame project's src folder, create a new Package. Name it com.yourname.framework.
This is where our interface (all 10 classes) will be stored.
Right click on this package and create a new Java Interface. Call it Game.
The contents of the "Game" Interface appear below.
Warning: All the code samples that follow assume that you have the package com.jamescho.framework.
If you use your own name, you will have to edit the "package" section in each class!
ALSO: As a general rule, don't worry about errors! Wait until you have created every single class inside the interface before you worry about fixing the imports!
If you use your own name, you will have to edit the "package" section in each class!
ALSO: As a general rule, don't worry about errors! Wait until you have created every single class inside the interface before you worry about fixing the imports!
package com.jamescho.framework;
public interface Game {
public Audio getAudio();
public Input getInput();
public FileIO getFileIO();
public Graphics getGraphics();
public void setScreen(Screen screen);
public Screen getCurrentScreen();
public Screen getInitScreen();
}
public interface Game {
public Audio getAudio();
public Input getInput();
public FileIO getFileIO();
public Graphics getGraphics();
public void setScreen(Screen screen);
public Screen getCurrentScreen();
public Screen getInitScreen();
}
Once you create the Game Interface as above, you will get several errors. An easy way to fix this is to put your mouse over each of the seven errors and apply a quick fix.
Select the "Create interface..." quick fix for the first five errors (the last three are all Screen errors) (It does not really matter whether you create a Class or Interface because they are both .java files, and it's the content that determines the type).
HOWEVER: DO NOT import (i.e. do NOT press Ctrl + Shift + O), as that will introduce many errors to your code later on.
When you have done all five, you will have created the following interfaces:
Audio, Input, FileIO, Graphics, Screen.
We will now discuss them in the reverse order.
HOWEVER: DO NOT import (i.e. do NOT press Ctrl + Shift + O), as that will introduce many errors to your code later on.
When you have done all five, you will have created the following interfaces:
Audio, Input, FileIO, Graphics, Screen.
We will now discuss them in the reverse order.
2. THE "Screen" Class
package com.jamescho.framework;
public abstract class Screen {
protected final Game game;
public Screen(Game game) {
this.game = game;
}
public abstract void update(float deltaTime);
public abstract void paint(float deltaTime);
public abstract void pause();
public abstract void resume();
public abstract void dispose();
public abstract void backButton();
}
public abstract class Screen {
protected final Game game;
public Screen(Game game) {
this.game = game;
}
public abstract void update(float deltaTime);
public abstract void paint(float deltaTime);
public abstract void pause();
public abstract void resume();
public abstract void dispose();
public abstract void backButton();
}
This is an abstract class (not really an interface, which you cannot use to create objects with (although you can subclass it). It contains abstract methods (which state the parameters but are not implemented). Some of these methods will be familiar, such as paint and update (they are named as they were in Units 2 and 3). They now have a parameter called deltaTime (which takes into account how much time passed since the last time the method was called) that we can use to create framerate independent movement (more on this later).
3. The "Graphics" Interface
package com.jamescho.framework;
import android.graphics.Paint;
public interface Graphics {
public static enum ImageFormat {
ARGB8888, ARGB4444, RGB565
}
public Image newImage(String fileName, ImageFormat format);
public void clearScreen(int color);
public void drawLine(int x, int y, int x2, int y2, int color);
public void drawRect(int x, int y, int width, int height, int color);
public void drawImage(Image image, int x, int y, int srcX, int srcY,
int srcWidth, int srcHeight);
public void drawImage(Image Image, int x, int y);
void drawString(String text, int x, int y, Paint paint);
public int getWidth();
public int getHeight();
public void drawARGB(int i, int j, int k, int l);
}
import android.graphics.Paint;
public interface Graphics {
public static enum ImageFormat {
ARGB8888, ARGB4444, RGB565
}
public Image newImage(String fileName, ImageFormat format);
public void clearScreen(int color);
public void drawLine(int x, int y, int x2, int y2, int color);
public void drawRect(int x, int y, int width, int height, int color);
public void drawImage(Image image, int x, int y, int srcX, int srcY,
int srcWidth, int srcHeight);
public void drawImage(Image Image, int x, int y);
void drawString(String text, int x, int y, Paint paint);
public int getWidth();
public int getHeight();
public void drawARGB(int i, int j, int k, int l);
}
The Graphics interface contains many methods that we will use to draw images to the screen. It has the familiar drawImage method and many other self explanatory methods. clearScreen fills the entire screen with a color. ARGB in the last method stands for Alpha, Red, Green, and Blue. Using four parameters, you can specify an RGB color and an Alpha value (opacity).
DO NOT IMPORT IMAGE. IT WILL BE CREATED LATER.
DO NOT IMPORT IMAGE. IT WILL BE CREATED LATER.
4. The "FileIO" Interface
package com.jamescho.framework;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.SharedPreferences;
public interface FileIO {
public InputStream readFile(String file) throws IOException;
public OutputStream writeFile(String file) throws IOException;
public InputStream readAsset(String file) throws IOException;
public SharedPreferences getSharedPref();
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.SharedPreferences;
public interface FileIO {
public InputStream readFile(String file) throws IOException;
public OutputStream writeFile(String file) throws IOException;
public InputStream readAsset(String file) throws IOException;
public SharedPreferences getSharedPref();
}
This interface is very straightforward. We handle IOException so that we do not need a try and catch statement.
SharedPreferences is an Android interface that lets you access and modify preference data. That is all you will need to know for now.
SharedPreferences is an Android interface that lets you access and modify preference data. That is all you will need to know for now.
5. The "Input" Interface
package com.jamescho.framework;
import java.util.List;
public interface Input {
public static class TouchEvent {
public static final int TOUCH_DOWN = 0;
public static final int TOUCH_UP = 1;
public static final int TOUCH_DRAGGED = 2;
public static final int TOUCH_HOLD = 3;
public int type;
public int x, y;
public int pointer;
}
public boolean isTouchDown(int pointer);
public int getTouchX(int pointer);
public int getTouchY(int pointer);
public List<TouchEvent> getTouchEvents();
}
import java.util.List;
public interface Input {
public static class TouchEvent {
public static final int TOUCH_DOWN = 0;
public static final int TOUCH_UP = 1;
public static final int TOUCH_DRAGGED = 2;
public static final int TOUCH_HOLD = 3;
public int type;
public int x, y;
public int pointer;
}
public boolean isTouchDown(int pointer);
public int getTouchX(int pointer);
public int getTouchY(int pointer);
public List<TouchEvent> getTouchEvents();
}
The Input interface keeps track of touch events, with variables x, y, type (touch down, touch up, etc), and pointer (each point of contact on screen - Android supports multi-touch).
6. The "Audio" Interface
package com.jamescho.framework;
public interface Audio {
public Music createMusic(String file);
public Sound createSound(String file);
}
public interface Audio {
public Music createMusic(String file);
public Sound createSound(String file);
}
This is the shortest interface of the day (except perhaps Sound). It uses the Music and Sound interfaces to create audio objects for use.
You will get two errors: Music and Sound cannot be resolved. Apply the Quick Fix: "Create Interface..." for both. This will create the Music.java and Sound.java files that you can edit.
You will get two errors: Music and Sound cannot be resolved. Apply the Quick Fix: "Create Interface..." for both. This will create the Music.java and Sound.java files that you can edit.
7. The "Music" Interface
package com.jamescho.framework;
public interface Music {
public void play();
public void stop();
public void pause();
public void setLooping(boolean looping);
public void setVolume(float volume);
public boolean isPlaying();
public boolean isStopped();
public boolean isLooping();
public void dispose();
void seekBegin();
}
public interface Music {
public void play();
public void stop();
public void pause();
public void setLooping(boolean looping);
public void setVolume(float volume);
public boolean isPlaying();
public boolean isStopped();
public boolean isLooping();
public void dispose();
void seekBegin();
}
This is a very straightforward interface. There are the familiar play, stop and pause methods, as well as ways to change volume, set looping (repeating an audio file), along with methods of checking the current state of the file. The dispose method removes the music file (allows it to be removed from Memory).
8. the "Sound" Interface
package com.jamescho.framework;
public interface Sound {
public void play(float volume);
public void dispose();
}
public interface Sound {
public void play(float volume);
public void dispose();
}
The Sound interface just has a play and dispose method.
9. the "Image" Interface
Within the same Package, create a new Interface. Name it Image.
package com.jamescho.framework;
import com.jamescho.framework.Graphics.ImageFormat;
public interface Image {
public int getWidth();
public int getHeight();
public ImageFormat getFormat();
public void dispose();
}
import com.jamescho.framework.Graphics.ImageFormat;
public interface Image {
public int getWidth();
public int getHeight();
public ImageFormat getFormat();
public void dispose();
}
This Image interface makes use of the ImageFormat from the Graphics interface. You might find this a bit odd as we are creating ints using methods. This will become more clear within context in the next lesson.
10. The Pool Class
Also within the same package, create a Pool Class as follows:
package com.jamescho.framework;
import java.util.ArrayList;
import java.util.List;
public class Pool<T> {
public interface PoolObjectFactory<T> {
public T createObject();
}
private final List<T> freeObjects;
private final PoolObjectFactory<T> factory;
private final int maxSize;
public Pool(PoolObjectFactory<T> factory, int maxSize) {
this.factory = factory;
this.maxSize = maxSize;
this.freeObjects = new ArrayList<T>(maxSize);
}
public T newObject() {
T object = null;
if (freeObjects.size() == 0)
object = factory.createObject();
else
object = freeObjects.remove(freeObjects.size() - 1);
return object;
}
public void free(T object) {
if (freeObjects.size() < maxSize)
freeObjects.add(object);
}
}
import java.util.ArrayList;
import java.util.List;
public class Pool<T> {
public interface PoolObjectFactory<T> {
public T createObject();
}
private final List<T> freeObjects;
private final PoolObjectFactory<T> factory;
private final int maxSize;
public Pool(PoolObjectFactory<T> factory, int maxSize) {
this.factory = factory;
this.maxSize = maxSize;
this.freeObjects = new ArrayList<T>(maxSize);
}
public T newObject() {
T object = null;
if (freeObjects.size() == 0)
object = factory.createObject();
else
object = freeObjects.remove(freeObjects.size() - 1);
return object;
}
public void free(T object) {
if (freeObjects.size() < maxSize)
freeObjects.add(object);
}
}
This is a rather complex class. As such, we will return to this class after we see how it is used in the implementation of the interface.
We have laid the groundwork for our first Android game. In Day 6, we will continue , so that we can build our game on top of it.
Thank you so much for reading!
Thank you so much for reading!
As always, feel free to email me questions at jamescho7@kilobolt.com
|
|

No source code is available for this lesson.
comments powered by Disqus