Sei sulla pagina 1di 201

Android Game Development Tutorials

Published on June 15, 2011 | 171,043 views | Filed in: Android Games Tags: featured

Some months ago we received an email from a fellow Java developer, Tamas Jano, asking to be
part of our JCG partners program. To our surprise he maintains a blog named Against The
Grain debating about game development for the Android platform. I have been reading all of his
articles since then and I must admit that his writings have been an inspiration and a motivation
for me and my colleagues here at Java Code Geeks so as to start developing our first game for
the Android platform.
With this post I would like to present Tamass work to our community hoping that you will be
inspired and motivated just like we did!
What follows is a portion of Tamass introductory article titled as A little motivation and
whats the idea behind all this. I am certain that after reading it you will realize (just like I did)
that you have many many things in common with this guy!
First of all I know no great coder who is not interested in games. Some love slow paced ones
while outdoorsy geeks (yes they do exist) will have a go with any type that requires all those
reflexes some just wont develop. At some point in their lives they might have wondered how the
hell is this done? Wouldnt it be cool to make such a thing? Id love to do that.
And so they went, getting into computing fueled by a passion for creating worlds they own and
command. Back in the days you would see these guys at the arcades, hanging around computer
labs and dreaming of owning one of those magnificent machines they can create their universe
on. Im talking about the 80s.
Many took the classes, went through all that necessary crap that comes with getting a degree one
would not care about in the future and here they are. Some graduated and have decent paying
software engineer positions working for a multinational corporation doing who knows what.
But a percentage of these so called engineers dream of games. They own the latest gadgets but
they do not have the one thing that would enable them to make games: Time. Working 9-5 sucks
and many have families or other obligations but they still think of doing projects on the side.
Unfortunately many never even get started.
How many thought: manIll be building the greatest game of all, Ill be rich and famous. Then
they meet someone, have to get a job to pay for settling down and pay the bills for a place
where they go in the evenings to crash just to start it over the next day. All this by doing boring
web stuff or working on a small part of a monstrous multi-threaded distributed enterprise
application architected by an inexperienced halfwit architect wannabe who got the job by
sticking with the company since he was an intern.
Where is the game you dreamed of doing 10 years ago?
To be precise I am in a similar situation and while I had a short gig with a game company I am
well in the rat race leading nowhere. I have decided to try one more time and I will give it a go.

Why? Just for the hell of it, to demonstrate that games are simple to build and you can sit at your
computer and have some fun too. Actually this is why I ended up a coder, to make games not to
configure some frameworks (yes, that is not programming, it is mostly configuration).
Well was I right? I hope I was!
As I told you before Java Code Geeks have been busy enough developing our first game for the
Android platform. A new category named Android Games has been created in order to contain
all game related articles from now on.
Here is the list of all Android Game Development tutorials (up until now) for your reference:
1. The Game Idea
2. Create the Project
3. A Basic Game Architecture
4. A Basic Game Loop
5. Displaying Images
6. Moving Images
7. The Game Loop
8. Measuring FPS
9. Sprite Animation
10. Particle Explosion
11. Design In-game Entities The Strategy Pattern
12. Using Bitmap Fonts
13. Switching from Canvas to OpenGL ES
14. Displaying Graphical Elements (Primitives) with OpenGL ES
15. OpenGL Texture Mapping
16. Design In-game Entities The State Pattern
17. Building Games Using the MVC Pattern Tutorial and Introduction

18. Android Game Development with libgdx Prototype in a day, Part 1a


19. Android Game Development with libgdx Prototype in a day, Part 1b
20. Android Game Postmortem ArkDroid Development
Last but not least we have established a new division, JCG Studios (Just Cool Games Studios)
where all our games will be presented and promoted.

Android Game Development The Game


Idea
Published on July 2, 2011 | 60,489 views | Filed in: Android Games

Coming up with an idea for the game


This is the hardest part. Because I am just one guy having limited time I will choose one idea that
is realisable in a short time and will contain all elements of an action game.
So I came up with a story for the game. The story goes like this:
The end is nigh! Evil robots from outer space have set up factories on the moon and are sending
their ever increasing waves of machines to destroy humanity. For what reason? Beats me but
they have laser cannons, missiles, brain washing weapons and a lot of other harmful stuff.
Every man for himself! How long before the end? How long can one survive or maybe defeat the
machines by reaching the moon base and annihilate the super brain?
That should be enough. Now lets design something around this story.
Checking the Android specs we see that we have limited memory and 480800 pixels to play
with. The first game that comes to my mind is robotron. Waves of robots, missiles from
everywhere and 2 joysticks. A perfect setup for a handheld device held horizontally.
One thumb for directions and the other one for shooting the baddies in every direction. A classic
shootem up.
Lets go retro. Pixelated graphics is cool and the art is in the effects. Will try to do that.
Lets design!

We have one guy. Hes got 3 lives and a gun. Hell be dropped in the middle of a room and some
baddies are trying to kill him already.
We have the basic information to sketch out our game structure.
But, we dont have a name. Lets see, droids taking over the planetchecked google for
droidz and droidz game guess what? No droidz game found. I will name this: droidz.
I find it a cool name for the first game using android.

Above you have a rough mock-up of what the game will look and feel like. The 2 grey circles are
the controllers. Imagine the device being held horizontally and you have your thumbs on the
circles. Your left thumb will move our hero while the right thumb will fire the weapon. The
direction is being controlled by the position of your thumb relative to the circles centre.
Now that we have the idea lets identify what we need to get the game done.
We need the game objects. Currently there are 2 types of actors in this. Our guy and the droids.
To control our guy we need to receive user input. The user input will be the touch screen. To be
more precise the 2 circles defined on the screen. One controls the guys position and the other his
weapon.
A typical game architecture looks like this:
1. Process input
2. Update state of game objects. This means calculate new positions for every item, check
game logic, collisions etc
3. Produce sounds
4. Render state to screen
5. If game is not over repeat from step 1
For example: Our guy is in the middle. Droids move every 1/10 of the second towards him.
Every tenth of a second we check if the screen was touched and if it was touched we move our

guy or fire his weapon. If the weapon was fired we check every tick (thats 1/10 s) if the bullett
collided with any droid to destroy him. If collided then droid is destroyed and the bullett is also
destroyed. If no collision then both droids and bulletts new positions are calculated according to
their speed (droid moves 5 pixels every 1/10 s for ex and the bullett moves 50). We also check if
the droid collided (reached) our guy and if so our hero is dead and game over.
This is an overview of how this game will work but will extend it as we go.
Reference: The Game Idea from our JCG partner Tamas Jano from Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

Android Game Development Create The


Project
Published on July 3, 2011 | 88,812 views | Filed in: Android Games

Now that we have our idea lets get the environment up and start coding.
To install Android follow the steps found on the official documentation page. I use eclipse so if
you are a Java guy it should be pretty familiar. If you have never developed in Java but did some
other coding in C++ or C# for example it should be pretty simple to catch up. I would
recommend starting with some Java tutorials and then switch to Android. If you havent
programmed beforewell thats though but its solvable. Google for some programming
tutorials and dont get discouraged! Then check back here.
I will use Android 2.2 as it is the latest at the time of this writing and I suspect it will take a long
time till I finish this project so it just might be quite used. Also because we plan to use multitouch we need version 2.x.
First lets create the AVD (Android Virtual Device). Click on the little Android icon or choose
Window -> Android SDK and AVD Manager and click on the New button.
Set the name to MyDevice, the target to Android 2.2 API Level 8. Set 128 MiB for the SD
Card. Set the Skin to Built-in HVGA and the Hardware to Abstracted LCD density to 160. These
are the current default settings.

Click Create AVD and the virtual device should be created.


Now lets create the project.
Select from the menu: New -> Project and choose Android Project.
Fill in as per the screen-shot and click Finish.
The Application name is the name given to our game. The package name is just the name space
to group our classes.
Select Android 2.2 for Build Target.
The most important is the Create Activity. The Activity is the class instantiated when the
application is started. Dont have to worry about it right now just remember that is the first thing
being called.

In a nutshell the Activity handles our input (gets the touches on the screen), creates the window
where we will display our game and so on. This usually is a full screen window and we will use
one as such.
Lets run the created application. Right click on the project and choose Run As -> Android
Application. Choose the configured device and wait for it to load. Remember not to close the
Virtual Device once it has started as every time you will run your project, eclipse will redeploy it
to the currently running device and will save you a lot of time if its already started.
You should see a screen like the one below. If the device asks you to unlock the screen do it by
dragging the unlock button with your mouse.

Now lets examine what has just happened. Open the DroidzActivity.java file.
view source
print?
package net.obviam.droidz;

import android.app.Activity;
import android.os.Bundle;

public class DroidzActivity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

01
02
03
04
05
06
07
08
09
10
11
12
13

package net.obviam.droidz;
import android.app.Activity;
import android.os.Bundle;
public class DroidzActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Youll notice one method. The onCreate() method on line 09. This method is called when the
activity is being created at the application launch. Its sets the view (the display) to be the default
R (check R.java) which is the default resource view automatically generated by the android tools
behind the scenes.
This file feeds on multiple configuration files to provide the activity with the view. It reads the
main.xml from the res (which stands for resources) directory and parses it.
Lets open the res/layout/main.xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>

view source
print?
01 <?xml version="1.0" encoding="utf-8"?>
02 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03
android:orientation="vertical"
04
android:layout_width="fill_parent"
05
android:layout_height="fill_parent"
06
>
07
<TextView
08
android:layout_width="fill_parent"
09
android:layout_height="wrap_content"
10
android:text="@string/hello"
11
/>
12
</LinearLayout>

Youll notice that a LinearLayout is used that fills up the whole screen and has a vertical
positioning (Line 2). Line 3 tells that our orientation is horizontal while lines 4 and 5 instruct
android to use the whole display (currently the parent is the display) for the view.
Line 7 defines a TextView which is just a label that takes up a whole line of the contained texts
height. The value is a placeholder read from the @string file. @string is also a placeholder for
the strings.xml file and opening this file youll immediately notice that this is the place where the
actually displayed value comes from. Worth noting that the R.java file is regenerated after we
modify strigs.xml and for each resource entry a corresponding constant is generated and it will
be used internally.
Open the /res/values/strings.xml file:
view source
print?
1
2
3
4
5
6

<?xml version="1.0" encoding="utf-8"?>


<resources>
<string name="hello">Hello World, DroidzActivity!</string>
<string name="app_name">droidz</string>
<string name="warning">Robots are rising</string>
</resources>

These are the resource strings. Apart from line 5 which I added everything is generated. To add
the warning message to the display just after the hello message modify the main.xml file and add
a new TextView that will display our @warning message.
The new main.xml file looks like this:
view source

print?
01 <?xml version="1.0" encoding="utf-8"?>
02 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03
android:orientation="vertical"
04
android:layout_width="fill_parent"
05
android:layout_height="fill_parent"
06
>
07
<TextView
08
android:layout_width="fill_parent"
09
android:layout_height="wrap_content"
10
android:text="@string/hello"
11
/>
12
<TextView
13
android:layout_width="fill_parent"
14
android:layout_height="wrap_content"
15
android:text="@string/warning"
16
/>
17
</LinearLayout>

If you run the activity then you should have a screen displaying the new warning message too.

Worth noting that eclipse regenerated the R.java file and if you open it you will notice a similar
line to this:
view source
print?
1 public static final int warning=0x7f040002;

It is generated by the android tooling and it keeps the IDs and pointers to the actual resources
that are used in the activity.
Go ahead and play with the current setting and see what the options are for different display
widgets.

Next we will actually load some images and draw them onto the screen.
Reference: Creating the Android Project from our JCG partner Tamas Jano from Against The
Grain blog.

Android Game Development A Basic


Game Architecture
Published on July 4, 2011 | 58,341 views | Filed in: Android Games

So we got our Android application up and running but you might be wondering what type of
application is exactly a game. I will try to give you my understanding of it. The following
diagram represents a game architecture.

Game architecture on an Android phone


In the schema above you see the Android OS running on the Phone and everything on top of that.
The input is the touch-screen in our case but it can be a physical keyboard if the phone has one,
the microphone, the camera, the accelerometers or even the GPS receiver if equipped. The
framework exposes the events when touching the screen through the View used in our Activity
from the previous article.

The User Input


In our game this is the event generated by touching the screen in one of the 2 defined control
areas. (see Step 1 the coloured circles). Our game engine monitors the onTouch event and at
every touch we record the coordinates. If the coordinates are inside our defined control areas on
the screen we will instruct the game engine to take action. For example if the touch occurs in the
circle designated to move our guy the engine gets notified and our guy is instructed to move. If
the weapon controller circle is touched the equipped weapon will be instructed to fire its bullets.
All this translates to changing the actors states that are affected by our gestures aka input.

I have just described the Game Logic part which follows.

Game Logic
The game logic module is responsible for changing the states of the actors in the game. By actors
I mean every object that has a state. Our hero, droids, terrain, bullets, laser beams etc. For
example we touch the upper half of the hero control area like in the drawing and this translates
to: calculate the movement speed of our guy according to the position of our movement
controller (our finger).

In the image above the light green circle represents our finger touching the control area. The
User Input module notifies the Game Engine (Game Logic) and also provides the coordinates. dx
and dy are the distances in pixels relative to the controller circle centre. The game engine
calculates the new speed it has to set for our hero and the direction he will move. If dx is positive
that means he will go right and if dy is positive he will also move upward.

Audio
This module will produce sounds considering the current state. As almost every actor/object will
produce sounds in their different states and because the devices well run our game on are
limited to just a few channels (that means briefly how many sounds can the device play at once)
it has to decide which sounds to play. For example the droid posing the biggest threat to our hero
will be heard as we want to draw attention to it and of course we will need to reserve a channel
for the awesome shooting sound of our weapon as it is much fun listening to our blaster singing.
So this is the audio in a nutshell.

Graphics
This is the module responsible for rendering the game state onto the display. This can be as
simple as drawing directly onto the canvas obtained from the view or having a separate graphics
buffer drawn into and then passed to the view which can be a custom view or an OpenGL view.

We measure the rendering in FPS which stands for frames per second. If we have 30FPS that
means that we display 30 images every second. For a mobile device 30 FPS is great so we will
aim for that. More on this later.
The only thing you want to know now that the higher the FPS the smoother the animation. Just
imagine someone walking and close your eyes for exactly one second. After opening your eyes
you will see the person in the position after one second. This is a 2FPS. Watch them walk but
keeping your eyes open and youll see a fluid motion. This is guaranteed to be a minimum of
30FPS but it is likely to be more, depending on your eyes. If you have awesome receptors in
pristine condition this could be 80-100 or more.

Output
The output is the result of both sound and image and maybe vibration if we decide to produce
some.
Next we will set up our view and will try to make our first game loop which will take input from
the touch screen. Well have our first game engine.
Reference: A Basic Game Architecture from our JCG partner Tamas Jano from Against The
Grain blog.

Android Game Development A Basic


Game Loop
Published on July 5, 2011 | 82,527 views | Filed in: Android Games

Following the series so far you we have an understanding of the game architecture. Even if just
briefly but we know that we need to take input in some form, update the internal state of the
game and finally render it to the screen and also produce some sounds and/or vibrations.
Furthermore we have created an example Android project for our first game. In this article we
are going to discuss and implement the basic game loop.
Lets keep it simple. Check the following diagram.

A Basic Game Loop


We handle input, update the state of our internal objects and render the current state. The Update
and Render are grouped logically. They are tied together and tend to be executed one after the
other.
Anything in Android happens inside an Activity. The Activity will create a View. The View is
where everything happens. It is where the touch takes place and the resulting image gets
displayed. Think of the Activity as a table that holds a sheet of paper (the View) enabling us to
draw something. We will use our pencil to draw something onto the paper. That will be our touch
and the actual chemistry happens on the paper so the result of our interaction with the View
produces an image. The same is with Activity and View. Something like the following diagram:

Android Game Loop


Lets open up DroidzActivity.java from our project. We see the line

view source
print?
1

setContentView(R.layout.main);

This does nothing more than assigns the default (R) view to the activity when it is created. In our
case it happens at startup.
Lets create a new View which we will use. A View is a simple class that provides us with event
handling (like onTouch) and a visible rectangle shaped space to draw on. The simplest way is to
extend Androids own SurfaceView. We will also implement SurfaceHolder.Callback to gain
access to surface changes, for example when it is destroyed or the orientation of the device has
changed.
MainGamePanel.java
package net.obviam.droidz;

import android.content.Context;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainGamePanel extends SurfaceView implements


SurfaceHolder.Callback {

public MainGamePanel(Context context) {


super(context);
// adding the callback (this) to the surface holder to intercept events
getHolder().addCallback(this);

// make the GamePanel focusable so it can handle events


setFocusable(true);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}

@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}

@Override
protected void onDraw(Canvas canvas) {

}
}
view source
print?
01
package net.obviam.droidz;
02
03
import android.content.Context;
04
import android.graphics.Canvas;
05
import android.view.MotionEvent;
06
import android.view.SurfaceHolder;
07
import android.view.SurfaceView;
08
09 public class MainGamePanel extends SurfaceView implements
10 SurfaceHolder.Callback {
11
12 public MainGamePanel(Context context) {
13 super(context);
14 // adding the callback (this) to the surface holder to intercept events
15 getHolder().addCallback(this);
16 // make the GamePanel focusable so it can handle events
17
setFocusable(true);
18
}
19
20
@Override
2 public void surfaceChanged(SurfaceHolder holder, int format, int width, int
1 height) {
2
}
2
23
24
@Override
25 public void surfaceCreated(SurfaceHolder holder) {
26 }
27
28
@Override
29 public void surfaceDestroyed(SurfaceHolder holder) {
30 }
31
32
@Override
33 public boolean onTouchEvent(MotionEvent event) {
34 return super.onTouchEvent(event);
35
}
36
37 @Override
38 protected void onDraw(Canvas canvas) {

39
40

}
}

The above code is a plain class that overrides the methods we are interested in.
Nothing special apart from lines 15 and 17.
view source
print?
1

getHolder().addCallback(this);

This line sets the current class (MainGamePanel) as the handler for the events happening on the
actual surface.
view source
print?
1

setFocusable(true);

The above line makes our Game Panel focusable, which means it can receive focus so it can
handle events. We added the callback and made it focusable in the constructor so we wont miss.
The over-riden methods (line 20 onwards) will all be used but currently keep them empty.
Lets create the thread that will be our actual game loop.
MainThread.java
package net.obviam.droidz;

public class MainThread extends Thread {

// flag to hold game state


private boolean running;
public void setRunning(boolean running) {
this.running = running;
}

@Override
public void run() {
while (running) {
// update game state
// render state to the screen
}
}
}
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18

package net.obviam.droidz;
public class MainThread extends Thread {
// flag to hold game state
private boolean running;
public void setRunning(boolean running) {
this.running = running;
}
@Override
public void run() {
while (running) {
// update game state
// render state to the screen
}
}
}

As you can see this does not do much. It overrides the run() method and while the running flag
is set to true it does an infinite loop.
Currently the thread is not instantiated so lets start it up when the screen loads.
Lets take a look at the modified MainGamePanel class.

package net.obviam.droidz;

import android.content.Context;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainGamePanel extends SurfaceView implements


SurfaceHolder.Callback {

private MainThread thread;

public MainGamePanel(Context context) {


super(context);
getHolder().addCallback(this);

// create the game loop thread


thread = new MainThread();

setFocusable(true);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
}

@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}

@Override
protected void onDraw(Canvas canvas) {
}
}
view source
print?
01
package net.obviam.droidz;
02
03
import android.content.Context;
04
import android.graphics.Canvas;
05
import android.view.MotionEvent;
06
import android.view.SurfaceHolder;
07
import android.view.SurfaceView;
08
09 public class MainGamePanel extends SurfaceView implements
10 SurfaceHolder.Callback {
11
12
private MainThread thread;
13
14 public MainGamePanel(Context context) {
15
super(context);
16
getHolder().addCallback(this);
17
18
// create the game loop thread
19
thread = new MainThread();
20
21
setFocusable(true);
22
}
23
24
@Override
2 public void surfaceChanged(SurfaceHolder holder, int format, int width, int

5 height) {
2
}
6
27
28
@Override
29 public void surfaceCreated(SurfaceHolder holder) {
30 thread.setRunning(true);
31
thread.start();
32
}
33
34
@Override
35 public void surfaceDestroyed(SurfaceHolder holder) {
36 boolean retry = true;
37
while (retry) {
38
try {
39
thread.join();
40
retry = false;
41 } catch (InterruptedException e) {
42 // try again shutting down the thread
43
}
44
}
45
}
46
47 @Override
48 public boolean onTouchEvent(MotionEvent event) {
49
return super.onTouchEvent(event);
50
}
51
52
@Override
53 protected void onDraw(Canvas canvas) {
54 }
55
}

We added the following lines:


Line 12 declares the thread as a private attribute.
view source
print?
1

private MainThread thread;

In line 19 we instantiate the thread.


view source
print?
1

thread = new MainThread();

In the surfaceCreated method we set the running flag to true and we start up the thread (lines 30
and 31). By the time the this method is called the surface is already created and the game loop
can be safely started.
Take a look at the surfaceDestroyed method.
view source
print?
01 public void surfaceDestroyed(SurfaceHolder holder) {
02 // tell the thread to shut down and wait for it to finish
03
// this is a clean shutdown
04
boolean retry = true;
05
while (retry) {
06
try {
07
thread.join();
08
retry = false;
09 } catch (InterruptedException e) {
10 // try again shutting down the thread
11
}
12
}
13
}

This method is called directly before the surface is destroyed. It is not the place to set the running
flag but the code we put in ensures that the thread shuts down cleanly. We simply block the
thread and wait for it to die.
If we now run our project in the emulator wont be able to see much but well use some logging
to test it. Dont worry about it as I will cover logging in a later chapter.
You can find more on the Android site.

Add interaction with the screen


We will exit the application when we touch the lower part of the screen. If we touch it anywhere
else well just log the coordinates.
In the MainThread class we add the following lines:
view source
print?
1 private SurfaceHolder surfaceHolder;
2 private MainGamePanel gamePanel;
3
4 public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {

5
6
7
8

super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}

We declared the gamePanel and surfaceHolder variables and a constructor taking the instances
as parameters.
It is important to have them both and not just the gamePanel as we need to lock the surface
when we draw and that can be done through the surfaceHolder only.
Change the line int the constructor of the MainGamePanel that instantiates the thread to
view source
print?
1 thread = new MainThread(getHolder(), this);

We are passing the current holder and the panel to its new constructor so the thread can access
them. We will create the game update method in the game panel and well trigger it from the
thread but currently just leave it as it is.
Add the TAG constant to the MainThread class. Every class will have its own String constant
called TAG. The value of the constant will be the name of the class containing it. We are using
Androids own logging framework and that takes two parameters. The firs is the tag which is just
a string to identify the source of the log message and the second is the message we want to log.
Its a good practice to use the name of the class for the tag as it makes it simple to look up the
logs.
A note on logging
To open the log viewer go to Windows -> Show View -> Other and in the dialog select
Android -> LogCat

Show View -> LogCat


Now you should see the LogCat view. This is nothing more than a console where you can follow
Androids log. Its a great tool as you can filter for logs containing a specific text or logs with a
certain tag which is quite useful.
Lets get back to our code. The MainThread.java class looks like this:
view source
print?
01
package net.obviam.droidz;
02
03
import android.util.Log;
04
import android.view.SurfaceHolder;
05
06 public class MainThread extends Thread {
07
08 private static final String TAG = MainThread.class.getSimpleName();
09
10
private SurfaceHolder surfaceHolder;
11
private MainGamePanel gamePanel;
12
private boolean running;
13 public void setRunning(boolean running) {
14 this.running = running;
15
}
16
17 public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
18 super();

19
this.surfaceHolder = surfaceHolder;
20
this.gamePanel = gamePanel;
21
}
22
23
@Override
24
public void run() {
25
long tickCount = 0L;
26
Log.d(TAG, "Starting game loop");
27
while (running) {
28
tickCount++;
29
// update game state
30
// render state to the screen
31 }
32 Log.d(TAG, "Game loop executed " + tickCount + " times");
33
}
34
}

In line 08 we define the tag for logging.


In the run() method we define tickCount which is incremented every time the while loop (the
game loop) is executed.
We log the results.
Lets go back to MainGamePanel.java class where we modified the onTouchEvent method so
we handle touches on the screen.
view source
print?
01
02
03
04
05
06
07
08
09
10
11

public boolean onTouchEvent(MotionEvent event) {


if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (event.getY() > getHeight() - 50) {
thread.setRunning(false);
((Activity)getContext()).finish();
} else {
Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());
}
}
return super.onTouchEvent(event);
}

Line 02 we check if the event on the screen is a start of a pressed gesture


(MotionEvent.ACTION_DOWN). If so we check if the touch happened in the lower part of the
screen. That is, the Y coordinate of the gesture is in the lower 50 pixels of the screen. If so we set
the threads running status to false and call finish() on the main activity which basically exits the
application.

Note: The screen is a rectangle with the upper left coordinates at (0,0) and the lower right
coordinates at (getWidth(), getHeight()).
I have also modified the DroidzActivity.java class so we log its lifecycle.
view source
print?
01
package net.obviam.droidz;
02
03
import android.app.Activity;
04
import android.os.Bundle;
05
import android.util.Log;
06
import android.view.Window;
07
import android.view.WindowManager;
08
09 public class DroidzActivity extends Activity {
10 /** Called when the activity is first created. */
11
12 private static final String TAG = DroidzActivity.class.getSimpleName();
13
14
@Override
15 public void onCreate(Bundle savedInstanceState) {
16 super.onCreate(savedInstanceState);
17 // requesting to turn the title OFF
18 requestWindowFeature(Window.FEATURE_NO_TITLE);
1
// making it full screen
9
2 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
0 WindowManager.LayoutParams.FLAG_FULLSCREEN);
21 // set our MainGamePanel as the View
22 setContentView(new MainGamePanel(this));
23
Log.d(TAG, "View added");
24
}
25
26
@Override
27
protected void onDestroy() {
28
Log.d(TAG, "Destroying...");
29
super.onDestroy();
30
}
31
32
@Override
33
protected void onStop() {
34
Log.d(TAG, "Stopping...");
35
super.onStop();
36
}
37
}

Line 20 makes the display fullscreen.


The onDestroy() and onStop() methods were overridden just to log the activitys lifecycle.
Lets run the application by right-clicking on the project and select Run As -> Android
application
You should see a black screen. If you click around a few time on the upper half and then you
click on the bottom of your emulators screen the application should exit.
At this stage it is worth checking the logs.

LogCat
The highlighted lines are the most interesting as if you match look the logs up in the code you
will see exactly the order of the method calls. You should also see how many times the threads
while loop executed. It is a very high number but next time we will be more considerate about
the cycles as we will introduce FPS and UPS. That is Frames Per Second and Updates Per
Second. We will create a game loop that will actually draw something onto the screen and it will
do it as many times per second as we specify it.
Things we did so far:

Create a full screen application

Have a separate thread controlling the application

Intercepting basic gestures like pressed gesture

Shutting down the application graciously

Download the source code here.


Import it into eclipse and it should work right away.

Android Game Development Displaying


Images with Android
Published on July 7, 2011 | 18,476 views | Filed in: Android Games

Before moving to the actual game loop lets display some graphics so we can get some
measurements done. If you havent checked it out please do as it is imperative that you
understand how a thread updates the screen. You can check it out here.
Displaying an image using Android is extremely simple.
To scale the problem down we will just display the image in the top left corner. We need an
image to display. I prefer .png formats and I have just created one named droid_1.png. The size
of the image is 2020 pixels. You can use whatever tool you like. I use Gimp or Photoshop.

To make it available for your application just copy the image into the /res/drawable-mdpi
directory (the easiest way is to drag and drop it there).
I have chosen mdpi which stands for normal screen medium density. To read on screen types
check the android documentation.
Modify the MainGamePanel.java class and change the onDraw(Canvas canvas) method to look
like this:
view source
print?
1 protected void onDraw(Canvas canvas) {
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(),
2
R.drawable.droid_1), 10, 10, null);
3
}

The drawBitmap method draws the droid_1 image to the coordinates 10,10.
We obtain the bitmap from the application resources by passing the id of our image (resource),
which is droid_1 in our case. When we copied the droid_1.png into the resource directory
eclipse detected it and the plugin executed the necessary scripts in the background so we have
the droid_1 identifier in the R.java file. The R.java holds the resource identifiers.
The thread suffered some changes too. Examine the new run() method.
view source
print?
01
02

public void run() {


Canvas canvas;

03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22

Log.d(TAG, "Starting game loop");


while (running) {
canvas = null;
// try locking the canvas for exclusive pixel editing on the surface
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
// update game state
// draws the canvas on the panel
this.gamePanel.onDraw(canvas);
}
} finally {
// in case of an exception the surface is not left in
// an inconsistent state
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
} // end finally
}
}

In line 02 we declare the canvas on which we will draw our image. The canvas is the surfaces
bitmap onto which we can draw and we can edit its pixels. In line 08 we try to get hold of it and
in line 12 we trigger the panels onDraw event to which we pass the obtained canvas. Note that it
is a synchronised block which means that we have exclusivity on it and nothing can modify it
while we are using it.
The functionality is very simple and basic. On every execution of the game loop we get hold of
the canvas and we pass it to the game panel to draw on it. The game panel just displays the image
at coordinates 10,10. Now back to the FPS. If the number of times per second the image is
displayed drops below 20, it starts to get noticeable by us humans. The challenge is to keep this
rate above a set level and we will see how shortly.
Try running the code and you should see our droid displayed close to the top left corner.

Droid in top left corner

Moving the Image


Now that we have displayed it, lets try moving it. How? We will use our finger. We will
implement a simple drag and drop functionality. To pick up an image we will simply touch it and

while our finger is on the screen we will update the images coordinates accordingly. Once the
touch is finished we leave the image there where the last touch was recorded.
We need to create an object that will hold our image and the coordinates.
I have created Droid.java for this. Note that I have put the class into the
net.obviam.droidz.model package.
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

package net.obviam.droidz.model;
import android.graphics.Bitmap;
public class Droid {
private Bitmap bitmap; // the actual bitmap
private int x; // the X coordinate
private int y; // the Y coordinate
public Droid(Bitmap bitmap, int x, int y) {
this.bitmap = bitmap;
this.x = x;
this.y = y;
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}

It is a plain class with some attributes and a constructor.


The x and y are the coordinates of the droid. The bitmap holds the image that will be displayed
as the droid. It is the graphical representation of it.
So far nothing special. But to play around with it we need to add some state. To keep it simple,
the droid has only 2 states. Touched and untouched. By touched I mean when our finger touched
the droid on the screen. We keep the touched state true while we hold our finger down on the
screen at the droids position. Otherwise the droid remains untouched (state set to false).
Check out the new droid class.
view source
print?
01
package net.obviam.droidz.model;
02
03
import android.graphics.Bitmap;
04
import android.graphics.Canvas;
05
import android.view.MotionEvent;
06
07
public class Droid {
08
09 private Bitmap bitmap; // the actual bitmap
10 private int x; // the X coordinate
11 private int y; // the Y coordinate
12 private boolean touched; // if droid is touched/picked up
13
14 public Droid(Bitmap bitmap, int x, int y) {
15
this.bitmap = bitmap;
16
this.x = x;
17
this.y = y;
18
}
19
20
public Bitmap getBitmap() {
21
return bitmap;
22
}
23 public void setBitmap(Bitmap bitmap) {
24 this.bitmap = bitmap;
25
}
26
public int getX() {
27
return x;
28
}
29
public void setX(int x) {
30
this.x = x;
31
}
32
public int getY() {
33
return y;

34
}
35
public void setY(int y) {
36
this.y = y;
37
}
38
39
public boolean isTouched() {
40
return touched;
41
}
42
43 public void setTouched(boolean touched) {
44 this.touched = touched;
45
}
46
4
public void draw(Canvas canvas) {
7
4 canvas.drawBitmap(bitmap, x - (bitmap.getWidth() / 2), y 8 (bitmap.getHeight() / 2), null);
49
}
50
5
public void handleActionDown(int eventX, int eventY) {
1
5 if (eventX >= (x - bitmap.getWidth() / 2) && (eventX <= (x +
2 bitmap.getWidth()/2))) {
5 if (eventY >= (y - bitmap.getHeight() / 2) && (y <= (y +
3 bitmap.getHeight() / 2))) {
5
// droid touched
4
55
setTouched(true);
56
} else {
57
setTouched(false);
58
}
59
} else {
60
setTouched(false);
61
}
62
63
}
64
}

We added the touched field to keep track of the state of our droid. You will notice two more
methods: public void draw(Canvas canvas) and public void handleActionDown(int eventX, int
eventY).
These methods are discussed later.
Now lets have a look at the MainGamePanel.java. It changed quite a lot.
view source
print?
001

package net.obviam.droidz;

002
003
import net.obviam.droidz.model.Droid;
004
import android.app.Activity;
005
import android.content.Context;
006
import android.graphics.BitmapFactory;
007
import android.graphics.Canvas;
008
import android.graphics.Color;
009
import android.util.Log;
010
import android.view.MotionEvent;
011
import android.view.SurfaceHolder;
012
import android.view.SurfaceView;
013
014 public class MainGamePanel extends SurfaceView implements
015
SurfaceHolder.Callback {
016
017 private static final String TAG = MainGamePanel.class.getSimpleName();
018
019
private MainThread thread;
020
private Droid droid;
021
022
public MainGamePanel(Context context) {
023 super(context);
024 // adding the callback (this) to the surface holder to intercept events
025
getHolder().addCallback(this);
026
02
// create droid and load bitmap
7
02 droid = new Droid(BitmapFactory.decodeResource(getResources(),
8 R.drawable.droid_1), 50, 50);
029
030
// create the game loop thread
031
thread = new MainThread(getHolder(), this);
032
033 // make the GamePanel focusable so it can handle events
034 setFocusable(true);
035
}
036
037 @Override
038 public void surfaceChanged(SurfaceHolder holder, int format, int width,
039
int height) {
040
}
041
042
@Override
043 public void surfaceCreated(SurfaceHolder holder) {
044 // at this point the surface is created and
045
// we can safely start the game loop
046
thread.setRunning(true);
047
thread.start();

048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096

}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "Surface is being destroyed");
// tell the thread to shut down and wait for it to finish
// this is a clean shutdown
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again shutting down the thread
}
}
Log.d(TAG, "Thread was shut down cleanly");
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// delegating event handling to the droid
droid.handleActionDown((int)event.getX(), (int)event.getY());
// check if in the lower part of the screen we exit
if (event.getY() > getHeight() - 50) {
thread.setRunning(false);
((Activity)getContext()).finish();
} else {
Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());
}
} if (event.getAction() == MotionEvent.ACTION_MOVE) {
// the gestures
if (droid.isTouched()) {
// the droid was picked up and is being dragged
droid.setX((int)event.getX());
droid.setY((int)event.getY());
}
} if (event.getAction() == MotionEvent.ACTION_UP) {
// touch was released
if (droid.isTouched()) {
droid.setTouched(false);
}
}
return true;
}
@Override

097
098
099
100
101
102

protected void onDraw(Canvas canvas) {


// fills the canvas with black
canvas.drawColor(Color.BLACK);
droid.draw(canvas);
}
}

Line 28 creates the droid object at the the coordinates 50,50.


It is declared as an attribute in line 20.
In the onTouchEvent (method line 71) if the action is the touch of the screen
(MotionEvent.ACTION_DOWN) we want to know if our finger landed on the droid. To do this
is easy. We need to check if the events coordinates are inside the droids bitmap. In order not to
clutter the onTouch event we just delegate this to the droid object. Now you can go back to the
Droid.java class and check the handleActionDown method.
view source
print?
0
public void handleActionDown(int eventX, int eventY) {
1
0 if (eventX >= (x - bitmap.getWidth() / 2) && (eventX <= (x +
2 bitmap.getWidth()/2))) {
0 if (eventY >= (y - bitmap.getHeight() / 2) && (y <= (y +
3 bitmap.getHeight() / 2))) {
0
// droid touched
4
05
setTouched(true);
06
} else {
07
setTouched(false);
08
}
09
} else {
10
setTouched(false);
11
}
12
13
}

It is very simple. If the action happened inside the area of our droids bitmap well set its touched
status to true
Going back to the onTouched method, notice that there is a code block (lines 81-86) that is
executed when the event is of type MotionEvent.ACTION_MOVE. This event happens when
our finger started to move on the screen. It is simple. We check if the droid is touched and if so
we just update its coordinates accordingly.
That is it. This was the update game state. We have updated the state of our sole object in the
game. The touched state and the coordinates. Now it is time to display it.

Check the onDraw method. This is triggered at every execution of the main loop inside the
thread remember?
It contains 2 lines. Line 99 simply fills the canvas with black and line 100 tells the droid to draw
itself on the canvas provided. By doing this is like me giving you a paper to draw yourself onto
it, and give the paper back to me so I can continue my drawing.
Check Droid.java for the draw implementation. It is dead simple. It takes the bitmap it was
instantiated with and draws it to the canvas at the coordinates the droid is at in that moment.
Note that the coordinates of the droid are exactly in the center of the bitmap so we need to move
the pointer to the top left corner of the image and draw it there. Im sure you wont find it hard to
understand.
Thats it. Run it and have a play with it.
Download he code for the project here (droidz.android.02.3-graphics.tar.gz)
Reference: Displaying Images with Android from our JCG partner Tamas Jano from Against
The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

Android Game Development Moving


Images on Screen
Published on July 9, 2011 | 5,696 views | Filed in: Android Games

In the previous post weve displayed an image and implemented a very simple drag functionality.
Things we should know by now following the series:

launch an Android application in full screen

use a separate thread which controls the application (the game loop)

load an image from the resources

acquire the canvas and draw the image onto it

handle basic touch gestures

The task Im setting for this entry is simple: have the droid travel through the screen. It should
never leave the surface and it should bounce back when it hits the wall which is the edge of the
screen.
If you remember the image is just a representation of the droid. So we will modify the droid
object and well add some abilities. Just one for the time being. Our droid is movable. It can
move. This implies that it has speed. We will vest it with the ability of movement. To achieve this
we will add a move() method and this method will just update the X and Y coordinates based on
its Speed. Speed will be a class in itself and the Droid will contain it. I will do a concrete
implementation now but later on I will be using the Strategy Pattern.
Create the Speed.java class.
view source
print?
01 package net.obviam.droidz.model.components;
02
03
public class Speed {
04
05 public static final int DIRECTION_RIGHT = 1;
06 public static final int DIRECTION_LEFT = -1;
07 public static final int DIRECTION_UP = -1;
08 public static final int DIRECTION_DOWN = 1;
09
10 private float xv = 1; // velocity value on the X axis
11 private float yv = 1; // velocity value on the Y axis
12
13 private int xDirection = DIRECTION_RIGHT;
14 private int yDirection = DIRECTION_DOWN;
15
16
public Speed() {
17
this.xv = 1;
18
this.yv = 1;
19
}
20
21
public Speed(float xv, float yv) {
22
this.xv = xv;
23
this.yv = yv;
24
}
25
26
public float getXv() {
27
return xv;
28
}
29
public void setXv(float xv) {
30
this.xv = xv;
31
}

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

public float getYv() {


return yv;
}
public void setYv(float yv) {
this.yv = yv;
}
public int getxDirection() {
return xDirection;
}
public void setxDirection(int xDirection) {
this.xDirection = xDirection;
}
public int getyDirection() {
return yDirection;
}
public void setyDirection(int yDirection) {
this.yDirection = yDirection;
}
// changes the direction on the X axis
public void toggleXDirection() {
xDirection = xDirection * -1;
}
// changes the direction on the Y axis
public void toggleYDirection() {
yDirection = yDirection * -1;
}
}

Well use direction constants to determine the movement direction on the axis. The droid has a
vertical and a horizontal speed and at each game update the coordinates are set considering the
direction of the movement.
The droid will be allowed to move only on the area of the canvas. That is a rectangle and our 2D
coordinate system. Unlike in the math classes the origin is in the top left corner. So for the droid
to start from the top left corner of the screen its coordinates will be 0,0. To move in a diagonal
line the speed will be 1 for both the X and Y components of the speed vector. To move towards
the bottom right the directions will be: 1 (right) for the X axis and 1 (down) for the Y axis.

Canvas Coordinate System


To have the droid move horizontally the speed of the Y vector must be 0. A value of 0.5 for Y
and 1 for X will make the droid travel at a 22.5 degrees to the X axis. Simple geometry.
In the Speed we have the vector components (x and y) and the directions along with the getters
and setters. The two methods (toggleXDirection() and toggleYDirection()) just change the
direction with one call. Well see later at collision detection (with the wall of the screen) that it is
pretty useful.
The game loop (MainThread.java) gets an important modification as it gets the game update
method introduced. The following code snippet is the updated run() method which has just one
line added:
view source
print?
1

this.gamePanel.update();

The run() method:


view source
print?
01
02
03
04

public void run() {


Canvas canvas;
Log.d(TAG, "Starting game loop");
while (running) {

05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

canvas = null;
// try locking the canvas for exclusive pixel editing
// in the surface
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
// update game state
this.gamePanel.update();
// render state to the screen
// draws the canvas on the panel
this.gamePanel.render(canvas);
}
} finally {
// in case of an exception the surface is not left in
// an inconsistent state
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
} // end finally
}
}

We will create the corresponding method in the MainGamePanel. This method is in charge of
updating the state of all the objects in the application. Currently only the droid. Because the droid
is moving we will introduce a basic collision detection with the walls. The logic is simple. Check
if the droid is moving towards left then check if the droids position is at the wall and if it is then
change its direction. Bear in mind that the droids position is the center of the image so we need
to use the images width and height to get the accuracy right.
We also update the position of the droid. To keep the update method simple we delegate the
update of the droids position to the droid itself. So the droid will get an update method which
will keep updating its position if the droid is not being picked up by a touch gesture. Check the
previous post for this.
Check the code: MainGamePanel.java
view source
print?
01
02
03
04
05
06
07
08
09
10

public void update() {


// check collision with right wall if heading right
if (droid.getSpeed().getxDirection() == Speed.DIRECTION_RIGHT
&& droid.getX() + droid.getBitmap().getWidth() / 2 >= getWidth()) {
droid.getSpeed().toggleXDirection();
}
// check collision with left wall if heading left
if (droid.getSpeed().getxDirection() == Speed.DIRECTION_LEFT
&& droid.getX() - droid.getBitmap().getWidth() / 2 <= 0) {
droid.getSpeed().toggleXDirection();

11 }
12 // check collision with bottom wall if heading down
13 if (droid.getSpeed().getyDirection() == Speed.DIRECTION_DOWN
14 && droid.getY() + droid.getBitmap().getHeight() / 2 >= getHeight()) {
15
droid.getSpeed().toggleYDirection();
16
}
17 // check collision with top wall if heading up
18 if (droid.getSpeed().getyDirection() == Speed.DIRECTION_UP
19 && droid.getY() - droid.getBitmap().getHeight() / 2 <= 0) {
20 droid.getSpeed().toggleYDirection();
21
}
22
// Update the lone droid
23
droid.update();
24
}

getWidth() and getHeight() return the width and height of the view. The panel is a view,
remember?
The Droid.java files update() method:
view source
print?
1
public void update() {
2
if (!touched) {
3 x += (speed.getXv() * speed.getxDirection());
4 y += (speed.getYv() * speed.getyDirection());
5
}
6
}

I also changed the renders name in the MainThread.java so now it is render instead if onDraw.
Just that I like it better as it follows the update -> render naming.
Run the application and you should see a screen like the following one with the droid moving in
a 45 degrees angle and bouncing off the walls as it hits them. You can also drag the droid around.
To exit the application click (touch) the lower part of the screen.

Moving Droid
Download the full source code and eclipse project here.
Reference: Moving Images on the Screen with Android from our JCG partner Tamas Jano from
Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

Android Game Development The Game


Loop
Published on July 12, 2011 | 32,726 views | Filed in: Android Games

The game loop is the heartbeat of every game. We used a very rudimentary one so far (you can
find it here) without any control over how fast or slow we update our game state and which
frames to render.
To recapitulate, the most rudimentary game loop is a while loop that keeps executing some
instructions until we signal it to finish, usually by setting a variable called running to false
view source
print?
1
2
3
4
5
6

boolean running = true;


while (!running)
{
updateGameState();
displayGameState();
}

The above code runs blindly without a care for timing and resources. If you have a fast device
then it will run very fast and if you have a slow one it will run slower.
The updateGameState() updates the state of every object in the game and the
displayGameState() renders the objects into an image which is displayed onto the screen.
There are two things we should consider here: FPS and UPS.
FPS Frames per Second the number of times displayGameState() is being called per
second.
UPS Update per Second the number of times updateGameState() is being called per
second.

Ideally the update and render methods will be called the same number of times per second
(preferably not less than 20-25 times per second). 25 FPS is usually enough on a phone so us
humans wont notice the animation being sluggish.
For example if we target 25 FPS then it means we have to call the displayGameState() method
every 40ms (1000 / 25 = 40ms, 1000ms = 1s). We need to bear in mind that updateGameState()
is also called before the display method and for us to reach 25 FPS, we have to make sure that
the update display sequence executes in exactly 40ms. If it takes less than 40ms, then we have
a higher FPS. If it takes more than that, then we have a slower running game.
Lets see some examples to understand the FPS better.
The following diagram shows exactly 1 FPS. It takes the update render cycle exactly one
second to execute. This means that you will see the image on the screen change once every
second.

1 Frame per Second


The following diagram shows 10FPS. An update render cycle takes 100ms. This means every
tenth of a second the image changes.

10 FPS
But the above scenario means that the update-render cycle executes in 1/10 of a second EVERY
time. That is an assumption and we cant control the actual times on cycle executes, or can we?
What happens if we have 200 enemies and every enemy is shooting at us? We need to update the
state of each enemy and the states of their bullets and check for collisions in one single update.
Its different when we have just 2 enemies. The times will clearly differ. The same applies to the
render method. Rendering 200 firing droids will clearly take more time than rendering only 2.
So what are the scenarios? We could have an update-render cycle that finishes in less than 100ms
(1/10 of a second), finishes in exactly 100ms or finishes in more than that. On a powerful
hardware it will be faster than on a weaker one. Lets see the diagrams.
The cycle finishes before the desired timeframe so we have a small amount of free time before
running the next cycle.

Frame with time to spare


The following diagram shows a cycle which falls behind. That means that the time it takes for a
update-render cycle to finish is greater than the desired one. If it takes 12ms that means we are
2ms behind (still considering the 10FPS). This can mount up and every cycle we loose time and
the game will run slowly.

Overdue Frame
The first situation is the desired one. This gives us some free time to do something before we
kick off the next cycle. We dont need to do anything so we just tell the game loop to go to sleep
for the remaining time period and wake up when the next cycle is due. If we wont do this the
game will run quicker than intended. By introducing the sleep time we achieved constant frame
rate.

The second situation (I skipped the ideal one as it almost never happens) when the loop is
behind, requires a different approach.
To achieve constant speed in a game we need to update the state of our objects when required.
Imagine a droid approaching you at a constant speed. You know if it travelled half the screen in
one second, so it will take another second to reach the other side of the screen. To calculate the
position accurately we need to know either the time delta since the last postion, and the current
speed of the droid, or we update the position (status) of the droid at constant intervals. I will
choose the second one as playing with deltas in the game update can be tricky. To achieve a
constant game speed we will have to skip displaying frames. Game speed is NOT FPS!
Examine the following diagram. It is a scenario in which the update-render cycle takes longer
than the desired time so we have to catch up. To do that we will skip the rendering of this frame
and will do another update so the game speed wont be affected. Well do a normal cycle in the
next frame with even some time to give to the CPU to rest.

Constant Game Speed with Variable FPS


The above scenario has many variations. You can imagine the game update taking more than one
full frame. In this case we can do nothing to keep the game speed constant and the game will run
slower. We might have to skip multiple renderings to keep the speed constant but we have to
make sure that we set the maximum number of frames allowed to be skipped because it can take
quite a few updates to catch up and in case we skipped 15 frames that means we lost a lot from
the game and it will just be unplayable.
The MainThread.javas run() looks like this:
view source
print?
01
02
03

// desired fps
private final static int MAX_FPS = 50;
// maximum number of frames to be skipped

04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

private final static int MAX_FRAME_SKIPS = 5;


// the frame period
private final static int FRAME_PERIOD = 1000 / MAX_FPS;
@Override
public void run() {
Canvas canvas;
Log.d(TAG, "Starting game loop");
long beginTime; // the time when the cycle begun
long timeDiff; // the time it took for the cycle to execute
int sleepTime; // ms to sleep (<0 if we're behind)
int framesSkipped; // number of frames being skipped
sleepTime = 0;
while (running) {
canvas = null;
// try locking the canvas for exclusive pixel editing
// in the surface
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
beginTime = System.currentTimeMillis();
framesSkipped = 0; // resetting the frames skipped
// update game state
this.gamePanel.update();
// render state to the screen
// draws the canvas on the panel
this.gamePanel.render(canvas);
// calculate how long did the cycle take
timeDiff = System.currentTimeMillis() - beginTime;
// calculate sleep time
sleepTime = (int)(FRAME_PERIOD - timeDiff);
if (sleepTime > 0) {
// if sleepTime > 0 we're OK
try {
// send the thread to sleep for a short period
// very useful for battery saving
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
// we need to catch up
// update without rendering
this.gamePanel.update();
// add frame period to check if in next frame

53
sleepTime += FRAME_PERIOD;
54
framesSkipped++;
55
}
56
}
57 } finally {
58 // in case of an exception the surface is not left in
59
// an inconsistent state
60
if (canvas != null) {
61 surfaceHolder.unlockCanvasAndPost(canvas);
62 }
63
} // end finally
64
}
65
}

Examine the above code very carefully as it implements the logic behind the diagram. You can
find the full code in the downloadable project.
There is another approach which I like. It is constant game speed with maximum number of
frames per second. It uses interpolation to draw the state and it occurs on fast hardwares when
there is time left for another rendering before the next game update. This can enhance the visuals
of a game as it enables smoother animation but because we use mobile devices, giving the CPU
some rest will save the battery quite a lot.
There is an awesome article on game loops here. I personally understood the game loops reading
this article so I highly recommend it. The best I could find.
Note that I also modified the default values in the Speed.java class. The speed is measured in
units/second. Because we are setting our desired FPS to 50 that means that the speed will
increase by 50*speed.value every update. To have the speed of lets say 40 pixels/second you
will need to set the speed delta for every tick to 2 (40 / (1000 / 50) = 2). In other words you need
the droid to advance 2 pixels every game update (when you have 50 game updates per second) to
cover 40 pixels per second.
Download the code here and play with it.
Examine it and you have a constant game speed with variable frame rate.
Reference: The Game Loop from our JCG partner Tamas Jano from Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

Android Game Development Measuring


FPS

Published on July 18, 2011 | 21,773 views | Filed in: Android Games

In the previous entry we have created a game loop that runs at a constant speed and constant
(more or less) FPS.
How can we measure it?
Check the new MainThread.java class.

view source
print?
001
package net.obviam.droidz;
002
003
import java.text.DecimalFormat;
004
005
import android.graphics.Canvas;
006
import android.util.Log;
007
import android.view.SurfaceHolder;
008
009
/**
010
* @author impaler
01
*
1
01 * The Main thread which contains the game loop. The thread must have
2 access to
013 * the surface view and holder to trigger events every game tick.
014 */
015
public class MainThread extends Thread {
016
017 private static final String TAG = MainThread.class.getSimpleName();
018
019
// desired fps
020
private final static int MAX_FPS = 50;
021 // maximum number of frames to be skipped
022 private final static int MAX_FRAME_SKIPS = 5;
023 // the frame period
024 private final static int FRAME_PERIOD = 1000 / MAX_FPS;
025
026
// Stuff for stats */
027 private DecimalFormat df = new DecimalFormat("0.##"); // 2 dp
028 // we'll be reading the stats every second
029 private final static int STAT_INTERVAL = 1000; //ms
030 // the average will be calculated by storing
031 // the last n FPSs

032 private final static int FPS_HISTORY_NR = 10;


033
// last time the status was stored
034
private long lastStatusStore = 0;
035
// the status time counter
036
private long statusIntervalTimer = 0l;
037 // number of frames skipped since the game started
038 private long totalFramesSkipped = 0l;
039 // number of frames skipped in a store cycle (1 sec)
040 private long framesSkippedPerStatCycle = 0l;
041
042 // number of rendered frames in an interval
043
private int frameCountPerStatCycle = 0;
044
private long totalFrameCount = 0l;
045
// the last FPS values
046
private double fpsStore[];
047 // the number of times the stat has been read
048 private long statsCount = 0;
049
// the average FPS since the game started
050
private double averageFps = 0.0;
051
052 // Surface holder that can access the physical surface
053
private SurfaceHolder surfaceHolder;
054
// The actual view that handles inputs
055
// and draws to the surface
056
private MainGamePanel gamePanel;
057
058
// flag to hold game state
059
private boolean running;
060
public void setRunning(boolean running) {
061
this.running = running;
062
}
063
064 public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
065
super();
066
this.surfaceHolder = surfaceHolder;
067
this.gamePanel = gamePanel;
068
}
069
070
@Override
071
public void run() {
072
Canvas canvas;
073 Log.d(TAG, "Starting game loop");
074 // initialise timing elements for stat gathering
075
initTimingElements();
076
077 long beginTime; // the time when the cycle begun
078 long timeDiff; // the time it took for the cycle to execute
079 int sleepTime; // ms to sleep (<0 if we're behind)
080 int framesSkipped; // number of frames being skipped

081
082
sleepTime = 0;
083
084
while (running) {
085 canvas = null;
086 // try locking the canvas for exclusive pixel editing
087
// in the surface
088
try {
089
canvas = this.surfaceHolder.lockCanvas();
090
synchronized (surfaceHolder) {
091 beginTime = System.currentTimeMillis();
092 framesSkipped = 0; // resetting the frames skipped
093
// update game state
094
this.gamePanel.update();
095
// render state to the screen
096
// draws the canvas on the panel
097
this.gamePanel.render(canvas);
098
// calculate how long did the cycle take
099 timeDiff = System.currentTimeMillis() - beginTime;
100 // calculate sleep time
101 sleepTime = (int)(FRAME_PERIOD - timeDiff);
102
103
if (sleepTime > 0) {
104
// if sleepTime > 0 we're OK
105 try {
106 // send the thread to sleep for a short period
107
// very useful for battery saving
108
Thread.sleep(sleepTime);
109
} catch (InterruptedException e) {}
110
}
111
112 while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
113 // we need to catch up
114 this.gamePanel.update(); // update without rendering
115 sleepTime += FRAME_PERIOD; // add frame period to check if in next frame
116 framesSkipped++;
117
}
118
119
if (framesSkipped > 0) {
120
Log.d(TAG, "Skipped:" + framesSkipped);
121
}
122
// for statistics
123 framesSkippedPerStatCycle += framesSkipped;
124 // calling the routine to store the gathered statistics
125
storeStats();
126
}
127 } finally {
128 // in case of an exception the surface is not left in
129
// an inconsistent state

130
if (canvas != null) {
131
surfaceHolder.unlockCanvasAndPost(canvas);
132
}
133
} // end finally
134
}
135
}
136
137 /**
138 * The statistics - it is called every cycle, it checks if time since last
139 * store is greater than the statistics gathering period (1 sec) and if so
140 * it calculates the FPS for the last period and stores it.
141 *
142 * It tracks the number of frames per period. The number of frames since
143 * the start of the period are summed up and the calculation takes part
144 * only if the next period and the frame count is reset to 0.
145
*/
146
private void storeStats() {
147
frameCountPerStatCycle++;
148
totalFrameCount++;
149
150
// check the actual time
151 statusIntervalTimer += (System.currentTimeMillis() - statusIntervalTimer);
152
153 if (statusIntervalTimer >= lastStatusStore + STAT_INTERVAL) {
154 // calculate the actual frames pers status check interval
15 double actualFps = (double)(frameCountPerStatCycle / (STAT_INTERVAL /
5 1000));
15
6
157 //stores the latest fps in the array
158 fpsStore[(int) statsCount % FPS_HISTORY_NR] = actualFps;
159
160 // increase the number of times statistics was calculated
161
statsCount++;
162
163
double totalFps = 0.0;
164
// sum up the stored fps values
165
for (int i = 0; i < FPS_HISTORY_NR; i++) {
166
totalFps += fpsStore[i];
167
}
168
169
// obtain the average
170
if (statsCount < FPS_HISTORY_NR) {
171
// in case of the first 10 triggers
172
averageFps = totalFps / statsCount;
173
} else {
174
averageFps = totalFps / FPS_HISTORY_NR;
175 }
176 // saving the number of total frames skipped

177 totalFramesSkipped += framesSkippedPerStatCycle;


178 // resetting the counters after a status record (1 sec)
179
framesSkippedPerStatCycle = 0;
180
statusIntervalTimer = 0;
181
frameCountPerStatCycle = 0;
182
183 statusIntervalTimer = System.currentTimeMillis();
184 lastStatusStore = statusIntervalTimer;
185 // Log.d(TAG, "Average FPS:" + df.format(averageFps));
186 gamePanel.setAvgFps("FPS: " + df.format(averageFps));
187
}
188
}
189
190
private void initTimingElements() {
191
// initialise timing elements
192
fpsStore = new double[FPS_HISTORY_NR];
193
for (int i = 0; i < FPS_HISTORY_NR; i++) {
194
fpsStore[i] = 0.0;
19
}
5
19 Log.d(TAG + ".initTimingElements()", "Timing elements for stats
6 initialised");
197
}
198
199
}

I introduced a simple measuring function. I count the number of frames every second and store
them in the fpsStore[] array. The storeStats() is called every tick and if the 1 second interval
(STAT_INTERVAL = 1000;) is not reached then it simply adds the number of frames to the
existing count.
If the one second is hit then it takes the number of rendered frames and adds them to the array of
FPSs. After this I just reset the counters for the current statistics cycle and add the results to a
global counter. The average is calculated on the values stored in the last 10 seconds.
Line 171 logs the FPS every second while line 172 sets the avgFps value of the gamePanel
instance to be displayed on the screen.
The MainGamePanel.java classs render method contains the the displayFps call which just
draws the text onto the top right corner of the display every time the state is rendered. It also has
a private member that is set from the thread.
view source
print?
01
02
03
04

// the fps to be displayed


private String avgFps;
public void setAvgFps(String avgFps) {
this.avgFps = avgFps;

05
}
06
07
public void render(Canvas canvas) {
08
canvas.drawColor(Color.BLACK);
09
droid.draw(canvas);
10
// display fps
11
displayFps(canvas, avgFps);
12
}
13
14 private void displayFps(Canvas canvas, String fps) {
15
if (canvas != null && fps != null) {
16
Paint paint = new Paint();
17 paint.setARGB(255, 255, 255, 255);
18 canvas.drawText(fps, this.getWidth() - 50, 20, paint);
19
}
20
}

Try running it. You should have the FPS displayed in the top right corner.

FPS displayed
Reference: Measuring FPS from our JCG partner Tamas Jano from Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

Android Game Development Sprite


Animation
Published on July 23, 2011 | 35,341 views | Filed in: Android Games

If you followed the series so far we are pretty knowledgable in handling touches, displaying
images and moving them around.

But a moving image its a pretty dull sight as it looks really fake and amateurish. To give the
characters some life we will need to do more than that. That is what animation is all about. A
rock is an inanimate object and even if it is thrown, it doesnt change its shape. A human on the
other hand, is very animated. Try throwing one and youll see twitching limbs and even screams
in the air.
Lets just resort to examining walking which is pretty complex in its own. Imagine a human
crossing your way (just in 2D). Youll notice different displays of the body. Left foot in front,
right hand in front while the oposite limbs are behind. This slowly changes so the left foot
remains behind while the right progresses along with the body. But at one point the cycle repeats.
If you dont close your eyes you see the person progressing smoothly. If you close your eyes and
keep them closed for a bit and open them again the person already went on and is in a different
position. Try blinking quite rapidly and you will see something like the old black and white
comedies. That is low frame rate. More on FPS here.
Actually we do want a low frame rate walking for this tutorial, just like this.

The walking presented above is a bit dodgy but its a ripped off version of the sprites from
Monkey Island. Shes Elaine Marley.
This is called a Sprite. It is a simple 2 dimensional image or animation.
To be able to re-create the above animation, we need every frame from the walking cycle.

It is a 150 pixels wide image and each frame is 30 pixels wide.


To illustrate it better check the following image.

To get the above animation in android (or iPhone or in any other program for that matter), we
need to load up each frame as a separate image and display them at regular intervals one after
each other. OR we can load up the big image containing all the frames and use the methods
provided by android do slice and dice them on the fly and to display only the relevant frame.
To do that is trivial. We know that we have 5 frames and each frame is 30 pixels wide. We define
a rectangle (that will be our selection) which has the width of one frame and the height of the
image.
The following image shows how I cut out the first two frames. The rest you should fill in.

Knowing all this lets go create the project. We will use the knowledge from some previous
chapters, most notably about the game loop and the one about the image display (here we set up
the thread that triggers the drawing of the graphics item every frame).
We will need an object to animate. We use Elaine from Monkey Island so I will the class
ElaineAnimated.java.
view source
print?
01
public class ElaineAnimated {
02
03 private static final String TAG = ElaineAnimated.class.getSimpleName();
04
0
private Bitmap bitmap; // the animation sequence
5
0 private Rect sourceRect; // the rectangle to be drawn from the animation
6 bitmap
07 private int frameNr; // number of frames in animation
08 private int currentFrame; // the current frame
09 private long frameTicker; // the time of the last frame update
10 private int framePeriod; // milliseconds between each frame (1000/fps)
1
1
1 private int spriteWidth; // the width of the sprite to calculate the cut out
2 rectangle
13 private int spriteHeight; // the height of the sprite
14
15 private int x; // the X coordinate of the object (top left of the image)
16 private int y; // the Y coordinate of the object (top left of the image)
17
18
}

The private attributes are commented but worth mentioning a few.

bitmap is the png file containing all the frames. The second image in this article.

sourceRect is the selection rectangle. It is the blue window in the image above. The
rectangle moves every frame onto the next.

frameTicker this is the java timestamp of the last frame change in the walking sequence.
Note that this is not the game FPS but the walking FPS. If we want Elaine to perform a
complete walk cycle in a second we set the frame rate for walking to 5 because we have 5
frames. To get a really smooth animation we need 30 frames but its not the point now.

framePeriod is time in milliseconds that represents the period of time a frame is being
displayed. If the cycle completes in 1 second that means for 5 frames the period will be
0.2 seconds. That is, each frame will be displayed for 0.2 seconds.

The constructor is as follows:


view source
print?
0 public ElaineAnimated(Bitmap bitmap, int x, int y, int width, int height, int
1 fps, int frameCount) {
0
this.bitmap = bitmap;
2
03
this.x = x;
04
this.y = y;
05
currentFrame = 0;
06
frameNr = frameCount;
07 spriteWidth = bitmap.getWidth() / frameCount;
08 spriteHeight = bitmap.getHeight();
09 sourceRect = new Rect(0, 0, spriteWidth, spriteHeight);
10 framePeriod = 1000 / fps;
11
frameTicker = 0l;
12
}

Im assuming that the frames are the same width so I calculate the width of the rectangle by
dividing the width of the image with the number of frames. I also pass in the fps which is again,
the frames per second of the walk cycle not the game FPS.
Elaine will have an update method of her own as she is an animated object and she needs to look
good and she is in charge of dragging her feet. Because the period of the game update cycle and
Elaines one might be (in this case is) different we pass the actual game time as a variable so we
know when we need to display the next frame.
For example the game runs very fast and the update is called every 20 milliseconds and we need
to update the frame every 200ms, then the progression of the frame will happen at every 10th
game update.
Heres the code:
view source
print?

01 public void update(long gameTime) {


02 if (gameTime > frameTicker + framePeriod) {
03
frameTicker = gameTime;
04
// increment the frame
05
currentFrame++;
06
if (currentFrame >= frameNr) {
07
currentFrame = 0;
08
}
09 }
10 // define the rectangle to cut out sprite
11 this.sourceRect.left = currentFrame * spriteWidth;
12 this.sourceRect.right = this.sourceRect.left + spriteWidth;
13
}

The update is called from the main game panel (check previous entries how that works). This is
the update method of the MainGamePanel class.
view source
print?
1 public void update() {
2 elaine.update(System.currentTimeMillis());
3
}

The update method is simple (Elaines). It increments the frame if the passed in time (which is
the system time when the update method was called) is greater than the last time (frameTicker)
the frame was updated plus the period of the next update.
If the next frame is beyond the last, we reset the cycle.
After all that area from which the image will be cut out is defined as the sourceRect.
Thats it. Now lets go on to display it.
view source
print?
1
2

public void draw(Canvas canvas) {


// where to draw the sprite
Rect destRect = new Rect(getX(), getY(), getX() + spriteWidth, getY() +
3
spriteHeight);
4 canvas.drawBitmap(bitmap, sourceRect, destRect, null);
5
}

That is all. We set the destination rectangle as to where to draw the cut out image. It is at Elaines
position (X and Y set in the constructor).
view source

print?
1 canvas.drawBitmap(bitmap, sourceRect, destRect, null);

tells android to cut out the image defined by sourceRect from the image contained in bitmap and
draw it into the rectangle on the canvas defined by destRect.
The draw is called from the game panels render method triggered by the game loop (check
previous entries).
The MainGamePanel.java differs slightly from the one from previous chapters. I got rid of all
the droidz and added just Elaine.
view source
print?
01
private ElaineAnimated elaine;
02
03 public MainGamePanel(Context context) {
04 //* ... removed ... */
05
06
// create Elaine and load bitmap
07 elaine = new ElaineAnimated(
08 BitmapFactory.decodeResource(getResources(), R.drawable.walk_elaine)
09 , 10, 50 // initial position
10 , 30, 47 // width and height of sprite
11 , 5, 5); // FPS and number of frames in the animation
12
13 // create the game loop thread
14 thread = new MainThread(getHolder(), this);
15
16
//* ... removed ... */
17
}

Elaine is instantiated in the panels constructor and is given an initial positon of (X=10, Y=50). I
pass in the width and the height of the sprite too but that is ignored anyway, but you can modify
the code.
The FPS is very important and the number of frames too. FPS says how many frames are to be
shown in one second. The last parameter is the number of frames in the cycle.
The thread and activity classes havent changed at all. You can find them in the download as they
are quite long to be pasted. The image is named walk_elaine.png and it was copied to
/res/drawable-mdpi/ so android can pick it up automatically.
If you run the application you should be seeing Elaine performing walking cycles in one place.
We should have used jumping as that can be performed in one place but you get the idea.

Elaine Walking

Enhancement
To make some neat additions modify Elaines draw method so it displays the original image
containing the sprites from which the frames are extracted.
view source
print?
1
2

public void draw(Canvas canvas) {


// where to draw the sprite
Rect destRect = new Rect(getX(), getY(), getX() + spriteWidth, getY() +
3
spriteHeight);
4 canvas.drawBitmap(bitmap, sourceRect, destRect, null);
5 canvas.drawBitmap(bitmap, 20, 150, null);
6 Paint paint = new Paint();
7 paint.setARGB(50, 0, 255, 0);
canvas.drawRect(20 + (currentFrame * destRect.width()), 150, 20 +
8 (currentFrame * destRect.width()) + destRect.width(), 150 +
destRect.height(), paint);
9
}

This just displays the image at (20, 150) and creates a new paint object so we can paint over the
current frame on the original image.
The method setARGB creates a semi-transparent green paint. The first value is 50 which means
its 75% transparent. 0 is completely transparent while 255 is fully opaque.
After everything was drawn we paint a rectangle of the size of a frame onto the original image so
you see which frame is being displayed in the motion.

Walking with Current Frame Painted


Thats it. Run it and you have your first sprite animation.
Download the source code here (animation_walk.tar.gz)
Reference: Sprite Animation with Android from our JCG partner Tamas Jano from Against The
Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

10

Android Game Development Particle


Explosion
Published on August 2, 2011 | 19,264 views | Filed in: Android Games

Ever wondered how explosions are created? Lets take a little detour and try to implement a basic
particle explosion.
An explosion is nothing more than a bunch of particles (be them pixels, small shapes or images)
scattered across the screen, originating from a single point. Not all the time but mostly and for
the sake of simplicity well assume that all particles originate from a single point.
Just think of fireworks. A tiny little rocket shoots up and explodes into hundreds of sparkling
little stars that fade out as they fall down. What happens is that a huge force in the center of the
rocket rips the body apart (thus creating particles) and scatters them randomly around the point
of explosion.
To make it simple well create a few particles, we will place them in one place (the origin) and
give them random forces. A force is a vector quantity. It means that it has magnitude and

direction. The magnitude will determine its speed and its direction will tell the particle which
way to go.
The Particle

The class file:


view source
print?
01
public class Particle {
02
03 public static final int STATE_ALIVE = 0; // particle is alive
04 public static final int STATE_DEAD = 1; // particle is dead
05
06 public static final int DEFAULT_LIFETIME = 200; // play with this
07 public static final int MAX_DIMENSION = 5; // the maximum width or height
08 public static final int MAX_SPEED = 10; // maximum speed (per update)
09
10 private int state; // particle is alive or dead
11 private float width; // width of the particle
12 private float height; // height of the particle
13 private float x, y; // horizontal and vertical position
14 private double xv, yv; // vertical and horizontal velocity
15 private int age; // current age of the particle
16 private int lifetime; // particle dies when it reaches this value
17 private int color; // the color of the particle
18 private Paint paint; // internal use to avoid instantiation
19
}

The particle is nothing more than a little rectangle (this can be an image, circle or any other
shape, but in our case we use a rectangle) with a few properties.
It has a state. This indicates whether the particle is alive or dead. A particle is alive when its
color is not black (it hasnt faded) and its age hasnt reached its lifetime. More on this a bit later.
It has a position. Its position in a 2D coordinate system is represented by 2 points: x and y.
It also has a speed and a direction. As you recall speed is a vector so it has 2 components in 2D.
In 3D it will also have the z component but we stay in 2D for now. To keep it simple now we add
two properties for this. vx and vy
The age of the particle is its 0 in the beginning and is incremented at each update.
The lifetime is the maximum age a particle can reach before it dies.
The rest are color and paint. These are for drawing only.
If you recall the previous entries, the game update is nothing more than calling the update
methods of every entities in the game and displaying them. The update method of the particle is
pretty simple.
But first we need to create the particle:
view source
print?
01
public Particle(int x, int y) {
02
this.x = x;
03
this.y = y;
04
this.state = Particle.STATE_ALIVE;
05 this.widht = rndInt(1, MAX_DIMENSION);
06 this.height = this.widht;
07
this.lifetime = DEFAULT_LIFETIME;
08
this.age = 0;
09 this.xv = (rndDbl(0, MAX_SPEED * 2) - MAX_SPEED);
10 this.yv = (rndDbl(0, MAX_SPEED * 2) - MAX_SPEED);
11 // smoothing out the diagonal speed
12 if (xv * xv + yv * yv > MAX_SPEED * MAX_SPEED) {
13
xv *= 0.7;
14
yv *= 0.7;
1
}
5
1 this.color = Color.argb(255, rndInt(0, 255), rndInt(0, 255), rndInt(0,
6 255));
17
this.paint = new Paint(this.color);
18
}

Check the creation of a particle and it should be straight forward.


You will notice that a particle is created at position x,y.
The state is set to alive.
We want to randomise the size of the rectangles because an explosion creates particles in
different sizes and shapes but well just randomise the size and colour.
I have written a few helper methods that give me random numbers, for this check the complete
source code.
Next the lifetime is set. Every particle will have the same lifetime.
The age is 0 of course as the particle has just been born.
Next is the interesting bit. Its very amateurish. To set the speed I have used 2 random numbers
for the 2 components of the speed vector (vx and vy). The smoothing is needed because if both
components are near the maximum value then the resulting magnitude will be over the max
speed. You could use simple trigonometric functions with a random degree instead of this.
The las thing to set is the color which again is randomised.
There you have it.
The update() method for the particle.
view source
print?
01
public void update() {
02
if (this.state != STATE_DEAD) {
03
this.x += this.xv;
04
this.y += this.yv;
05
06
// extract alpha
07
int a = this.color >>> 24;
08
a -= 2; // fade by 2
09 if (a <= 0) { // if reached transparency kill the particle
10 this.state = STATE_DEAD;
11 } else {
12 this.color = (this.color & 0x00ffffff) + (a << 24); // set the new alpha
13 this.paint.setAlpha(a);
14 this.age++; // increase the age of the particle
15 }
16 if (this.age >= this.lifetime) { // reached the end if its life
17
this.state = STATE_DEAD;
18
}
19
}

20

Its pretty simple. Every update, the position is set according to the speed and the alpha
component of the particles color is decremented. In other words the particle is being faded.
If the age exceeded the lifetime or the opacity is 0 (that means that it is completely transparent)
the particle is declared dead.
If you wonder about the magic with colours, it is quite simple once you get the bitwise operators.
Dont worry, Im rubbish as well, just make sure you know where to look. Here is a good
explanation of colour components and how to use bitwise operators to manipulate them:
http://lab.polygonal.de/2007/05/10/bitwise-gems-fast-integer-math/. Its faster than using the
objects but you can safely use the android methods too.
Just as a side note on colours
You can specify colours in Android as an int. If youre familiar with rgb and argb that is great.
rgb is 24 bits color while argb is 32 bits. It also has the alpha component which is
transparency/opacity.
Opacity values: 0 = transparent, 255 = completely opaque.
To represent an int in hex you just prefix it with 0x. A color in hex is simple: 0x00FF00 is green
for example. The pattern is: 0xRRGGBB (Red, Green, Blue). Now to add the alpha you will add
it to the beginning. 0xAARRGGBB.
Because it is in hex, the values are between 00 and FF. 0 being 0 and FF being 255 in decimal.
When you create a colour out of components like color(a, r, g, b) (for example: new Color(125,
255, 0, 0) creates a semi transparent red), you can simply create it with an integer expressed in
hex like this: new Color(0x80FF0000);
This is how you would extract the components of an argb colour.
view source
print?
1
2
3
4
5

int color = 0xff336699;


int alpha = color >>> 24;
int red = color >>> 16 & 0xFF;
int green = color >>> 8 & 0xFF;
int blue = color & 0xFF;

The draw() method is simple again.


view source
print?

1
2

public void draw(Canvas canvas) {


paint.setColor(this.color);
canvas.drawRect(this.x, this.y, this.x + this.widht, this.y + this.height,
3
paint);
4}

At this stage try to create some particles in your game panel and see what happens.
The Explosion
The explosion is nothing more than hundreds of particles originating from one place, the origin.

In the image above you see the first 4 updates of a simple explosion. All the particles have the
same speed but they spread out in different directions. Each circle is one update.
The main properties of an explosion are:
view source
print?
01
public class Explosion {
02
03 public static final int STATE_ALIVE = 0; // at least 1 particle is alive
04 public static final int STATE_DEAD = 1; // all particles are dead
05
06 private Particle[] particles; // particles in the explosion
07 private int x, y; // the explosion's origin
08 private int size; // number of particles
09 private int state; // whether it's still active or not
10 }

It contains an array of particles. The size is the number of particles. An explosion is alive if it has
at least one particle alive.
The update is extremely simple. It iterates through all the particles and calls the update()
method on each particle. The draw() ditto.
In our application we will create explosions on the screen where we touch it.
The constructor is very simple:
view source
print?
01
02
03
04
05
06
07
08
09
10

public Explosion(int particleNr, int x, int y) {


Log.d(TAG, "Explosion created at " + x + "," + y);
this.state = STATE_ALIVE;
this.particles = new Particle[particleNr];
for (int i = 0; i < this.particles.length; i++) {
Particle p = new Particle(x, y);
this.particles[i] = p;
}
this.size = particleNr;
}

The array of particles is being filled at the touch down position.


In our application we will allow up to 10 explosions. So in the MainGamePanel we declare an
array of explosions.
view source
print?
1

private Explosion[] explosions;

In the surfaceCreated method we instantiate the array and fill it with null.
view source
print?
1 explosions = new Explosion[10];
2 for (int i = 0; i < explosions.length; i++) {
3
explosions[i] = null;
4
}

The onTouchEvent is where we create explosions.

view source
print?
01 public boolean onTouchEvent(MotionEvent event) {
02 if (event.getAction() == MotionEvent.ACTION_DOWN) {
03 // check if explosion is null or if it is still active
04 int currentExplosion = 0;
0
Explosion explosion = explosions[currentExplosion];
5
0 while (explosion != null && explosion.isAlive() && currentExplosion <
6 explosions.length) {
07 currentExplosion++;
08 explosion = explosions[currentExplosion];
09 }
10 if (explosion == null || explosion.isDead()) {
1 explosion = new Explosion(EXPLOSION_SIZE, (int)event.getX(),
1 (int)event.getY());
1
explosions[currentExplosion] = explosion;
2
13
}
14
}
15
return true;
16
}

What we do is iterate through the explosions and when we find the first null (this means we
never used it for an instance) or the first dead explosion we create a new one at the touch
position.
The update and render methods are straight forward. Iterate through the explosions and if they
are not null and are alive then call their update and draw methods respectively.
In the final code I added a border for the screen as the wall and added a basic collision detection
for the particles so they bounce off the walls. The wall is being transmitted as a reference and the
update method checks for collision with it. Use it as an exercise and remove the collision and try
attaching an image to the particle instead of being a rectangle. To create explosions just click on
the screen.
It should look like this:

Explore the code and have fun.


Download it here (android.particles.tgz).
Reference: Particle Explosion with Android from our JCG partner Tamas Jano from Against
The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

11

Android Game Development Design Ingame Entities The Strategy Pattern


Published on August 17, 2011 | 14,982 views | Filed in: Android Games

In this part I will try to explain what I understand on good game design elements. I will use
droids in the examples and I will script a basic fight simulator to see how they behave.

The problem:
I command a single robot and I want to obliterate my enemies. To face the same type of enemy
all over again is boring. I need new challenges and this means new types of enemies. For
example in the first level I want only to practice my target. So I need a pretty dumb enemy that
does not do much but takes the shots. After I mastered that skill (shooting a helpless droid), I
need a bit of a challenge and I want the enemy droid to fight back, but because I am still a

beginner I dont want to die quickly so I need weak droids. After I am over with them I want a
tougher challenge. I need better and stronger droids. Not just stronger, but different in behaviour
as well as it can get boring killing the same type of enemy over and over again.

The obvious solution:


Create 3 classes for the 3 types of enemy droids. To keep it simple, each droid has 2 abilities:
move and attack. It makes sense to create a Droid interface with these two methods and have
each droid implement them.
They can move and shoot. Well, not all of them but we can provide an empty implementation for
the ones that do nothing.
The droid types:

Decoy Droid will have no weapon and cant move.

Scout Droid will have a weak weapon and moves fast.

Assault Droid will have a heavy weapon and moves slowly.

Looking at the 3 types we can implement the following simple class diagram:

The interface has 3 simple methods which the droids need to implement:
view source
print?
01
02
03
04

public interface Droid {


// display some info of the droid
public void display();

05
06
07
08
09
10
11

// move the droid


public void move(int x, int y);
// attack position
public void shoot(int x, int y);
}

The 3 classes are as follow:


DecoyDroid.java
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16

public class DecoyDroid implements Droid {


@Override
public void display() {
System.out.println("I am a DECOY droid");
}
@Override
public void move(int x, int y) {
System.out.println("Can't move.");
}
@Override
public void shoot(int x, int y) {
System.out.println("Have no weapon.");
}
}

ScoutDroid.java
view source
print?
01
02
03
04
05
06
07
08
09

public class ScoutDroid implements Droid {


private float damage = 0.5f;
@Override
public void display() {
System.out.println("I am a scout droid");
}

10
11
12
13
14
15
16
17
18
19
20

@Override
public void move(int x, int y) {
System.out.println("Moving QUICKLY to: " + x + "," + y + ".");
}
@Override
public void shoot(int x, int y) {
System.out.println("Light Laser Canon targeting: " + x + "," + y
+ ". Damage: " + damage);
}
}

AssaultDroid.java
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

public class AssaultDroid implements Droid {


private float damage = 2.5f;
private boolean loaded = true;
@Override
public void display() {
System.out.println("I am an ASSAULT droid");
}
@Override
public void move(int x, int y) {
System.out.println("Moving SLOWLY to: " + x + "," + y + ".");
}
@Override
public void shoot(int x, int y) {
if (loaded) {
System.out.println("Heavy laser targeting: " + x + "," + y
+ ". Damage: " + damage);
loaded = false;
} else {
System.out.println("Reloading...");
loaded = true;
}
}
}

Both ScoutDroid and AssaultDroid have the argument damage. This holds the value of the
damage inflicted by them.

To give the AssaultDroid a heavy weapon with a slow reload time we added the loaded variable.
This way it takes the assault droid two turns to fire its weapon once.
I have created a simple simulator for the droids to take turns to move and shoot.
Run the simulator for this design:
BadDroidSimulator.java
view source
print?
01
public class BadDroidSimulator {
02
03 public static void main(String[] args) {
04 // for generating random numbers
05
Random rand = new Random();
06
07
Droid scout = new ScoutDroid();
08
Droid assailant = new AssaultDroid();
09
Droid decoy = new DecoyDroid();
10
11
scout.display();
12
assailant.display();
13
decoy.display();
14
15 // shoot-out - each droid fires once per turn
16 for (int i = 1; i <= 5; i++) {
1
System.out.println("\n<=== BEGIN TURN " + i + " ===>");
7
1 scout.shoot(rand.nextInt(10), rand.nextInt(10)); // we assume this is an
8 enemy position
19 scout.move(rand.nextInt(10), rand.nextInt(10));
20 System.out.println();
21 assailant.shoot(rand.nextInt(10), rand.nextInt(10));
22 assailant.move(rand.nextInt(10), rand.nextInt(10));
23 System.out.println();
24 decoy.shoot(rand.nextInt(10), rand.nextInt(10));
25 decoy.move(rand.nextInt(10), rand.nextInt(10));
26 System.out.println("<=== END TURN " + i + " ===>");
27
}
28
}
29
}

The result (console output) will look like this:


view source

print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

I am a scout droid
I am an ASSAULT droid
I am a DECOY droid
<=== BEGIN TURN 1 ===>
Light Laser Canon targeting: 9,0. Damage: 0.5
Moving QUICKLY to: 4,6.
Heavy laser targeting: 6,2. Damage: 2.5
Moving SLOWLY to: 9,1.
Have no weapon.
Cant move.
<=== END TURN 1 ===>
<=== BEGIN TURN 2 ===>
Light Laser Canon targeting: 3,4. Damage: 0.5
Moving QUICKLY to: 6,5.
Reloading
Moving SLOWLY to: 1,6.
Have no weapon.
Cant move.
<=== END TURN 2 ===>
<=== BEGIN TURN 3 ===>
Light Laser Canon targeting: 6,7. Damage: 0.5
Moving QUICKLY to: 9,7.
Heavy laser targeting: 7,1. Damage: 2.5
Moving SLOWLY to: 2,0.
Have no weapon.
Cant move.
<=== END TURN 3 ===>
<=== BEGIN TURN 4 ===>
Light Laser Canon targeting: 3,7. Damage: 0.5
Moving QUICKLY to: 1,4.
Reloading
Moving SLOWLY to: 5,9.
Have no weapon.
Cant move.
<=== END TURN 4 ===>

47
48
49
50
51
52
53
54
55
56
57

<=== BEGIN TURN 5 ===>


Light Laser Canon targeting: 0,8. Damage: 0.5
Moving QUICKLY to: 3,9.
Heavy laser targeting: 1,2. Damage: 2.5
Moving SLOWLY to: 3,2.
Have no weapon.
Cant move.
<=== END TURN 5 ===>

Challenges to extend the design


The droids take turns to move and shoot. This is all good, but:

What if you want to create a hybrid droid? A droid that moves as fast as the scout but
with a heavy weapon? You will have to create a new class and copy paste the respective
methods from the Scout and Assault droid, right?

Also imagine that the shooting mechanism is not that simple and it needs collision
detection and so on. For each droid the same redundant code needs to be rewritten.

What if the fire power could be enhanced with power ups?

What if the droid gains self-conscientiousness and finds a weapon to use it instead of the
current one?

I am sure you have plenty ideas on how to enhance the gameplay and extend the world but the
most obvious solution (described above) seems ill-suited for this. It requires new droid classes to
be created and each droid type will implement its methods separately. Many of these methods are
identical. The current design doesnt allow you to change the droids internals at runtime without
significant effort.
Here is one proposed solution: Composition and the Strategy Pattern.

Designing a Droid (properly)


A very simple droid consists of a weapon put on a chassis. The first design consisted of a is a
type relationship. A ScoutDroid is a generic Droid with some peculiarities.
Composition is based on has a relationships. A Droid has a Chassis. A Droid has a Weapon.
What type of components a droid has, determines its type.

Lets decompose the Scout Droid for example.


The Scout Droid is a Droid which has a Light Laser Canon has a set of Wheels to move. We
want to make the scout move quickly with a light weapon.
The Assault Droid on the other hand is a Droid too but it has a Heavy Laser Canon and it runs
on Tracks. This makes it extremely powerful but a bit slow.
Think from a factory perspective. How does a car production line work? You get the chassis with
a specific place for the engine, wheels, drive-shaft, gear-box and so on.
All these components are produced separately. The teams that produce them have no idea of the
other parts. They must fulfil one criteria: the gearbox must fit in perfectly in its place and
connected up with the engine.. Different makes have different ways of doing this. The connector
in this instance is the interface.
The engine has a similar story. If it hooks up nicely with the wheels and gearbox then it can be
fitted. Its internal design, capacity, power, fuel consumption can be completely different. The
engine is one of the cars components.
So is our droid. But to keep it simple we have only 2 components. We need one generic droid
that has all the wirings built so its components will be triggered by the droid through those
interfaces. For example a droid needs to only pull the trigger of the weapon and doesnt care
what type of weapon it is as long as it has a trigger. The droid needs to understand the
pullTrigger method and to do this it needs to be implemented, in order for us to give weapons to
the droid to use.
The same thing with the changing of location. It needs to trigger the movement. The wheels or
track or anti-gravity propulsion will take the droid there. The droid only needs to set the
coordinates.
To fulfil this we need a class with implemented methods instead of an interface.
We create the abstract Droid class. We make it abstract because we actually implement the
methods that trigger the weapon, and action the moving mechanism but we dont have concrete
weapons and movement mechanisms attached to the droid. The assembly of a concrete droid will
be delegated to the type constructor along with the description method.
view source
print?
01
public abstract class Droid {
02
03 protected Weapon weapon; // the weapon which will be used in fights
04 protected Chassis chassis; // the chassis on which the droid is placed
05
06 public void moveToPosition(int x, int y) {
07
System.out.print(id + " > " );
08
chassis.moveTo(x, y);
09
}
10
11 /**

12 * Engages the position on the screen whether it is occupied by


13 * an enemy or not. Each strategy should decide how to do it.
14 */
15 public void attackPosition(int x, int y) {
16 System.out.print(id + " > ");
17
weapon.useWeapon(new Vector2f(x, y));
18
}
19
20
/**
21
* Displays some info on the droid
22
*/
23
public abstract void display();
24
}

If you examine the class you will see that the Droid has 3 methods from which 2 are
implemented. It also has two components: Weapon and Chassis.
The components are interfaces so the droid does not know what it is doing when triggering the
actions on them. It is all delegated to the implementation.
The interfaces are as follows:
Weapon.java
view source
print?
01
public interface Weapon {
02
/**
03 * The trigger to use the weapon.
04 * @param target - where on the map is the target
05 */
06 public void useWeapon(Vector2f target);
07
08
/**
09 * Returns the description of the weapon
10 */
11
public String getDescription();
12
}

Chassis.java
view source
print?
01
public interface Chassis {
02
/**
03 * Delegates the movement to the supporting chassis and

04 * tries to move the unit to x,y


05
*/
06
public void moveTo(int x, int y);
07
08
/**
09 * Returns the description of the chassis
10 */
11
public String getDescription();
12
}

We will enhance our base Droid class. We will add setter and getter methods for both Weapon
and Chassis. This will allow us to change the droids behaviour at runtime. This is what the
strategy pattern is all about. A Droid has behaviours: it can use a weapon and it can move.
These two strategies (behaviours) need to be implemented.
We also add an id which will be unique in our game for each droid instance. I use a very simple
id generation strategy. I increment the nextId static field and append it to the concrete droid type
prefix in the constructor for each type.
Here is the new Droid class:
view source
print?
01
public abstract class Droid {
02
03 protected static int nextId = 0; // the next available ID
04
05 protected String id; // unique id
06 protected Weapon weapon; // the weapon which will be used in fights
07 protected Chassis chassis; // the chassis on which the droid is placed
08
09 // the unique ID of the droid in the game
10 public String getId() {
11
return id;
12
}
13
14
public Weapon getWeapon() {
15
return weapon;
16
}
17 public void setWeapon(Weapon weapon) {
18 this.weapon = weapon;
19
}
20
21
public Chassis getChassis() {
22
return chassis;
23 }

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

public void setChassis(Chassis chassis) {


this.chassis = chassis;
}
public void moveToPosition(int x, int y) {
System.out.print(id + " > " );
chassis.moveTo(x, y);
}
/**
* Engages the position on the screen whether it is occupied by
* an enemy or not. Each strategy should decide how to do it.
*/
public void attackPosition(int x, int y) {
System.out.print(id + " > ");
weapon.useWeapon(new Vector2f(x, y));
}
/**
* Displays some info on the droid
*/
public abstract void display();
}

Lets build some weapons


NoWeapon.java
view source
print?
01 /**
02 * This is a null object. A null object is a dummy that does nothing and it
03 * is a mere place-holder and eliminates the need to check for null.
04 * @author impaler
05
*
06
*/
07 public class NoWeapon implements Weapon {
08
09 @Override
10 public void useWeapon(Vector2f target) {
11 // We are doing nothing
12 System.out.println("No weapon equipped!");
13
}
14
15
@Override
16
public String getDescription() {

17
18
19

return "Nothing";
}
}

This is the null object. The class description should give you an idea what it is.
LightLaserCanon.java
view source
print?
01 /**
02 * This is a light laser cannon whit a quick reload time and high accuracy
03
*
04
* @author impaler
05
*
06
*/
07 public class LightLaserCanon implements Weapon {
08
09 private float damage = 0.5f; // the damage inflicted
10
11 @Override
12 public void useWeapon(Vector2f target) {
13 System.out.println("Shooting my laser canon to " + (int)target.getX() + ","
14 + (int)target.getY() + ". Bang on! Done " + damage + " damage.");
15
}
16
17
@Override
18
public String getDescription() {
19 return "First generation laser canon. Street use only!";
20 }
21
}

HeavyLaserCanon.java
view source
print?
0
/**
1
0 * This is a heavy assault laser cannon with high accuracy but slow reload
2 time.
03
* @author impaler
04
*/
05 public class HeavyLaserCanon implements Weapon {
06
07 private boolean loaded = true; // after fire needs to be reloaded

08 private float damage = 1.5f; // the damage is considerable


09
10
@Override
11 public void useWeapon(Vector2f target) {
12 if (loaded) {
1
// we fire the canon
3
1 System.out.println("Eat this! Laser beam hit target (" + (int)target.getX()
4 + "," + (int)target.getY() + ") and dealt " + damage + " damage.");
15
// next time needs reloading
16
loaded = false;
17 } else {
18 System.out.println("Darn! Out of ammo! Reloading...");
19
loaded = true;
20
}
21
}
22
23
@Override
24
public String getDescription() {
2 return "DASS-5000 - The ultimate in siege weaponry provided by Obviam
5 Enterprises.";
2
}
6
27
}

You might notice the Vector2f class. This is a very basic 2D vector class which currently holds
the x and y coordinates. Nothing more. You can find it in the downloaded source.

Lets build some chassis


The getDescription() method says what the chassis is like.
NoChassis.java null object (see weapons)
view source
print?
01 public class NoChassis implements Chassis {
02
03
@Override
04
public void moveTo(int x, int y) {
05 System.out.println("It's just a frame. Can't move.");
06 }
07
08
@Override
09
public String getDescription() {
10
return "It's just a frame.";

11
12

}
}

SteelStand.java
view source
print?
01 public class SteelStand implements Chassis {
02
03
@Override
04
public void moveTo(int x, int y) {
05
System.out.println("Can't move.");
06
}
07
08
@Override
0
public String getDescription() {
9
1 return "Unmovable reinforced steel stand ideal for turrets and defensive
0 units.";
11
}
12
}

Wheels.java
view source
print?
01 public class Wheels implements Chassis {
02
03
@Override
04
public void moveTo(int x, int y) {
05 System.out.println("Speeding to " + x + "," + y + " on my wheels!");
06 }
07
08
@Override
0
public String getDescription() {
9
1 return "4 wheel drive, very fast on flat terrain but struggling through
0 obstacles.";
11
}
12
}

Track.java
view source

print?
01 public class Track implements Chassis {
02
03
@Override
04
public void moveTo(int x, int y) {
0 System.out.println("Don't get in my way! Moving slowly to: " + x + "," + y +
5 ".");
0
}
6
07
08
@Override
09 public String getDescription() {
10 return "Slow moving tracks but able to go through many obstacles.";
11
}
12
}

Now we can assemble our droids


First lets create a DecoyDroid. This droid will have no weapon and will be placed on a steel
stand. Its for our target practice, remember?
DecoyDroid.java
view source
print?
01 public class DecoyDroid extends Droid {
02
03
public DecoyDroid() {
04
id = "DCY-" + (++Droid.nextId);
05
weapon = new NoWeapon();
06
chassis = new SteelStand();
07
}
08
09
@Override
10
public void display() {
1 System.out.println("+-----------------------------------------------------1 --------------------------------------+");
1
System.out.println("| I am a DECOY droid.");
2
13 System.out.println("|\tID: " + id);
14 System.out.println("|\tWeapon: " + weapon.getDescription());
1
System.out.println("|\tChassis: " + chassis.getDescription());
5
1 System.out.println("+-----------------------------------------------------6 --------------------------------------+");
17
}

18

Examine the default constructor. It creates an id and assigns an instance of NoWeapon and
SteelStand to the droid.
The display() method is more elaborate than before but just to describe the droid better. It makes
use of the components descriptions too.
If you instantiate a DecoyDroid and call its display method you will get a nice description of it.
view source
print?
1
2
3
4

++
| I am a DECOY droid.
| ID: DCY-3
| Weapon: Nothing
| Chassis: Unmovable reinforced steel stand ideal for turrets and defensive
5
units.
6 ++

Lets build the rest of the types:


ScoutDroid.java
view source
print?
01 public class ScoutDroid extends Droid {
02
03
public ScoutDroid() {
04
id = "SCT-" + (++Droid.nextId);
05
weapon = new LightLaserCanon();
06
chassis = new Wheels();
07
}
08
09
@Override
10
public void display() {
1 System.out.println("+-----------------------------------------------------1 --------------------------------------+");
1
System.out.println("| I am a SCOUT droid.");
2
13 System.out.println("|\tID: " + id);
14 System.out.println("|\tWeapon: " + weapon.getDescription());
1
System.out.println("|\tChassis: " + chassis.getDescription());
5
1 System.out.println("+-----------------------------------------------------6 --------------------------------------+");
17
}

18

AssaultDroid.java
view source
print?
01 public class AssaultDroid extends Droid {
02
03
public AssaultDroid() {
04
id = "ASS-" + (++Droid.nextId);
05
weapon = new HeavyLaserCanon();
06
chassis = new Track();
07
}
08
09
@Override
10
public void display() {
1 System.out.println("+-----------------------------------------------------1 --------------------------------------+");
1
System.out.println("| I am an ASSAULT droid.");
2
13 System.out.println("|\tID: " + id);
14 System.out.println("|\tWeapon: " + weapon.getDescription());
1
System.out.println("|\tChassis: " + chassis.getDescription());
5
1 System.out.println("+-----------------------------------------------------6 --------------------------------------+");
17
}
18
}

You will notice that the only things needed to be implemented are the constructor which adds
the chassis and weapon and the display() method.
The following diagram shows the new architecture:

Lets create a test script for it. Well simulate 5 turns in which each droid will use its weapon and
move to a random location. Check the behaviour of each weapon and you will notice that the
heavy laser will fire once every 2 turns. To make it interesting, in turn 4 we give a
HeavyLaserCanon to DecoyDroid. Look at how it changes the droids behaviour and it starts
firing. This is a hybrid droid created on the fly at runtime.
The simulator code (DroidSimulator.java):
view source
print?
01
public class DroidSimulator {
02
03 public static void main(String[] args) {
04 // for generating random numbers
05
Random rand = new Random();
06
07
Droid scout = new ScoutDroid();
08
Droid assailant = new AssaultDroid();
09
Droid decoy = new DecoyDroid();
10
11
scout.display();
12
assailant.display();
13
decoy.display();
14
15 // shoot-out - each droid fires once per turn
16 for (int i = 1; i <= 5; i++) {
17 System.out.println("\n<=== BEGIN TURN " + i + " ===>");
18 // in turn 3 decoy droid is given an assault canon
19 if (i == 4) {
20 decoy.setWeapon(new HeavyLaserCanon());
2 System.out.println("* " + decoy.getId() + " acquired " +
1 decoy.getWeapon().getDescription() + "\n");
2
}
2
2 scout.attackPosition(rand.nextInt(10), rand.nextInt(10)); // we assume this
3 is an enemy position
2
scout.moveToPosition(rand.nextInt(10), rand.nextInt(10));
4
25 System.out.println();
26 assailant.attackPosition(rand.nextInt(10), rand.nextInt(10));
27 assailant.moveToPosition(rand.nextInt(10), rand.nextInt(10));
28 System.out.println();
29 decoy.attackPosition(rand.nextInt(10), rand.nextInt(10));
30 decoy.moveToPosition(rand.nextInt(10), rand.nextInt(10));
31 System.out.println("<=== END TURN " + i + " ===>");
32 }
33
}

34

The output:
view source
print?
01
++
02
| I am a SCOUT droid.
03 | ID: SCT-1
04 | Weapon: First generation laser canon. Street use only!
0 | Chassis: 4 wheel drive, very fast on flat terrain but struggling through
5 obstacles.
0
++
6
07
++
08
| I am an ASSAULT droid.
0
| ID: ASS-2
9
1 | Weapon: DASS-5000 The ultimate in siege weaponry provided by Obviam
0 Enterprises.
11 | Chassis: Slow moving tracks but able to go through many obstacles.
12 ++
13
++
14
| I am a DECOY droid.
15
| ID: DCY-3
16
| Weapon: Nothing
1 | Chassis: Unmovable reinforced steel stand ideal for turrets and defensive
7 units.
1
++
8
19 <=== BEGIN TURN 1 ===>
20 SCT-1 > Shooting my laser canon to 0,3. Bang on! Done 0.5 damage.
21 SCT-1 > Speeding to 0,2 on my wheels!
22
23 ASS-2 > Eat this! Laser beam hit target (3,4) and dealt 1.5 damage.
24 ASS-2 > Dont get in my way! Moving slowly to: 3,8.
25
26
DCY-3 > No weapon equipped!
27
DCY-3 > Cant move.
28
<=== END TURN 1 ===>
29
30
<=== BEGIN TURN 2 ===>
31 SCT-1 > Shooting my laser canon to 4,0. Bang on! Done 0.5 damage.
32 SCT-1 > Speeding to 5,0 on my wheels!
33
34 ASS-2 > Darn! Out of ammo! Reloading
35 ASS-2 > Dont get in my way! Moving slowly to: 1,6.

36
37
DCY-3 > No weapon equipped!
38
DCY-3 > Cant move.
39
<=== END TURN 2 ===>
40
41 <=== BEGIN TURN 3 ===>
42 SCT-1 > Shooting my laser canon to 3,0. Bang on! Done 0.5 damage.
43 SCT-1 > Speeding to 0,6 on my wheels!
44
45 ASS-2 > Eat this! Laser beam hit target (9,1) and dealt 1.5 damage.
46 ASS-2 > Dont get in my way! Moving slowly to: 8,0.
47
48
DCY-3 > No weapon equipped!
49
DCY-3 > Cant move.
50
<=== END TURN 3 ===>
51
52
<=== BEGIN TURN 4 ===>
5 * DCY-3 acquired DASS-5000 The ultimate in siege weaponry provided by
3 Obviam Enterprises.
5
4
55 SCT-1 > Shooting my laser canon to 8,6. Bang on! Done 0.5 damage.
56 SCT-1 > Speeding to 2,3 on my wheels!
57
58 ASS-2 > Darn! Out of ammo! Reloading
59 ASS-2 > Dont get in my way! Moving slowly to: 0,6.
60
61 DCY-3 > Eat this! Laser beam hit target (9,4) and dealt 1.5 damage.
62 DCY-3 > Cant move.
63
<=== END TURN 4 ===>
64
65 <=== BEGIN TURN 5 ===>
66 SCT-1 > Shooting my laser canon to 1,7. Bang on! Done 0.5 damage.
67 SCT-1 > Speeding to 1,9 on my wheels!
68
69 ASS-2 > Eat this! Laser beam hit target (1,4) and dealt 1.5 damage.
70 ASS-2 > Dont get in my way! Moving slowly to: 3,6.
71
72 DCY-3 > Darn! Out of ammo! Reloading
73
DCY-3 > Cant move.
74
<=== END TURN 5 ===>

Note in turn 4 how DecoyDroid got the new weapon and changed its behaviour (the yellow line).
Now you should understand the null object pattern as well.
As it stands now, it is easy to create new weapons, chassis and droids by keeping the code to a
minimum. Always favour composition over inheritance in these situations. You can create a very
elaborate droid, with shields, sensors, an array of weapons and also an AI component which

decides what weapons to use according to the situation. If you have noticed, I used the term
use instead of fire, because a weapon can be a melee one too and not necessarily a ranged
weapon.
The downloadable project contains only the strategy pattern implementation. The simple
inheritance approach is left out. Play with it and get the grips of this useful pattern as I will use it
extensively and it is considered good design. It is a simple Java application, it is not Android
enabled.
Dowload the source here (obviam.compositions.part1.tgz).
In the following parts Ill try to add some AI capabilities and how to compose the final droid
from images of its components.
Reference: Design In-game Entities. Object Composition Strategies. Part 1 The Strategy
Pattern from our JCG partner Tamas Jano from Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

12

Android Game Development Using


Bitmap Fonts
Published on September 12, 2011 | 11,215 views | Filed in: Android Games

Android is an OS running on many types of devices with different screen sizes. Because of that it
is pretty difficult to address font related issues regarding both size and appearance on these
platforms.
To use a consistent font face across devices I have used bitmap fonts. That is, each character is
represented by a bitmap.
We can create an image for each letter in the alphabet and number for example and whenever we
want to display a text, we draw the images of the characters from the string at the given position.
But wait! Isnt loading an image for every character overkill? Yes it is. We can use androids
utilities for manipulating bitmaps to our advantage.
All we need is a bitmap containing all the characters we want to use and slice it up into
individual bitmaps. To do this the easy way we will use a monospaced font. A monospaced font
is a font whose letters and characters occupy the same horizontal space. In other words, the
characters have the same width.
A simple character map can look like this.

Note that the background is transparent.


The above character map is arranged in a grid. The width of a character is 8 pixels. The height is
12 pixels. Note that the second row starts at 15 pixels so there is a gap between the rows. Its just
a choice and also how Photoshop broke the lines and I didnt bother to change them.

The above image shows the beginning of the first row and how the characters are organised into
cells.
Following this it is easy to slice it up. A simple for iteration will do the trick. To keep things
simple I have created a map of only the English alphabet, digits and a few punctuation marks.
You can extend it as you wish. Use a monospaced font in Photoshop or Gimp or whatever image
editor you fancy and create your own sheet.
Here are plenty of bitmap fonts to choose from.
How can we use this? My idea to display text onto the screen is to create a drawString method
that takes the text to be displayed as a parameter along with the position where we want to
display it.
Something like this will do it:
view source
print?
1 void drawString(Canvas canvas, String text, int x, int y)

I also pass the canvas object in, onto which I want to draw the text. This is just for simplicity. In
case of an OpenGL renderer we will have to use billboards (squares with textures). But for the
purpose of slicing images and displaying fonts lets stick with this approach.
Create a simple Android project that use simple 2D canvas. We will draw onto that.
I implemented the SurfaceView to hold my canvas and called it DrawingPanel.
In its constructor I simply register it to receive events when touching the surface and load the
resources. The resources are in fact just the images of the glyphs/characters.

Download the following image file and drag it into your eclipses projects resource folder under:
/res/drawable-mdpi for ADP to generate the id for the resource.

Create the DrawingPanel class.


view source
print?
0 public class DrawingPanel extends SurfaceView implements
1 SurfaceHolder.Callback {
0
2
03 private Canvas canvas; // the canvas to draw on
04 private Glyphs glyphs; // the glyphs
05
06 public DrawingPanel(Context context) {
07
super(context);
08
// adding the panel to handle events
09
getHolder().addCallback(this);
10
11
// initialise resources
12
loadResources();
13
14 // making the Panel focusable so it can handle events
15
setFocusable(true);
16
}
17
18 /** Loads the images of the glyphs */
1
private void loadResources() {
9
2 this.glyphs = new Glyphs(BitmapFactory.decodeResource(getResources(),
0 R.drawable.glyphs_green));
21
Log.d(TAG, "Green glyphs loaded");
22
}

I omitted the other methods that need to be implemented as they are just stubs.
The canvas variable is used to draw the text onto and is obtained at every touch event. Youll see
later in the onTouchEvent method.
The most interesting class is the Glyphs class which holds the association of characters with
images. The glyphs variable is instantiated in the loadResources() method. It calls the
constructor of the Glyphs class with the character sheet image copied earlier.

Check out the Glyphs class:


view source
print?
01
package net.obviam.fonts;
02
03
import java.util.HashMap;
04
import java.util.Map;
05
06
import android.graphics.Bitmap;
07
import android.graphics.Canvas;
08
import android.util.Log;
09
10
/**
11
* @author impaler
12
*
13
*/
14
public class Glyphs {
15
16 private static final String TAG = Glyphs.class.getSimpleName();
17 private Bitmap bitmap; // bitmap containing the character map/sheet
18
19 // Map to associate a bitmap to each character
20 private Map<Character, Bitmap> glyphs = new HashMap<Character, Bitmap>(62);
21
22 private int width; // width in pixels of one character
23 private int height; // height in pixels of one character
24
25 // the characters in the English alphabet
26 private char[] charactersL = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g',
27 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
28 'u', 'v', 'w', 'x', 'y', 'z' };
29 private char[] charactersU = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G',
30 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
31 'U', 'V', 'W', 'X', 'Y', 'Z' };
32 private char[] numbers = new char[] { '1', '2', '3', '4', '5', '6', '7',
33
'8', '9', '0' };
34
35
public Glyphs(Bitmap bitmap) {
36
super();
37
this.bitmap = bitmap;
38
this.width = 8;
39
this.height = 12;
40
// Cutting up the glyphs
41 // Starting with the first row - lower cases
42 for (int i = 0; i < 26; i++) {

43 glyphs.put(charactersL[i], Bitmap.createBitmap(bitmap,
44 0 + (i * width), 0, width, height));
45 }
46 Log.d(TAG, "Lowercases initialised");
47
48 // Continuing with the second row - upper cases
49 // Note that the row starts at 15px - hardcoded
50 for (int i = 0; i < 26; i++) {
51 glyphs.put(charactersU[i], Bitmap.createBitmap(bitmap,
52 0 + (i * width), 15, width, height));
53
}
54
// row 3 for numbers
55 Log.d(TAG, "Uppercases initialised");
56 for (int i = 0; i < 10; i++) {
57 glyphs.put(numbers[i], Bitmap.createBitmap(bitmap,
58 0 + (i * width), 30, width, height));
59
}
60
Log.d(TAG, "Numbers initialised");
61
62
// TODO - 4th row for punctuation
63
}
64
65
public Bitmap getBitmap() {
66
return bitmap;
67
}
68
69 /**
70 * Draws the string onto the canvas at <code>x</code> and <code>y</code>
71
* @param text
72
*/
73 public void drawString(Canvas canvas, String text, int x, int y) {
74 if (canvas == null) {
75
Log.d(TAG, "Canvas is null");
76
}
77 for (int i = 0; i < text.length(); i++) {
78 Character ch = text.charAt(i);
79 if (glyphs.get(ch) != null) {
80 canvas.drawBitmap(glyphs.get(ch), x + (i * width), y, null);
81
}
82
}
83
}
84
}

The line
view source
print?

1 private Map<Character, Bitmap> glyphs = new HashMap<Character, Bitmap>(62);

creates the map which associates a bitmap to each character.


To load this up we need the bitmaps for each character. I have created 3 arrays for the characters
for which I have bitmaps.
charactersL[] holds the lower case letters of the English alphabet, charactersU[] the upper case
letters and numbers[] holds the numbers. As an exercise add the punctuation array as this one is
missing.
Note that the order of the characters is the same as in the character sheet.
For convenience I have created an array for each row from the image. To associate the images
with the characters I will iterate through them and cut out the respective image from the sheet
based on the index. Having a fixed width for the characters, makes all this dead easy. Examine
carefully and understand the constructor. It does the slicing and association.
The drawString(Canvas canvas, String text, int x, int y) method does the drawing. It takes the
position where to draw, iterates through the passed in text and draws every character
progressively. It is easy to calculate the horizontal offset as each character has the same width.
That is it. To try it out add the following method to the DrawingPanel:
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23

public boolean onTouchEvent(MotionEvent event) {


// draw text at touch
try {
canvas = getHolder().lockCanvas();
synchronized (getHolder()) {
if (event.getAction() == MotionEvent.ACTION_DOWN
|| event.getAction() == MotionEvent.ACTION_MOVE) {
// clear the screen
canvas.drawColor(Color.BLACK);
// draw glyphs
glyphs.drawString(canvas, "Drawing string at "
+ (int) event.getX() + " " + (int) event.getY(),
(int) event.getX(), (int) event.getY());
}
if (event.getAction() == MotionEvent.ACTION_UP) {
canvas.drawColor(Color.BLACK);
glyphs.drawString(canvas, "Drawn string at "
+ (int) event.getX() + " " + (int) event.getY(),
(int) event.getX(), (int) event.getY());
}
}
} finally {
if (canvas != null) {

24
25
26
27
28
29

getHolder().unlockCanvasAndPost(canvas);
}
}
// event was handled
return true;
}

Every time we touch the screen, we try to get hold of the canvas to be able to draw onto it. In
case of a touch or drag we simply clear the canvas and draw the string onto it.
When we stopped touching the screen we display a slightly different text at the last position.
Finally we release the canvas. Make sure you return true to signal that the event was handled.
That is it. One last thing needed is to set the DrawingPanel to be our view. This one is done in
the activity created with the project. I have also disabled the title.
view source
print?
01
02
03
04
05
06
07
08
09
10

public class PrintingActivity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// turn off title
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new DrawingPanel(this));
}
}

The resulting application should look like this:

To do this with OpenGL follow the same principle and use the bitmaps for textures. I will publish
an OpenGL version of this article at some point so stay tuned.

Download the code here (obviam.bitmapfont.tar.gz).


Reference: Using Bitmap Fonts in Android from our JCG partner Tamas Jano from Against
The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

13

Android Game Development Switching


from Canvas to OpenGL ES
Published on September 30, 2011 | 19,886 views | Filed in: Android Games

It is about time we delve into the graphical capabilities of the Android platform. Android
supports the OpenGL ES API. Needless to say that offloading graphics handling to a dedicated
GPU is way more optimal than doing it in the CPU. Most android devices have such a dedicated
GPU.
OpenGL is an API for writing 2D and 3D graphics that is rendered on the GPU. This will free up
precious computing resources on the CPU to be used for more complex physics or more entities
or anything not related to graphics.
There are a few notions that need to be understood but I will introduce them when we will bump
into them during the course.
If you followed the articles related to displaying graphics on an android device, you already
know that in order to display graphical elements, we need a surface and a renderer. We used a
basic SurfaceView from which we obtained the Canvas and we drew everything onto it by
calling the supported draw method from within our game loop.
Using OpenGL is not much different. Android comes with a dedicated implementation of the
SurfaceView interface for displaying images rendered by OpenGL.
Lets create the android project the usual way.

New Project Wizard


I call the activity simply Run. Check what the wizard has generated and it should look like this:
view source
print?
1
2
3
4

public class Run extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

5
6
7
8

super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Nothing special.

Creating the OpenGL renderer


Lets build the renderer. Create a class GlRenderer which implements the
android.opengl.GLSurfaceView.Renderer interface.
It will look like this:
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView.Renderer;
public class GlRenderer implements Renderer {
@Override
public void onDrawFrame(GL10 gl) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
}

We need to implement the above 3 methods. Currently they are empty and do nothing.

The methods
onSurfaceCreated(GL10 gl, EGLConfig config)created or recreated. It is important to bear
the recreated bit in mind as it means every time the device goes to sleep for example and
awakes, the surface gets recreated. Because the context which holds the resources gets destroyed
too, this is the place where we will load our resources (images for textures, etc).

onSurfaceChanged(GL10 gl, int width, int height) is called whenever the surface size
changes. This mainly affects our viewport. The viewport is just a rectangular region through
which we see our game world.
onDrawFrame(GL10 gl) is called by the rendering thread to draw each frame. This is where all
the drawing happens. We dont need to call it explicitly. A rendering thread is created by android
for us and that will call it.
Lets switch to the OpenGL renderer. Check out the new Run activity.
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

package net.obviam.opengl;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class Run extends Activity {
/** The OpenGL view */
private GLSurfaceView glSurfaceView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Initiate the Open GL view and
// create an instance with this activity
glSurfaceView = new GLSurfaceView(this);
// set our renderer to be the main renderer with
// the current activity context
glSurfaceView.setRenderer(new GlRenderer());
setContentView(glSurfaceView);
}

35
36
37
38
39
40
41
42
43
44
45
46
47
48

/** Remember to resume the glSurface */


@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
/** Also pause the glSurface */
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
}

In line 12 we declare a GLSurfaceView member variable. This is our OpenGL view provided by
android. When we instantiate it (line 27) we have to make it context aware. That is, for the view
to have access to the application environment.
All we need to do is to add our renderer to this view. This we do in line 31.
Line 32 tells the activity to use our OpenGL view.
The onResume() and onPause() methods are being overridden and trigger the respective
methods in our view.
You can run the application as an Android app and you should see a blank black screen.
That is it. We have switched from the canvas to the OpenGL renderer.
Download the source code and eclipse project here (obviam.opengl.p01.tgz)
Reference: OpenGL ES with Android Tutorial- Switching from Canvas to OpenGL from our
JCG partner Tamas Jano from Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

14

Android Game Development Displaying


Graphical Elements (Primitives) with
OpenGL ES
Published on October 3, 2011 | 2,586 views | Filed in: Android Games

This is part 2 of the android OpenGL ES series. In the previous article we looked at how to set up
the android project to use the provided OpenGL view with our renderer. You can use the project
from that article as a template for this.
Before we start displaying things, we must know a few basic concepts of 3D programming and
also familiarise ourselves with the terminology. Is basic geometry really.
3D graphics happens in the Cartesian Coordinate System.
That means that the coordinate system used has three dimensions. X, Y and Z.
Traditionally X goes from left to right, Y from bottom to top, and Z from me into the screen so
to speak.
While we deal with objects to display (a robot for example or a car) OpenGL deals with
components of these objects. Each object is created from primitives which in the case of
OpenGL is a triangle. Every triangle has a face and a backface.
A triangle is defined by 3 points in space. A point is called a vertex (vertices plural).
The following diagram shows 2 vertices. A and B.

Vertices
I drew this diagram to show how we will differentiate between 2D and 3D. A vertex is defined by
its X, Y and Z coordinates. If we use 0 for the Z component all the time, we have 2D. You can
see vertex A is part of the plane defined by X and Y. Vertex B is farther in on the Z coordinate. If
you think of Z as a line being perpendicular to the screen, we wouldnt even see B.
A triangle is called a primitive. A primitive is the simplest type OpenGL understands and is able
to graphically represent.

It is very simple. 3 vertices define a triangle. There are other primitives as well, like quads but
well stick to the basics. Every shape can be broken down into triangles.
We mentioned the face of the triangle before.
Why is it important? In 3D you will have objects with parts facing towards you, the player and
parts facing away from you. In order to make the drawing efficient, OpenGL will not draw the
triangles facing away from you as it is not necessary because they will be hidden by the triangles
facing towards you anyway. This is called backface culling.
How does OpenGL determine this? This is determined by the order of the vertices when drawing
the triangle. If the order is counter clockwise then it is a face (green triangle). Clockwise order of
the vertices means it is a backface (the red triangle). This is the default setting but it can be
changed of course. The following diagram illustrates just that.

Backface Culling
The red triangle wont be drawn.

Creating and Drawing a Triangle


With all the theory understood, lets create a triangle and draw it.
A triangle is defined by 3 vertices. The coordinates of the vertices is not measured in pixels. We
will use float to represent the values and they will be relative to each other.
If a sides length is 1.0f and an other sides length is 0.5f, then it means that the second side is
half the length of the first sides length. How big it will be displayed depends on how the
viewport is set up. Imagine the viewport as a camera. When we use 2D then it means that the

camera is orthogonal to the screen. If the camera is very close, the triangle will appear big, if its
far, then the triangle will be small.
Lets create the Triangle class.
view source
print?
01
package net.obviam.opengl;
02
03
import java.nio.ByteBuffer;
04
import java.nio.ByteOrder;
05
import java.nio.FloatBuffer;
06
07 import javax.microedition.khronos.opengles.GL10;
08
09
public class Triangle {
10
11 private FloatBuffer vertexBuffer; // buffer holding the vertices
12
13 private float vertices[] = {
14 -0.5f, -0.5f, 0.0f, // V1 - first vertex (x,y,z)
15 0.5f, -0.5f, 0.0f, // V2 - second vertex
16 0.0f, 0.5f, 0.0f // V3 - third vertex
17
};
18
19 public Triangle() {
20 // a float has 4 bytes so we allocate for each coordinate 4 bytes
2 ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length *
1 4);
2
vertexByteBuffer.order(ByteOrder.nativeOrder());
2
23
24 // allocates the memory from the byte buffer
25 vertexBuffer = vertexByteBuffer.asFloatBuffer();
26
27 // fill the vertexBuffer with the vertices
28 vertexBuffer.put(vertices);
29
30 // set the cursor position to the beginning of the buffer
31
vertexBuffer.position(0);
32
}
33
}

Line 11 defines a FloatBuffer that will hold the vertices for our triangle. We need to use the
java.nio package as it is very intensive input output.

The vertices[] array holds the actual coordinates for the vertices.
The triangle we will draw is represented in the following diagram. We calculate everything from
the origin.

Triangle
In the constructor we initialise the triangle from this vertices[] array.
What we do is, we fill the vertexBuffer with the coordinates and set the cursors position to the
beginning of the buffer. We will be using this buffer in the OpenGL call to display triangle strips.
We currently have just one.
Lets take a look at the renderer. The GlRenderer
view source
print?
01
package net.obviam.opengl;
02
03 import javax.microedition.khronos.egl.EGLConfig;
04 import javax.microedition.khronos.opengles.GL10;
05
06
import android.opengl.GLU;
07 import android.opengl.GLSurfaceView.Renderer;
08
09 public class GlRenderer implements Renderer {
10
11 private Triangle triangle; // the triangle to be drawn
12
13
/** Constructor */
14
public GlRenderer() {

15
this.triangle = new Triangle();
16
}
17
18
@Override
19
public void onDrawFrame(GL10 gl) {
20
// clear Screen and Depth Buffer
21 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
22
23
// Reset the Modelview Matrix
24
gl.glLoadIdentity();
25
26
// Drawing
27 gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
28 // is the same as moving the camera 5 units away
29 triangle.draw(gl); // Draw the triangle
30
31
}
32
33 @Override
34 public void onSurfaceChanged(GL10 gl, int width, int height) {
35 if(height == 0) { //Prevent A Divide By Zero By
36 height = 1; //Making Height Equal One
37
}
38
39 gl.glViewport(0, 0, width, height); //Reset The Current Viewport
40 gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
41 gl.glLoadIdentity(); //Reset The Projection Matrix
42
43 //Calculate The Aspect Ratio Of The Window
44 GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
45
46 gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
47 gl.glLoadIdentity(); //Reset The Modelview Matrix
48 }
49
50
@Override
51 public void onSurfaceCreated(GL10 gl, EGLConfig config) {
52 }
53
}

We create the triangle in the constructor.


The onDrawFrame(GL10 gl) is of the most interest for us.
OpenGL works with state variables. Every method we call on the OpenGL context changes its
internal state.

Following the onDrawFrame method we see that every time a frame is drawn, the buffers get
cleared, the ModelView matrix is reloaded (dont worry if you dont understand this at the
moment), the camera is moved away 5 units (were dealing with units here, not pixels) and the
triangles draw() method is called.
The onSurfaceChanged on the other hand, transitions the OpenGL context between a few states.
First it sets the viewport to the current width and height of the surface (so it works with the
GL_PROJECTION state), then it transitions the state to the GL_MODELVIEW so we can work
with our models the triangle in our case. It will make sense later on, dont worry.
Lets check out the draw method for the triangle:
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15

public void draw(GL10 gl) {


gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// set the colour for the triangle
gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}

Because we store the triangles vertices coordinates in a FloatBuffer we need to enable OpenGL
to read from it and understand that is a triangle there. Line 02 does just that.
Line 05 sets the colour for the entity (triangle in our case) that will be drawn. Note that the
values of the rgb are floats and are between 0.0 and 1.0.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); will tell OpenGL to use the
vertexBuffer to extract the vertices from.
The first parameter (value = 3) represents the number of vertices in the buffer. The second lets
OpenGL know what type the data the buffer holds.
The third parameter is the offset in the array used for the vertices. Because we dont store extra
data, our vertices follow each other and there is no offset.

Finally the last parameter is our buffer containing the vertices.


gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3); tells OpenGL to
draw triangle strips found in the buffer provided earlier, starting with the first element. It also lets
it know how many vertices there are.
That is it. Run the project and you should be able to see your first accelerated triangle. Just like
this:

Download the source here (obviam.opengl.p02.tgz):


I was inspired by code from the nehe android ports. To learn the guts of OpenGL I warmly
recommend the nehe tutorials.
Next we will see how we can create basic 3D objects and rotate them. We will also find out how
we can use textures on elements.
Reference: OpenGL ES Android Displaying Graphical Elements (Primitives) from our JCG
partner Tamas Jano from Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

15

Android Game Development OpenGL


Texture Mapping
Published on October 6, 2011 | 17,582 views | Filed in: Android Games

In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on
android. Now lets take it further and build on them. In this article we will create a billboard
(which is a square) and we will apply a texture onto it. A texture is nothing more than a bitmap
image. When we work in 2D we set the Z coordinate to 0. Well cover 3D later. This is very
useful to use in 2D games and is the preferred way to display images using OpenGL. It is very
fast indeed.
In the previous articles we managed to display triangles. How to display a square then? A square
is composed of 2 triangles.
The following diagram shows you this:

Square from Triangles


There is an interesting thing to note here. The square is ABDC instead of the usual ABCD. Why
is that? Because of how OpenGL chains triangles together.
What you see here is a triangle strip. A triangle strip is a series of connected triangles, 2 triangles
in our case.
OpenGL draws the following triangle strip (which is a square) using the vertices in the following
order:
Triangle 1: V1 -> V2 -> V3
Triangle 2: V3 -> V2 -> V4

Triangle Strip
It draws the first triangle using the vertices in order, then it takes the last vertex from the
previous triangle and uses the last side of the triangle as the basis for the new triangle.
This also has benefits: we eliminate redundant data from the memory.
Grab the project from the previous article and create a new class called Square.
If you compare the Square class with the Triangle class, you will notice just one difference:
view source
print?
01
package net.obviam.opengl;
02
03
import java.nio.ByteBuffer;
04
import java.nio.ByteOrder;
05
import java.nio.FloatBuffer;
06
07 import javax.microedition.khronos.opengles.GL10;
08
09
public class Square {
10
11 private FloatBuffer vertexBuffer; // buffer holding the vertices
12
13 private float vertices[] = {
14 -1.0f, -1.0f, 0.0f, // V1 - bottom left
15 -1.0f, 1.0f, 0.0f, // V2 - top left
16 1.0f, -1.0f, 0.0f, // V3 - bottom right
17
1.0f, 1.0f, 0.0f // V4 - top right
18
};

19
20
public Square() {
2
// a float has 4 bytes so we allocate for each coordinate 4 bytes
1
2 ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length *
2 4);
23 vertexByteBuffer.order(ByteOrder.nativeOrder());
24
25 // allocates the memory from the byte buffer
26 vertexBuffer = vertexByteBuffer.asFloatBuffer();
27
28 // fill the vertexBuffer with the vertices
29
vertexBuffer.put(vertices);
30
31 // set the cursor position to the beginning of the buffer
32 vertexBuffer.position(0);
33
}
34
35 /** The draw method for the square with the GL context */
36 public void draw(GL10 gl) {
37 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
38
39 // set the colour for the square
40 gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
41
42
// Point to our vertex buffer
43 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
44
45 // Draw the vertices as triangle strip
46 gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
47
48 //Disable the client state before leaving
49 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
50 }
51
}

The difference is in the highlighted lines (13-18). Thats right, weve added one more vertex to
the vertices array.
Now change the GlRenderer so instead of a Triangle we use a Square.
view source
print?
01
package net.obviam.opengl;
02
03 import javax.microedition.khronos.egl.EGLConfig;

04 import javax.microedition.khronos.opengles.GL10;
05
06
import android.opengl.GLU;
07 import android.opengl.GLSurfaceView.Renderer;
08
09 public class GlRenderer implements Renderer {
10
11
private Square square; // the square
12
13 /** Constructor to set the handed over context */
14 public GlRenderer() {
15
this.square = new Square();
16
}
17
18
@Override
19
public void onDrawFrame(GL10 gl) {
20
// clear Screen and Depth Buffer
21 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
22
23
// Reset the Modelview Matrix
24
gl.glLoadIdentity();
25
26
// Drawing
27 gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
28 // is the same as moving the camera 5 units away
29 square.draw(gl); // Draw the triangle
30
31
}
32
33 @Override
34 public void onSurfaceChanged(GL10 gl, int width, int height) {
35 if(height == 0) { //Prevent A Divide By Zero By
36 height = 1; //Making Height Equal One
37
}
38
39 gl.glViewport(0, 0, width, height); //Reset The Current Viewport
40 gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
41 gl.glLoadIdentity(); //Reset The Projection Matrix
42
43 //Calculate The Aspect Ratio Of The Window
44 GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
45
46 gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
47 gl.glLoadIdentity(); //Reset The Modelview Matrix
48 }
49
50
@Override

51 public void onSurfaceCreated(GL10 gl, EGLConfig config) {


52 }
53
}

Running this will produce the following result:

Triangle Strip forming a Square


Examining this, the draw() method in the Square class should make sense now.
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15

public void draw(GL10 gl) {


gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// set the colour for the square
gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}

First we enable OpenGL to use a vertex array for rendering. Our vertex array contains the
vertices for our square.
gl.glVertexPointer (line 5) tells the opengl renderer from where to take the vertices and of what
type they are.
The first parameter tells how many coordinates are used for a vertex. We use 3 (x,y,z). The
second parameter tells that the values are of type float.
The 3rd parameter is the offset between the vertices in the array. It is called the strife. We have a
tightly packed array so it is 0.
Finally the last parameter tells where the vertices are held. Of course it is our buffer
vertexBuffer.
gl.glDrawArrays in line 11 tells OpenGL to draw the primitive. What kind of primitive? The
one specified in the first parameter: GL10.GL_TRIANGLE_STRIP. It takes the vertices from
the previously set vertex buffer and it follows the rules of the triangle strips described earlier.
The second parameter specifies the starting index for the vertices in the array.
The 3rd parameter tells OpenGL, how many vertices to use for the polygon, about to be
rendered. Because in the previous statement (gl.glVertexPointer) we specified that 3 coordinates
define a vertex, we will provide the length of our vertex array divided by 3. There are 9 elements
in the array defining 3 vertices.
glDisableClientState(GL10.GL_VERTEX_ARRAY) disables the state of rendering from an
array containing the vertices.
Think of glEnableClientState and glDisableClientState as begin end statements in a
program. We basically enter subroutines in the OpenGL renderer. Once we entered a routine, we
set up variables (the vertex buffer, the colour, etc) and we execute other subroutines (draw
vertices). After were done, we exit the subroutine. We work in isolation inside the renderer.
Make sure you run the application at this stage and understand what is going on.

Creating the Texture


Now the fun part. Lets load up an image and create a texture. A texture IS an image.
To find out how you can load up images in your android app, check out this article.
We will be working with the Square class as we want to apply the texture to the square.
We need to load up the image, tell the opengl renderer that we want to use it as a texture, and
finally we will tell the renderer where exactly onto our primitive (square) to display it.

Think of it as if you were putting a foil onto a window or a wall. I provide you with a foil
containing an image of the size of the window and tell you to cover the window with it, so the
top left corner of the foil will be on the top left corner of the window. That is it, lets get to work.
OpenGL uses the vertices to work out where to put stuff. So we need to create an array for the
image. But this time, this will be 2D as a bitmap is like a sheet of paper, a flat plane.
Add the coordinate array for the texture.
view source
print?
1 private FloatBuffer textureBuffer; // buffer holding the texture coordinates
2 private float texture[] = {
3 // Mapping coordinates for the vertices
4 0.0f, 1.0f, // top left (V2)
5 0.0f, 0.0f, // bottom left (V1)
6 1.0f, 1.0f, // top right (V4)
7 1.0f, 0.0f // bottom right (V3)
8 };

We need to create the textureBuffer in a similar way to the vertexBuffer. This happens in the
constructor and well just reuse the byteBuffer. Check the new constructor:
view source
print?
01 public Square() {
02 ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
03 byteBuffer.order(ByteOrder.nativeOrder());
04 vertexBuffer = byteBuffer.asFloatBuffer();
05
vertexBuffer.put(vertices);
06
vertexBuffer.position(0);
07
08 byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
09 byteBuffer.order(ByteOrder.nativeOrder());
10 textureBuffer = byteBuffer.asFloatBuffer();
11
textureBuffer.put(texture);
12
textureBuffer.position(0);
13
}

We will add an important method to the Square class. The loadGLTexture method. This will be
called from the renderer when it starts up. It happens in the onSurfaceCreated method. This will
load up the image from the disk and bind it to a texture in the OpenGL repository. It will
basically assign an internal ID for the processed image and will be used by the OpenGL API to
identify it among other textures.

view source
print?
01
/** The texture pointer */
02
private int[] textures = new int[1];
03
04 public void loadGLTexture(GL10 gl, Context context) {
05 // loading texture
06 Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
07
R.drawable.android);
08
09
// generate one texture pointer
10
gl.glGenTextures(1, textures, 0);
11 // ...and bind it to our array
12 gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
13
14
// create nearest filtered texture
1 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
5 GL10.GL_NEAREST);
1 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
6 GL10.GL_LINEAR);
1
7
1 // Use Android GLUtils to specify a two-dimensional texture image from our
8 bitmap
19 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
20
21
// Clean up
22
bitmap.recycle();
23
}

We need a texture pointer array. This is where OpenGL will store the names of the textures we
will use in our application. Because we have just one image, we will create an array of size 1.
Line 06 loads the android bitmap which was previously copied into the /res/drawable-mdpi
directory, so the ID is already generated.
A note about this bitmap. It is encouraged to be square. It helps a lot with scaling. So make sure
your bitmaps for textures are squares (66, 1212, 128128, etc.). If not square, make sure the
width and height are powers of 2 (2, 4, 8, 16, 32, ). You can have a bitmap 128512 and it is
perfectly usable and it is optimised.
Line 10 generates the names for the textures. In our case generates one name and stores it in the
textures array. Even if it says name, it actually generates an int. A bit confusing, but it is how it
is.

Line 12 binds the texture with the newly generated name (texture[0]). What this means is, that
anything using textures in this subroutine, will use the bound texture. It practically activates the
texture. A bound texture is the active texture. If we would have had multiple textures and
multiple squares to use them, we would have had to bind (activate) the appropriate textures for
each square just before they were used to activate them.
Lines 15 and 16 set some filters to be used with for texture. We have just told OpenGL what
types of filters to use when it needs to shrink or expand the texture to cover the square. We have
chosen some basic algorithms on how to scale the image. Dont have to worry about this now.
In line 19 we use Androids utilities to specify the 2D texture image for our bitmap. It creates the
image (texture) internally in its native format based on our bitmap.
in line 22 we free up the memory. This you should not forget as memory on a device is very
limited and images are big.
Now lets see how the draw() method has been modified.
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23

public void draw(GL10 gl) {


// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}

Its not a huge modification from the previous article. The additions are documented and do the
following:

Line 03 binds (activates) the texture with the name (integer ID) stored in textures[0].
Line 07 enables the texture mapping in the current OpenGL context.
Line 14 provides the OpenGL context with the texture coordinates.
After drawing the primitive with textures, we switch off the texture mapping along with the
primitive rendering.
Important UV Mapping
If you look carefully, the vertex order in the texture mapping coordinates array doesnt follow the
order present in the squares vertex coordinates array.
There is a very good explanation of texture mapping coordinates here:
http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-part-6_25.html.
I will try to explain it quickly though. Examine the following diagram.

Square and Texture Coordinates Ordering


The square is composed of 2 triangles and the vertices are in the following order.
1 bottom left
2 bottom right
3 top left
4 top right
Notice the counter clockwise path.
The texture coordinates will be in the order: 1 -> 3 -> 2 -> 4
Just bear this mapping in mind and rotate it if you start your shape from a different corner. To
read up on UV mapping check the wikipedia entry or search the net for it.

For the final part, to make this work, we need to provide the context to our renderer so we can
load up the texture at startup.
The onSurfaceCreated method will look like this.
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14

public void onSurfaceCreated(GL10 gl, EGLConfig config) {


// Load the texture for the square
square.loadGLTexture(gl, this.context);
gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping ( NEW )
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}

Line 03 loads the texture. The rest of the lines just configure the renderer with some values. You
dont have to worry about them now.
You will need to provide the application context to the Square object, because the object itself
loads the texture and needs to know the path to the bitmap.
Just provide the context to the renderer in the Run activitys onCreate method
(glSurfaceView.setRenderer(new GlRenderer(this));) and its done.
Make sure the renderer has the context declared and set via the constructor.
Excerpt from the GlRendered class.
view source
print?
01
private Square square; // the square
02
private Context context;
03
04 /** Constructor to set the handed over context */
05
public GlRenderer(Context context) {
06
this.context = context;
07

08
09
10

// initialise the square


this.square = new Square();
}

If you run the code you should see the square with a nice android laid on top of it.

Square with Android Texture


Download the source code and project here (obviam.opengl.p03.tgz).
Reference: Texture Mapping OpenGL Android (Displaying Images using OpenGL and
Squares) from our JCG partner Tamas Jano from Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

16

Android Game Development Design Ingame Entities The State Pattern


Published on October 7, 2011 | 2,739 views | Filed in: Android Games

In this part I will try to explain how to design easily extensible and maintainable game elements
that control their own internal state and behaviours.
An internal state is best described as being the soul and mind of the entity. In the first part I
described why composition is better than inheritance. In a nutshell composition provides the

means to interchange the algorithms associated with their behaviours. State on the other hand
helps objects to control their own behaviors.
If you are not familiar with the behaviors and strategies, I strongly suggest to go and check out
the previous article as I will be picking up those droids and make them utterly clever during the
next articles. But first we need to take a closer look to how I design less clever entities, like
weapons.
Lets design an old fashioned rifle and learn from the process how to design the next gen
weapons to fend off the invading droid army.
Breaking it down, what can one do with a rifle? Pull the trigger of course and reload (insert, eject
the ammo clip).
Now think of all the scenarios. What happens if I pull the trigger and there is no clip? Or when
there is one but its empty? Apparently a simple thing became a bit more complicated. Lets see it
on paper:

Initial Rifle State Diagram


Lets examine the diagram and figure out what it is and what is that we want.
The above diagram is called a State Diagram.
Each of those circles is a State and each of those arrows is a State Transition.
Each state is just a different configuration of the rifle. The rifle behaves in certain ways
depending in which state it is in and some action is needed to take it to another state. So, to go to
another state, you will need to do something like pull the trigger or insert clip. See the arrows on
the diagram.
We identify the following states:

No Clip

Has Clip

Ammo fired

Out of Ammo

and actions (transitions):

inserts clip

ejects clip

pulls trigger

fire ammo

Note: I used third person for 3 of the actions. It is because the user of the weapon will trigger
these actions while fire ammo is more of an internal action.
The whole thing described above is also called a Finite State Machine. It is nothing more than
an object that holds a finite number of states that govern behaviour and the object can be in only
one state at any given time.

Our First Implementation


Knowing all this, what would be our first choice for the implementation? A class that has all the
possible states and actions, right? It should also hold the current state. Simple.
Create the Rifle.java class.
view source
print?
01
public class Rifle {
02
03
// defining the states
04
final static int NO_CLIP = 0;
05
final static int HAS_CLIP = 1;
06
final static int AMMO_FIRED = 2;
07
final static int OUT_OF_AMMO = 3;
08
09 int state = NO_CLIP; // instance variable holding the current state
10 int ammoCount = 0; // we count the ammo

11

Great! We created the structure of the rifle. We also want to know when we are out of ammo, so
we added the ammoCount variable. They are set to default values. The rifle holds no clip thus
the ammo is 0 when it is created.
Now lets add the actions. But beware! Exposing all the actions to someone handling the weapon
is dangerous. What will happen when someone tries to pull out the clip while firing? We need to
take these into consideration when triggering the actions.
view source
print?
01
// **********************
02
// Creating the actions
03
// **********************
04
05 public void insertClip() {
06 // We check each possible state and act according to them
07 if (state == HAS_CLIP) {
08 System.out.println("There is already a clip loaded.");
09 } else if (state == AMMO_FIRED) {
10 System.out.println("You'll hurt yourself!!!");
11 } else if (state == OUT_OF_AMMO) {
12 System.out.println("You need to take out the empty clip first.");
13
} else if (state == NO_CLIP) {
14
state = HAS_CLIP;
1
ammoCount = 10;
5
1 System.out.println("You have loaded a clip with " + ammoCount + "
6 bulletts.");
17
}
18
}
19
20
public void ejectClip() {
21 if (state == NO_CLIP) {
22 System.out.println("The magazine is empty.");
23 } else if (state == AMMO_FIRED) {
24 System.out.println("You'll hurt yourself!!!");
25 } else if (state == HAS_CLIP) {
26 // You could still eject it if you want but for the sake of
27 // simplicity let's use up the ammo first
28 System.out.println("Use up all your ammo first.");
29
} else if (state == OUT_OF_AMMO) {
30
state = NO_CLIP;
31 System.out.println("You have unloaded a clip.");
32 }
33
}

34
35
public void pullTrigger() {
36
if (state == NO_CLIP) {
37
System.out.println("Empty Click!");
38
} else if (state == AMMO_FIRED) {
39
System.out.println("Jammed!");
40
} else if (state == OUT_OF_AMMO) {
41 System.out.println("Click! Out of ammo.");
42 } else if (state == HAS_CLIP) {
43
System.out.println("BANG!!!");
44
state = AMMO_FIRED;
45
fireAmmo();
46
}
47
}
48
49
public void fireAmmo() {
50
if (state == NO_CLIP) {
51 System.out.println("Empty magazine.");
52 } else if (state == AMMO_FIRED) {
53 System.out.println("Bullet already on its way to kill someone!");
54 } else if (state == OUT_OF_AMMO) {
55
System.out.println("Out of ammo.");
56
} else if (state == HAS_CLIP) {
57
state = AMMO_FIRED;
58
ammoCount--;
59 System.out.println("Bullet on its way!");
60 // we check if the clip is empty
61
if (ammoCount == 0) {
62
// yes, it's empty
63 System.out.println("Darn! Out of ammo");
64 state = OUT_OF_AMMO;
65
} else {
66
state = HAS_CLIP;
67
}
68
}
69
}

Lets put the rifle to the test.


Create the RifleTest.java class.
view source
print?
01
02
03
04

public class RifleTest {


public static void main(String[] args) {
Rifle rifle = new Rifle();

05
06
07
08
09
10
11
12
13
14
15
16
17
18
19

System.out.println(rifle);
rifle.insertClip();
rifle.pullTrigger();
rifle.pullTrigger();
rifle.pullTrigger();
rifle.pullTrigger();
System.out.println(rifle);
rifle.insertClip();
rifle.ejectClip();
rifle.pullTrigger();
}
}

It is a very simple scripted scenario which performs some actions on the rifle. Some may be good
some bad. As when trying to force in a second clip or pulling the trigger when its out of ammo.
Check out the result and examine it carefully. How cool is that? We are the Kalashnikovs of our
age.
view source
print?
01 << RIFLE [state=Empty Magazine (No Clip), ammo=0] >>
02 > You have loaded a clip with 3 bullets.
03
> BANG!!!
04
> Bullet on its way!
05
> BANG!!!
06
> Bullet on its way!
07
> BANG!!!
08
> Bullet on its way!
09
> Darn! Out of ammo
10
!* Click! Out of ammo.
11 << RIFLE [state=Out of Ammo, ammo=0] >&g;t
12 !* You need to take out the empty clip first.
13
> You have unloaded a clip.
14
!* Empty Click! No clip!

Note that I have omitted the toString() method for the Rifle.
Well done! We have our first state machine.

But

We cant do much firing bullet by bullet. We need automatic fire! Oh, and we cant just let
people running around with rifles without the safety ON.
Ah, thats easy, right? Well have a few more states and a few more transitions.
But wait, we will need to rework the Rifle class a bit.
Lets see what we need to modify just to support automatic and manual fire:

we need to add the two states

but then we need to modify every single method to handle the states by adding
conditional statements

pullTrigger() will get complicated as it will need to know what state it is in and check
bullets and fire them as such

That is a LOT of work. It must be some other way.

The Solution
What if we give each state a behaviour and put it into its own class? This way each state will
implement its own actions only. We will have the rifle class delegating the action to the state
object that represents the current state.
Lets see how does it look?

Final Rifle State Diagram


What you should notice is that the Has Clip is now Manual/Auto and has a switch transition. It
basically has a sub-state now. Flipping the switch changes the behaviour. Both states will have

the pull trigger action but each state will behave differently. This is easily achieved with
interfaces, right?
Lets start coding then. First, lets create the state interface. Remember, each state will implement
its transition and will provide the dummy implementation for the rest. The interface will contain
all the actions.
The methods map directly to all the actions that can happen with the Rifle
view source
print?
1
2
3
4
5
6
7
8

public interface RifleState {


public void insertClip();
public void ejectClip();
public void swithManualAuto();
public void pullTrigger();
public void fireAmmo();
}

The new Rifle class will have none of the implemented actions, but will have all the states and
will delegate the actions to its current state.
Rifle.java
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17

public class Rifle {


// the states of the rifle
RifleState emptyState;
RifleState autoFireState;
RifleState manualFireState;
RifleState outOfAmmoState;
RifleState roundFiredState;
RifleState ammoFiredState;
RifleState state = emptyState;
int ammoCount = 0;
// constructor
public Rifle() {
// creating states
this.emptyState = new NoClipState(this);

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

this.autoFireState = new AutoFireState(this);


this.manualFireState = new ManualFireState(this);
this.outOfAmmoState = new OutOfAmmoState(this);
this.roundFiredState = new RoundFiredState(this);
this.ammoFiredState = new AmmoFiredState(this);
this.state = this.emptyState;
this.ammoCount = 0;
}
// convenience methods - delegating only
public void insertClip() {
this.state.insertClip();
}
public void ejectClip() {
this.state.ejectClip();
}
public void switchManualAuto() {
this.state.switchManualAuto();
}
public void pullTrigger() {
this.state.pullTrigger();
}
// getters and setters
// ... omitted
}

You see that the class has changed a bit. It has all the states and a current state. It has a
constructor too. The constructor is needed to set up the rifle and pass itself as a reference to all of
the states to give them access to the rifles properties. In our case just the ammo count and
current state need to be accessed.
Also the fireAmmo() is missing as it is a state internal action.
Now lets map the states to actual classes. These are the same as in the original rifle class.
I will list one full class and for the rest only the methods that change the state. Examine the
source code for the complete listings.
OutOfAmmoState.java
view source
print?
01 public class OutOfAmmoState implements RifleState {
02
03
private Rifle rifle;

04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

public OutOfAmmoState(Rifle rifle) {


this.rifle = rifle;
}
@Override
public void ejectClip() {
rifle.setState(rifle.getEmptyState());
System.out.println("> Clip ejected.");
}
@Override
public void fireAmmo() {
System.out.println("!* You can't fire with no ammo.");
}
@Override
public void insertClip() {
System.out.println("!* There is an empty clip inserted already!");
}
@Override
public void pullTrigger() {
System.out.println("!* Out of ammo!");
}
@Override
public void switchManualAuto() {
System.out.println("!* Plesea reload first");
}
}

Notice that the only way out of the OutOfAmmoState is by ejecting the clip.
Every other attempt will do nothing.
Also note the constructor. We are passing the reference to the rifle there.
Check out the other classes too:
AmmoFiredState
view source
print?
01 public class AmmoFiredState implements RifleState {
02
03
private Rifle rifle;

04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19

public AmmoFiredState(Rifle rifle) {


this.rifle = rifle;
}
@Override
public void fireAmmo() {
rifle.setAmmoCount(rifle.getAmmoCount() - 1);
System.out.println("> Fired 1 bullet.");
if (rifle.getAmmoCount() == 0) {
rifle.setState(rifle.getOutOfAmmoState());
} else {
rifle.setState(rifle.getManualFireState());
}
}
// ... ommited
}

AutoFireState
view source
print?
01 public class AutoFireState implements RifleState {
02
03
private Rifle rifle;
04
public AutoFireState(Rifle rifle) {
05
this.rifle = rifle;
06
}
07
08
@Override
09
public void ejectClip() {
10
rifle.setAmmoCount(0);
11 rifle.setState(rifle.getEmptyState());
12 System.out.println("> Clip ejected. Please reload.");
13
}
14
15
@Override
16
public void pullTrigger() {
17 System.out.println("> Pulled trigger.");
18 rifle.setState(rifle.getRoundFiredState());
19
rifle.getState().fireAmmo();
20
}
21
22
@Override
23 public void switchManualAuto() {
24 rifle.setState(rifle.getManualFireState());
25 System.out.println("> Switched to manual. Hope they are slow and few!");
26 }

27
28

// ... ommited
}

If you follow the diagram then you should be able to figure out the transitions. There is a trick
there as the Manual and Auto modes are very similar and I just transition between them. There is
a drawback as after a reload, the manual state is the active one even if the auto was set before.
But Im sure you can figure out a quick fix.
ManualFireState
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

public class ManualFireState implements RifleState {


private Rifle rifle;
public ManualFireState(Rifle rifle) {
this.rifle = rifle;
}
@Override
public void ejectClip() {
rifle.setAmmoCount(0);
rifle.setState(rifle.getEmptyState());
System.out.println("> Clip ejected. Please reload.");
}
@Override
public void pullTrigger() {
System.out.println("> Pulled trigger.");
rifle.setState(rifle.getAmmoFiredState());
rifle.getState().fireAmmo();
}
@Override
public void switchManualAuto() {
rifle.setState(rifle.getAutoFireState());
System.out.println("> Switched to auto. Bring'em on!!!");
}
// ... ommited

NoClipState
view source

print?
01 public class NoClipState implements RifleState {
02
03
private Rifle rifle;
04
public NoClipState(Rifle rifle) {
05
this.rifle = rifle;
06
}
07
08
@Override
09
public void insertClip() {
10
rifle.ammoCount = 50;
11 rifle.setState(rifle.getManualFireState());
12 }
13
14
// ...ommited
15
}

RoundFiredState
view source
print?
01 public class RoundFiredState implements RifleState {
02
03
private Rifle rifle;
04
public RoundFiredState(Rifle rifle) {
05
this.rifle = rifle;
06
}
07
08
@Override
09
public void fireAmmo() {
10
int count = 10;
11 while (count > 0 && rifle.getAmmoCount() > 0) {
12 System.out.print("> BANG! ");
13 rifle.setAmmoCount(rifle.getAmmoCount() - 1);
14 count--;
15
}
16
System.out.println();
1 System.out.println("> Fired a round of " + (10 - count) + " bullets.
7 Yeah!");
1
if (rifle.getAmmoCount() <= 0) {
8
19 rifle.setAmmoCount(0);
20 rifle.setState(rifle.getOutOfAmmoState());
21 } else {
22 rifle.setState(rifle.getAutoFireState());
23
}

24
25
26

}
// ...ommited
}

Great! Lets throw together a test for the new shiny Rifle.
RifleTest
view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22

public class RifleTest {


public static void main(String[] args) {
Rifle rifle = new Rifle();
rifle.pullTrigger();
rifle.ejectClip();
rifle.insertClip();
rifle.pullTrigger();
rifle.switchManualAuto();
rifle.pullTrigger();
rifle.pullTrigger();
rifle.switchManualAuto();
rifle.pullTrigger();
rifle.insertClip();
rifle.switchManualAuto();
rifle.pullTrigger();
rifle.pullTrigger();
rifle.pullTrigger();
rifle.pullTrigger();
rifle.pullTrigger();
}

Examine the output very carefully and go through the source code. You should try adding new
features or think of other scenarios.
view source
print?
01
02
03
04
05
06
07 >

!* You cant fire with an empty magazine.


!* The magazine is empty.
> Pulled trigger.
> Fired 1 bullet.
> Switched to auto. Bringem on!!!
> Pulled trigger.
BANG! >BANG! >BANG! >BANG! >BANG! >BANG! >BANG! > BANG! >BANG! >BANG!

08 > Fired a round of 10 bullets. Yeah!


09 > Pulled trigger.
10 >BANG! >BANG! >BANG! >BANG! >BANG! >BANG! >BANG! > BANG! >BANG! >BANG!
11 > Fired a round of 10 bullets. Yeah!
12 > Switched to manual. Hope they are slow and few!
13
> Pulled trigger.
14
> Fired 1 bullet.
15
!* Clip is already present!
16
> Switched to auto. Bringem on!!!
17 > Pulled trigger.
18 > BANG! >BANG! >BANG! >BANG! >BANG! >BANG! >BANG! > BANG! >BANG! >BANG!
19
> Fired a round of 10 bullets. Yeah!
20
> Pulled trigger.
21 > BANG! >BANG! >BANG! >BANG! >BANG! >BANG! >BANG! > BANG! >BANG! >BANG!
22 > Fired a round of 10 bullets. Yeah!
23 > Pulled trigger.
24 > BANG! >BANG! >BANG! >BANG! >BANG! >BANG! >BANG! >BANG!
25
> Fired a round of 8 bullets. Yeah!
26
!* Out of ammo!
27
!* Out of ammo!

Again, the yellow lines show you when you tried something dodgy.
Voila! We have state machines and easily extensible game elements.
I strongly encourage you to extend it and build your own, as it is a very important element of
game design.
You can apply this principle for the whole game and infrastructure. Think of the game as a whole
and when youre on the menu screen (thats the Menu State), when youre in the paused screen,
thats the Pause State, or the main screen thats the Running State. You could create a framework
and easily add different game states.
I do hope this gave you a good introduction on how to implement state driven behaviours. Note
that I used normal Java practices to write the code for clarity. Meaning that when writing a game,
especially for Android, you might not need to overload your classes with getters and setters and
you should adhere to the optimized ways. You could use public attributes and access them
directly for example. But it was not the scope of this article.
Also understanding this is crucial to make a step towards autonomous agents (automatons). Next
time I will introduce event and/or message driven behaviours. We will return to our beloved
droids to give them wits to outrun you.
Download the source code and project here (obviam.states.tgz).
Note that the first attempt was renamed to RifleOld.java and RifleOldTest.java

Reference: Design In-game Entities. Object Composition Strategies. Part 2 The State Pattern
from our JCG partner Tamas Jano from Against The Grain blog.
Do not forget to check out our new Android Game ArkDroid (screenshots below). You feedback
will be more than helpful!

17

Building Games Using the MVC Pattern


Tutorial and Introduction
Published on February 14, 2012 | 7,062 views | Filed in: Desktop Java Tags: Game Design

One useful architecture pattern in game development is the MVC (model-view-controller)


pattern.
It helps separate the input logic, the game logic and the UI (rendering). The usefulness is quickly
noticeable in the early stages of any game development project because it allows to change
things quickly without too much rework of code in all layers of the application.
The following diagram is the simplest logical representation of the model view controller
concept.

Model-View-Controller pattern
Example Usage
In an example game where the player controls a robot the following can happen:

1 User clicks/taps somewhere on the screen.

2 The controller handles the click/tap and converts the event into an appropriate action.
For example if the terrain is occupied by an enemy, an attack action is created, if it is

empty terrain, then a move action is created and finally if the place where the user tapped
is occupied by an obstacle, do nothing.

3 The controller updates the robots (models) state accordingly. If the move action
was created, then it changes the position, if the attack, then it fires.

4 The renderer (view) gets notified about the state changes and renders the worlds
current state.

What this all means is, that the models (robots) dont know anything about how to draw
themselves, or how to change their state (position, hit points). They are dumb entities. In Java
they are also called POJOs (plain old java objects).
The controller is in charge of changing the models state and notify the renderer.
The renderer has to have a reference to the models (robots and any other entities) and their state,
in order to draw them.
We know from the typical game architecture that the main loop acts as a super controller, which
updates the states and then renders the objects onto the screen many times a second. We can put
all the update and rendering into the main loop along with the robots but that would be messy.
Lets identify the different aspects (concerns) of our games.
The models

The droid controlled by the player

An arena where the droid can move

Some obstacles

Some enemies to shoot at

The controllers

The main loop and the input handler

Controller to process player input

Controller to perform actions on the players robot (move, attack)

The views

The world renderer to render the objects onto the screen

Creating the Project

For simplicity I have chosen the applet this time and will try to keep it very brief. The project has
the following structure:

MVC Project structure


The file Droids.java is the applet and contains the main loop.
view source
print?
01
package net.obviam.droids;
02
03
import java.applet.Applet;
04
import java.awt.Color;
05
import java.awt.Event;
06
import java.awt.Graphics;
07
import java.awt.image.BufferedImage;
08
09 public class Droids extends Applet implements Runnable {
10
11 private static final long serialVersionUID = -2472397668493332423L;
12
13
public void start() {
14
new Thread(this).start();
15
}
16
17
public void run() {
18
19 setSize(480, 320); // For AppletViewer, remove later.
20
2
// Set up the graphics stuff, double-buffering.
1
2 BufferedImage screen = new BufferedImage(480, 320,
2 BufferedImage.TYPE_INT_RGB);
23 Graphics g = screen.getGraphics();
24 Graphics appletGraphics = getGraphics();
25
26
long delta = 0l;

27
28
// Game loop.
29
while (true) {
30
long lastTime = System.nanoTime();
31
32
g.setColor(Color.black);
33
g.fillRect(0, 0, 480, 320);
34
35 // Draw the entire results on the screen.
36 appletGraphics.drawImage(screen, 0, 0, null);
37
38
// Lock the frame rate
39 delta = System.nanoTime() - lastTime;
40 if (delta < 20000000L) {
41 try {
42 Thread.sleep((20000000L - delta) / 1000000L);
43 } catch (Exception e) {
44 // It's an interrupted exception, and nobody cares
45
}
46
}
47
if (!isActive()) {
48
return;
49
}
50
}
51
}
52
53
public boolean handleEvent(Event e) {
54
return false;
55
}
56
}

Running the above code as an applet does nothing more than to sett up the main loop and to paint
the screen black.
There are 3 packages in the structure and the respective components will go there.
net.obviam.droids.model will contain all the models
net.obviam.droids.view will contain all the renderers
net.obviam.droids.controller will contain all the controllers
Creating the models
The Droid

Droid.java

view source
print?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

package net.obviam.droids.model;
public class Droid {
private float x;
private float y;
private float speed = 2f;
private float rotation = 0f;
private float damage = 2f;
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public float getSpeed() {
return speed;
}
public void setSpeed(float speed) {
this.speed = speed;
}
public float getRotation() {
return rotation;
}
public void setRotation(float rotation) {
this.rotation = rotation;
}
public float getDamage() {
return damage;
}
public void setDamage(float damage) {
this.damage = damage;
}
}

It is a simple java object without any knowledge of the surrounding world. It has a position,
rotation, speed and damage. These states are defined by the member variables and are accessible
through the getter and setter methods.
The game requires a few more models: obstacles and enemies on a map. For simplicity the
obstacles will have just a position on the map and the enemies will be standing objects. The map
will be a 2 dimensional array holding the enemies, obstacles and the droid. The map will be
called Arena to differentiate from the standard Java map and will be populated with obstacles

and enemies when it is constructed.


Obstacle.java

view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19

package net.obviam.droids.model;
public class Obstacle {
private float x;
private float y;
public Obstacle(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
}

Enemy.java

view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15

package net.obviam.droids.model;
public class Enemy {
private float x;
private float y;
private int hitpoints = 10;
public Enemy(float x, float y) {
this.x = x;
this.y = y;
}
public float getX() {
return x;

16
17
18
19
20
21
22
23
24
25
26

}
public float getY() {
return y;
}
public int getHitpoints() {
return hitpoints;
}
public void setHitpoints(int hitpoints) {
this.hitpoints = hitpoints;
}
}

Arena.java

view source
print?
01
package net.obviam.droids.model;
02
03
import java.util.ArrayList;
04
import java.util.List;
05
import java.util.Random;
06
07
public class Arena {
08
09 public static final int WIDTH = 480 / 32;
10 public static final int HEIGHT = 320 / 32;
11
12 private static Random random = new Random(System.currentTimeMillis());
13
14
private Object[][] grid;
15 private List<Obstacle> obstacles = new ArrayList<Obstacle>();
16 private List<Enemy> enemies = new ArrayList<Enemy>();
17
private Droid droid;
18
19
public Arena(Droid droid) {
20
this.droid = droid;
21
22
grid = new Object[HEIGHT][WIDTH];
23
for (int i = 0; i < WIDTH; i++) {
24
for (int j = 0; j < HEIGHT; j++) {
25
grid[j][i] = null;
26
}
27 }
28 // add 5 obstacles and 5 enemies at random positions
29
for (int i = 0; i < 5; i++) {
30
int x = random.nextInt(WIDTH);
31
int y = random.nextInt(HEIGHT);

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

while (grid[y][x] != null) {


x = random.nextInt(WIDTH);
y = random.nextInt(HEIGHT);
}
grid[y][x] = new Obstacle(x, y);
obstacles.add((Obstacle) grid[y][x]);
while (grid[y][x] != null) {
x = random.nextInt(WIDTH);
y = random.nextInt(HEIGHT);
}
grid[y][x] = new Enemy(x, y);
enemies.add((Enemy) grid[y][x]);
}
}
public List<Obstacle> getObstacles() {
return obstacles;
}
public List<Enemy> getEnemies() {
return enemies;
}
public Droid getDroid() {
return droid;
}
}

The Arena is a more complex object but reading through the code should make it easy to
understand. It basically groups all the models together into a single world. Our game world is the
arena which contains all the elements like our droid, enemies and obstacles.
The WIDTH and HEIGHT are calculated based on the resolution I have chosen. A cell (tile) on the
grid will be 32 pixels wide and tall so I just compute how many cells go onto the grid.
In the constructor (line #19) the grid is set up and 5 obstacles and 5 enemies are randomly
placed. This will make up the starting arena and our game world.
In order to keep the main loop tidy, well delegate the update and rendering to the GameEngine.
This is a simple class that will process the user input, update the states of the models and will
render the world. It is a tiny glue framework to make all these happen.
The GameEngine.java stub
view source
print?
01
02
03
04
05

package net.obviam.droids.controller;
import java.awt.Event;
import java.awt.Graphics;

06
public class GameEngine {
07
08 /** handle the Event passed from the main applet **/
09
public boolean handleEvent(Event e) {
10
switch (e.id) {
11
case Event.KEY_PRESS:
12
case Event.KEY_ACTION:
13
// key pressed
14
break;
15
case Event.KEY_RELEASE:
16
// key released
17
break;
18
case Event.MOUSE_DOWN:
19
// mouse button pressed
20
break;
21
case Event.MOUSE_UP:
22
// mouse button released
23
break;
24
case Event.MOUSE_MOVE:
25
// mouse is being moved
26
break;
27 case Event.MOUSE_DRAG:
28 // mouse is being dragged (button pressed)
29
break;
30
}
31
return false;
32
}
33
34 /** the update method with the deltaTime in seconds **/
35
public void update(float deltaTime) {
36
// empty
37
}
38
39 /** this will render the whole world **/
40 public void render(Graphics g) {
41
// empty
42
}
43
}

To use the engine the Droids.java class needs to be modified. We need to create an instance of
the GameEngine class and call the update() and render() methods at the appropriate times.
Also we need to delegate the input processing to the engine.
Add the following lines:
Declare the private member and also instantiate it.
view source

print?
1 private GameEngine engine = new GameEngine();

The modified game loop looks like this:


view source
print?
01
while (true) {
02
long lastTime = System.nanoTime();
03
04
g.setColor(Color.black);
05
g.fillRect(0, 0, 480, 320);
06
07 // Update the state (convert to seconds)
08 engine.update((float)(delta / 1000000000.0));
09
// Render the world
10
engine.render(g);
11
12 // Draw the entire results on the screen.
13 appletGraphics.drawImage(screen, 0, 0, null);
14
15 // Lock the frame rate
16 delta = System.nanoTime() - lastTime;
17
if (delta < 20000000L) {
18
try {
19 Thread.sleep((20000000L - delta) / 1000000L);
20 } catch (Exception e) {
21 // It's an interrupted exception, and nobody cares
22 }
23
}
24
}

The highlighted lines (#7-#10) contain the delegation to the update() and render() methods.
Note that there is a conversion to seconds from nano seconds. Its very useful to work in seconds
as we can work with real world values.
Important: The update needs to happen after the delta (time elapsed since the last update) has
been calculated. Also the render should be called after the update so it will display the current
state of the objects. Note that the screen is cleared each time before the render (painted black).
The last thing to be done is to delegate the input handling.
Replace the current handleEvent method with the following snippet:
view source

print?
1 public boolean handleEvent(Event e) {
2 return engine.handleEvent(e);
3
}

Very simple straightforward delegation.


Running the applet yields no particular exciting result. Just a black screen. It makes sense as
everything is just a stub apart from the screen being cleared every cycle.
Initialising the models (world)

Our game needs a droid and some enemies. By design, the world is our Arena. By instantiating
it, we have created a world (check the constructor in Arena).
We will create the world in the GameEngine as the engine is responsible for telling the view what
to render.
We also need the Droid to be created here because the Arena requires it its constructor. Is good
to have it separate as the droid will be controlled by the player.
Add the following members to the GameEngine along with the constructor which initialises the
world.
view source
print?
01
02
03
04
05
06
07
08
09
10

private Arena arena;


private Droid droid;
public GameEngine() {
droid = new Droid();
// position droid in the middle
droid.setX(Arena.WIDTH / 2);
droid.setY(Arena.HEIGHT / 2);
arena = new Arena(droid);
}

Note: Arenas constructor needs to be modified, so the Droid gets added to the grid before the
obstacles and enemies.
view source
print?
1
...
2
// add the droid
3 grid[(int)droid.getY()][(int) droid.getX()] = droid;
4 ...

Running the applet again, wont change the output but we have our world created. We can add
logging to see the result but that wont be interesting. Lets create our first view which will
reveal our world.
Creating the first View/Renderer

Weve put a lot of effort in creating the arena and world, were eager to actually see it. Because
of this, we will create a quick and dirty renderer to reveal the world. By quick and dirty I mean
no fancy images or anything but simple squares, circles and placeholders. Once we are happy
that the game elements are in we can work on a more elaborate view to replace the squares and
circles with fancy graphics. This is where the power of decoupling shines.
Steps to render the world.

Draw the grid to see where the cells are.

Obstacles will be drawn as blue squares and they will occupy the cells

Enemies will be red circles

The droid will be a green circle with a brown square

First we create the renderer interface. We use this to establish a single way to interact with the
renderer and it will make it easy to create more views without affecting the game engine. To read
more on why is a good idea check this and this.
Create an interface in the view package.
Renderer.java

view source
print?
1
2
3
4
5
6
7

package net.obviam.droids.view;
import java.awt.Graphics;
public interface Renderer {
public void render(Graphics g);
}

That is all. It contains one single method: render(Graphics g). The Graphics g is the canvas
that is passed from the applet. Ideally the interface will be agnostic of this and each
implementation will use a different back-end but the purpose of this exercise is to describe the
MVC not to create a full framework. Because we have chosen applet we need the Graphics
object.
The concrete implementation looks like this:

SimpleArenaRenderer.java

(in the view package)

view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

package net.obviam.droids.view;
import java.awt.Color;
import java.awt.Graphics;
import net.obviam.droids.model.Arena;
import net.obviam.droids.model.Droid;
import net.obviam.droids.model.Enemy;
import net.obviam.droids.model.Obstacle;
public class SimpleArenaRenderer implements Renderer {
private Arena arena;
public SimpleArenaRenderer(Arena arena) {
this.arena = arena;
}
@Override
public void render(Graphics g) {
// render the grid
int cellSize = 32; // hard coded
g.setColor(new Color(0, 0.5f, 0, 0.75f));
for (int i = 0; i <= Arena.WIDTH; i++) {
g.drawLine(i * cellSize, 0, i * cellSize, Arena.HEIGHT * cellSize);
if (i <= Arena.WIDTH)
g.drawLine(0, i * cellSize, Arena.WIDTH * cellSize, i * cellSize);
}
// render the obstacles
g.setColor(new Color(0, 0, 1f));
for (Obstacle obs : arena.getObstacles()) {
int x = (int) (obs.getX() * cellSize) + 2;
int y = (int) (obs.getY() * cellSize) + 2;
g.fillRect(x, y, cellSize - 4, cellSize - 4);
}
// render the enemies
g.setColor(new Color(1f, 0, 0));
for (Enemy enemy : arena.getEnemies()) {
int x = (int) (enemy.getX() * cellSize);
int y = (int) (enemy.getY() * cellSize);

43
44
45
46
47
48
49
50
51
52
53
54
55
56

g.fillOval(x + 2, y + 2, cellSize - 4, cellSize - 4);


}
// render player droid
g.setColor(new Color(0, 1f, 0));
Droid droid = arena.getDroid();
int x = (int) (droid.getX() * cellSize);
int y = (int) (droid.getY() * cellSize);
g.fillOval(x + 2, y + 2, cellSize - 4, cellSize - 4);
// render square on droid
g.setColor(new Color(0.7f, 0.5f, 0f));
g.fillRect(x + 10, y + 10, cellSize - 20, cellSize - 20);
}
}

Lines #13 #17 declare the Arena object and make sure that it is set when the renderer is
constructed. I called it ArenaRenderer because we will render the arena (world).
The only method in the renderer is the render() method. Lets see what it does step by step.
#22 Declare a cell size in pixels. It is 32. Its hard coded as in the Arena class.
#23 #28 The grid is being drawn. It is a simple grid. First the colour is set to dark green and
lines are drawn at equal distance.
Drawing the obstacles blue squares
#31 Set the brush color to blue.
#32 #36 Iterate through all the obstacles in the arena and for each it draws a blue filled
rectangle slightly smaller than the cell on the grid.
#39 #44 Sets the color to red and by iterating through the enemies in the arena, it draws a
circle at the respective position.
#47 #54 Finally draws the droid as a green circle with a brown square on top.
Note that the arena in the real world has a width of 15 (480 / 32). So the droid will always be at
the same position (7, 5) and the renderer works out its position on the screen by using a unit
measure conversion. In this case is 1 unit in world coordinate is 32 pixels on the screen.
By modifying the GameEngine to use the newly created view (SimpleArenaRenderer) we get
the result.
view source
print?
01
02
03
04
05

public class GameEngine {


private Arena arena;
private Droid droid;
private Renderer renderer;

06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

public GameEngine() {
droid = new Droid();
// position droid in the middle
droid.setX(Arena.WIDTH / 2);
droid.setY(Arena.HEIGHT / 2);
arena = new Arena(droid);
// setup renderer (view)
renderer = new SimpleArenaRenderer(arena);
}
/** ... code stripped ... **/
/** this will render the whole world **/
public void render(Graphics g) {
renderer.render(g);
}
}

Pay attention to the highlighted lines (5, 15, 22). These are the lines where the renderer (view) is
added to the game.
The result should look like the following image (the positions are random apart from the players
droid):

The result of the first view


This is a great view to test out the arena and see the models. Its extremely easy to create a new
view that instead of shapes (squares and circles) displays actual sprites.

Controller for Handling Input and Update Models

So far the game does nothing but displays the current state of the world (arena). For simplicity
we will update just one state of the droid, its position.
The steps to move the droid based on user input are:

On mouse up check if the clicked cell on the grid is empty. This means that it does
contain any objects which can be Enemy or Obstacle instances.

If the cell is empty, the controller will create an action that will move the droid at a
constant speed until it reaches the destination.

view source
print?
01
package net.obviam.droids.controller;
02
03
import net.obviam.droids.model.Arena;
04
import net.obviam.droids.model.Droid;
05
06
public class ArenaController {
07
08
private static final int unit = 32;
09
private Arena arena;
10
11
/** the target cell **/
12
private float targetX, targetY;
13
/** true if the droid moves **/
14
private boolean moving = false;
15
16
public ArenaController(Arena arena) {
17
this.arena = arena;
18
}
19
20
public void update(float delta) {
21
Droid droid = arena.getDroid();
22
if (moving) {
23
// move on X
24
int bearing = 1;
25
if (droid.getX() > targetX) {
26
bearing = -1;
27
}
28
if (droid.getX() != targetX) {
29 droid.setX(droid.getX() + bearing * droid.getSpeed() * delta);
30 // check if arrived
31 if ((droid.getX() < targetX && bearing == -1)

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

|| (droid.getX() > targetX && bearing == 1)) droid.setX(targetX);


}
// move on Y
bearing = 1;
if (droid.getY() > targetY) {
bearing = -1;
}
if (droid.getY() != targetY) {
droid.setY(droid.getY() + bearing * droid.getSpeed() * delta);
// check if arrived
if ((droid.getY() < targetY && bearing == -1)
|| (droid.getY() > targetY && bearing == 1)) droid.setY(targetY);
}
// check if arrived
if (droid.getX() == targetX && droid.getY() == targetY)
moving = false;
}
}
/** triggered with the coordinates every click **/
public boolean onClick(int x, int y) {
targetX = x / unit;
targetY = y / unit;
if (arena.getGrid()[(int) targetY][(int) targetX] == null) {
// start moving the droid towards the target
moving = true;
return true;
}
return false;
}
}

The following breakdown explains the logic and important bits.


#08 The unit represents how many pixels are in a cell which represents 1 unit in world
coordinates. Its hard-coded and not optimal but for the demo is good enough.
#09 The Arena the controller will control. It is set when the controller is constructed (line #16).
#12 The target coordinates of the click in world units.
#14 It is true when the droid is moving. This is the move actions state. Ideally this should
be a stand alone class, but to demonstrate the controller and keep it concise, well hack an action
together inside the controller.
#20 The update method that updates the position of the droid according to the time passed at a
constant speed. It is extremely simple, it checkes both X and Y positions and if they are not the
same as the target position, it updates the droids respective position (X or Y) considering its
speed. If the droid is in the target position, then the move state variable is updated completing the
move action.

This is not a very well written action, there is no collision checking on obstacles or enemies
found along the way, no path finding. It just updates state.
#52 The onClick(int x, int y) method will be called when the mouse up event occurs. It
checks if the clicked cell is empty and if so, then it starts the move action by setting the state
variable to true
#53-#54 Converts screen coordinates to world coordinates.
This is the controller. To use it, the GameEngine needs to be updated.
The updated GameEngine.java
view source
print?
01
package net.obviam.droids.controller;
02
03
import java.awt.Event;
04
import java.awt.Graphics;
05
06
import net.obviam.droids.model.Arena;
07 import net.obviam.droids.model.Droid;
08 import net.obviam.droids.view.Renderer;
09 import net.obviam.droids.view.SimpleArenaRenderer;
10
11
public class GameEngine {
12
13
private Arena arena;
14
private Droid droid;
15
private Renderer renderer;
16
private ArenaController controller;
17
18
public GameEngine() {
19
droid = new Droid();
20
// position droid in the middle
21
droid.setX(Arena.WIDTH / 2);
22
droid.setY(Arena.HEIGHT / 2);
23
arena = new Arena(droid);
24
25 // setup renderer (view)
26 renderer = new SimpleArenaRenderer(arena);
27 // setup controller
28 controller = new ArenaController(arena);
29
}
30
31 /** handle the Event passed from the main applet **/
32 public boolean handleEvent(Event e) {
33
switch (e.id) {

34
case Event.KEY_PRESS:
35
case Event.KEY_ACTION:
36
// key pressed
37
break;
38
case Event.KEY_RELEASE:
39
// key released
40
break;
41
case Event.MOUSE_DOWN:
42
// mouse button pressed
43
break;
44
case Event.MOUSE_UP:
45
// mouse button released
46
controller.onClick(e.x, e.y);
47
break;
48
case Event.MOUSE_MOVE:
49
// mouse is being moved
50
break;
51 case Event.MOUSE_DRAG:
52 // mouse is being dragged (button pressed)
53
break;
54
}
55
return false;
56
}
57
58 /** the update method with the deltaTime in seconds **/
59
public void update(float deltaTime) {
60
controller.update(deltaTime);
61
}
62
63 /** this will render the whole world **/
64 public void render(Graphics g) {
65
renderer.render(g);
66
}
67
}

The changes are highlighted.


#16 Declare the controller.
#28 Instantiate the controller.
#46 Delegating the mouse up event.
#60 Call the update method on the controller.
Run the applet and you can click on the map and if the cell is empty, the droid will move there.
Excercises

Create a view that will display images/sprites for entities instead of the drawn shapes.
Hint: Use BufferedImage to achieve that.

Extract the move action into a new class.

Add new actions (attack) when an enemy is clicked


Hint:Create a bullet entity that gets fired to the target. You can use the move action with a
higher speed. When the hitpoint gets down to 0, then the enemy is destroyed. Use a
different image to represent different states.

Source Code

https://github.com/obviam/mvc-droids or download as zip file.


You can also use git

$ git clone git://github.com/obviam/mvc-droids.git

Reference: Building Games Using the MVC Pattern Tutorial and Introduction from our JCG
partner Impaler at the Against the Grain blog.

18

Android Game Development with libgdx


Prototype in a day, Part 1a
Published on May 3, 2012 | 12,104 views | Filed in: Android Games

In this article I will take a detour from the building blocks of a game engine and components and
I will demonstrate how to prototype a game quickly using the libgdx library.
What you will learn:

Create a very simple 2D shooter platformer game.

What a complete game architecture looks like.

How to use 2D Graphics with OpenGL without knowing anything about OpenGL.

What different entities make up a game and how they are tied together in a game world.

How to add sound to your game.

How to build your game on the desktop and deploy in onto Android yes, its that magic.

Steps to create a game

1. Have an idea for a game.

2. Draft up some scenarios on paper to resemble your vision and how will it look like.

3. Analyse the idea, iterate over a few versions by tweaking it and decide what the game
will have in its initial version.

4. Pick a technology and start prototyping.

5. Start coding and creating the assets for the game.

6. Play-test, improve, and continuously make small steps towards finishing it.

7. Polish and release!

The Game Idea


Because this will be a one day project, there is very limited time at disposal and the goal is to
learn the technology to make games, not the actual process. For this purpose I took the liberty to
borrow ideas from other games and focus on the technical aspects of this process.
I will be borrowing heavily from a game called Star Guard. Its a little gem made by Vacuum
Flowers. Go get the game and check it out. A very simple shooter platformer with a simplistic
style and old school arcade feel.
The idea is to guide our hero through the levels by killing enemies and and dodging everything
that tries to kill us.
The controls are simple, the arrow keys move the hero to the left or right, Z jumps and X shoots
the laser. The longer the jump button is held, the higher the hero jumps. He can change direction
in the air and also shoot. Well see how we can translate these controls to Android later on.
The next steps (2 and 3) can be skipped over as we will already have this taken care of because
of the functioning game.
Start your Eclipse
This is where we start. I will be using libgdx library to create the game. Why libgdx? Its the best
library (in my opinion) that makes developing games easy without knowing much about the
underlying technology. It allows developers to create their games on the desktop and deploy it to
Android without any modification. It offers all the elements to use it in games and hides the
complexity of dealing with specific technologies and hardware. It will become more obvious as
we go along.
Setting up the project
By following the instructions from libgdxs documentation we have to first download the library.
Go to http://libgdx.badlogicgames.com/nightlies/ and download the libgdx-nightlylatest.zip file and unpack it.
Create a simple java project in eclipse. I will call it star-assault.

Leave the default settings and once the project was created, right click on it and select New>Folder and create a directory named libs.
From the unpacked libgdx-nighly-latest directory, copy the gdx.jar file into the newly
created libs directory. Also copy the the gdx-sources.jar file into the libs directory. It is in
the sources sub-directory of the unpacked gdx directory. You can do this by simply dragging the
jar files into your directories in eclipse. If you copy them using explorer, or finder or any other
means, dont forget to refresh your eclipse project after by pressing F5.
The structure should look like the following image:

Add gdx.jar as a dependency to the project. Do this by right-clicking the project title and
select Properties. On this screen pick Java Build Path and click onto the Libraries tab. Click
Add JARs, navigate to the libs directory and select gdx.jar, then click OK.
In order to have access to the gdx source code and to be able to debug our game easily, its a
good idea to add the sources to the gdx.jar file. To do this, expand the gdx.jar node, select

Source attachment, click Edit, then Workspace and pick gdx-sources.jar then OK
until all the pop-up windows are closed.

The complete documentation for setting up projects with libgdx can be found on the official
wiki.
This project will be the core project for the game. It will contain the game mechanics, the engine,
everything. We will need to create two more projects, basically launchers for the 2 platforms we
are targeting. One for Android and one for Desktop. These projects will be extremely simple and
will contain only the dependencies required to run the game on the respective platforms. Think
of them as the class containing the main method.
Why do we need separate projects for these? Because libgdx hides the complexity of dealing
with the underlying operating system (graphics, audio, user input, file i/o, etc.), Each platform
has a specific implementation and we will need to include only those implementations (bindings)
that are required targeted. Also because the application life-cycle, the asset loading (loading of
images, sounds, etc) and other common aspects of an application are heavily simplified, the
platform specific implementations reside in different JAR files and only those need to be
included that are required for the platform we are targeting.
The Desktop Version
Create a simple java project as in the previous step and name it star-assault-desktop. Also
follow the steps to create the libs directory. This time the required jar files from the
downloaded zip file are:
gdx-natives.jar,

gdx-backend-lwjgl.jar,
gdx-backend-lwjgl-natives.jar.
Also add these jar files as dependencies

to the project as in the previous project. (right click the


project -> Properties -> Java Build Path -> Libraries -> Add JARs, select the three JARs and
click OK.)
We also need to add the star-assault project to the dependencies. To do this, click the
Projects tab, click Add, check the star-assault project and click OK.
Important! We need to make the star-assault project a transitive dependency, meaning that
dependencies for this project to be made dependencies of projects depending on this. To do this:
right click on the main project -> Properties -> Java Build Path -> Order and Export ->
check the gdx.jar file and click OK.
The Android Version
For this you will need the Android SDK installed.
Create a new Android project in eclipse: File -> New -> Project -> Android Project.
Name it star-assault-android. For build target, check Android 2.3?. Specify a package
name net.obviam or your own preference. Next to Create Activity enter
StarAssaultActivity. Click Finish.

Go to the project directory and create a sub-directory named libs (you can do this from eclipse).
From the nightly zip, place gdx-backend-android.jar and the armeabi and armeabi-v7a
directories in the newly created libs directory.

In eclipse, right click the project -> Properties -> Java Build Path -> Libraries -> Add
JARs, select gdx-backend-android.jar and click OK.
Click Add JARs again, select gdx.jar under the main project (star-assault) and click OK.
Click the Projects tab, click Add, check the main project and click OK twice.
This is how the structure should look like:

Important!
For ADT release 17 and newer, the gdx jar files need to be explicitly marked to be exported.
To do this
Click on the Android Project
Select Properties
Select Java Build Path (step 1)
Select Order and Export (step 2)
Check all the references, e.g. the gdx.jar, the gdx-backend-android.jar, the main project etc.
(step 3).
The following image shows the new state.

Also, more information on this issue here.


Sharing the Assets (images, sounds and other data)
Because the game will be identical on both desktop and Android but each version requires to be
built separately from different projects, we want to keep the images, sounds and other data files
in a shared location. Ideally this would be in the main project as it is included in both Android
and desktop bu because Android has a strict rule on where to keep all these files, we will have to
keep the assets there. It is in the automatically created assets directory in the Android project.
In eclipse there is the possibility to link directories as in symbolic links on linux/mac or shortcuts
in windows. To link the assets directory from the Android project to the desktop project do the
following:
Right click the star-assault-desktop project -> Properties -> Java Build Path -> Source
tab -> Link Source -> Browse -> browse to the asssets directory in the star-assaultandroid project and click Finish. You can also extend the Variables instead of browsing to
the assets directory. It is recommended as it makes the project file system independent.
Also make sure the assets directory is included as a source folder. To do that, right click on the
assets directory in eclipse (the desktop project), select Build Path -> Use as Source Folder.
At this stage we are ready with the setup and we can go ahead to work on the game.
Creating the Game
A computer application is a piece of software that runs on a machine. It starts up, does something
(even if thats nothing) and stops in a way or another. A computer game is a specific type of
application in which the does something part is filled with a game. The start and end is
common to all applications. Also the game has a very straight forward architecture based around
an continuous loop. You can find out more about the architecture and the loop here and here.

Thanks to libgdx our game can be pieced together as a staged play in a theatre. All you need to
do is, to think of the game as a theatrical play. We will define the stages, the actors, their roles
and behaviours, but we will delegate the choreography to the player.
So to set up our game/play we need to take the following steps:

1. Start application.

2. Load up all the images and sounds and store them in memory.

3. Create the stages for our play along with the actors and their behaviours (rules for
interactions between them).

4. Hand the control to the player.

5. Create the engine that will manipulate the actors on the stage based on the input
received from the controller.

6. Determine when the play ends.

7. End the show.

It looks quite simple and it really is. I will be introducing the notions and elements as they
appear.
To create the Game we simply need just one class.
Lets create StarAssault.java in the star-assault project. Every class will be created in this
project with 2 exceptions.
view source
print?
01
package net.obviam.starassault;
02
03 import com.badlogic.gdx.ApplicationListener;
04
05 public class StarAssault implements ApplicationListener {
06
07
@Override
08
public void create() {
09
// TODO Auto-generated method stub
10
}
11
12
@Override
13 public void resize(int width, int height) {

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

// TODO Auto-generated method stub


}
@Override
public void render() {
// TODO Auto-generated method stub
}
@Override
public void pause() {
// TODO Auto-generated method stub
}
@Override
public void resume() {
// TODO Auto-generated method stub
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
}

Just implement ApplicationListener from gdx and eclipse will generate the stubs for the
methods needed to be implemented.
These are all the methods that we need to implement from the application lifecycle. It is very
simple considering all the setup code needed for Android, or on desktop to initialise the OpenGL
context and all those boring (and difficult) tasks.
The method create() is called first. This happens when the application is ready and we can start
loading our assets and create the stage and actors. Think of building the stage for the play in a
theatre AFTER all the things have been shipped there and prepared. Depending on where the
theatre is and how you get there, the logistic can be a nightmare. You can ship things by hand, or
by plane or truckswe dont know. Were inside and have the stuff ready and we can start to
assemble it. This is what libgdx is doing for us. Shipping our stuff and delivering it regardless of
the platform.
The method resize(int width, int height) is called every time the drawable surface is
resized. This gives us the chance to rearrange the bits before we go on to start the play. It
happens when the window (if the game runs in one) is resized for example.
The heart of every game is the render() method which is nothing more than the infinite loop.
This gets called continuously until we decide that the game is over and want to terminate the
program. This is the play in progress.

Note: For computers the game over is not equivalent of program over. So its just a state. The
program is in a state of game over, but is still running.
Of course that the play can be interrupted bu pauses and they can be resumed. The pause()
method will be called whenever the application enters into the background on the desktop or
Android. When the application comes to the foreground it resumes and the resume() method is
being called.
When the game is done and the application is being closed, the dispose() is called and this is
the time to do some cleanup. Its similar when the play is over, spectators have left and the stage
is being dismantled. No more coming back. More on the lifecycle here.
The Actors
Lets start taking steps towards the actual game. The first mile-stone is to have a world in which
our guy can move. The world is composed of levels and each level is composed of a terrain. The
terrain is nothing more than some blocks through which our guy cant go.
Identifying the actors and entities so far in the game is easy.
We have the guy (lets call him Bob libgdx has tutorials with Bob) and the blocks that make up
the world.
Having played Star Guard we can see that Bob has a few states. When we dont touch anything,
Bob is idle. He can also move (in both directions) and he can also jump. Also when hes dead, he
cant do anything. Bob can be in only one of the 4 identified states at any given time. There are
other states as well but well leave them out for now.
The states for Bob:

Idle when not moving or jumping and is alive

Moving either left or right at a constant speed.

Jumping also facing left or right and high or low.

Dead hes not even visible and respawning.

The Blocks are the other actors. For simplicity we have just blocks. The level consists of blocks
placed in a 2 dimensional space. For simplicity we will use a grid.
Turn the start of Star Guard into a block and Bob structure, will look something like this:

The top one is the original and the bottom one is our world representation.
We have imagined the world but we need to work in a measure system that we can make sense
of. For simplicity we will say that one block in the world is one unit wide and 1 unit tall. We can
use meters to make it even simpler but because Bob is half a unit, it makes him half a meter.
Lets say 4 units in the game world make up 1 meter so Bob will be 2 meters tall.

It is important because when we will calculate the speed with which Bob runs for example, we
need to know what were doing.
Lets create the world.
Our main playable character is Bob.
The Bob.java class looks like this:
view source
print?
01
package net.obviam.starassault.model;
02
03 import com.badlogic.gdx.math.Rectangle;
04 import com.badlogic.gdx.math.Vector2;
05
06
public class Bob {
07
08
public enum State {
09
IDLE, WALKING, JUMPING, DYING
10
}
11
12 static final float SPEED = 2f; // unit per second
13 static final float JUMP_VELOCITY = 1f;
14 static final float SIZE = 0.5f; // half a unit
15
16
Vector2 position = new Vector2();
17
Vector2 acceleration = new Vector2();

18
19
20
21
22
23
24
25
26
27
28

Vector2 velocity = new Vector2();


Rectangle bounds = new Rectangle();
State state = State.IDLE;
boolean facingLeft = true;
public Bob(Vector2 position) {
this.position = position;
this.bounds.height = SIZE;
this.bounds.width = SIZE;
}
}

Lines #16-#21 define the attributes of Bob. The values of these attributes define Bobs state at
any given time.
position Bobs position in the world. This is expressed in world coordinates (more on this
later).
acceleration This will determine the acceleration when Bob jumps.
velocity Will be calculated and used for moving Bob around.
bounds Each element in the game will have a bounding box. This is nothing more than a
rectangle, in order to know if Bob ran into a wall, got killed by a bullet or shot an enemy and hit.
It will be used for collision detection. Think of playing with cubes.
state the current state of Bob. When we issue the walk action, the state will be WALKING and
based on this state, we know what to draw onto the screen.
facingLeft represents Bobs bearing. Being a simple 2D platformer, we have just 2 facings.
Left and right.
Lines #12-#15 define some constants we will use to calculate the speed and positions in the
world. These will be tweaked later on.
We also need some blocks to make up the world.
The Block.java class looks like this:
view source
print?
01
02
03
04
05
06
07
08
09
10
11

package net.obviam.starassault.model;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
public class Block {
static final float SIZE = 1f;
Vector2 position = new Vector2();
Rectangle bounds = new Rectangle();

12
13
14
15
16
17
18

public Block(Vector2 pos) {


this.position = pos;
this.bounds.width = SIZE;
this.bounds.height = SIZE;
}
}

Blocks are nothing more than rectangles placed in the world. We will use these blocks to make
up the terrain. We have one simple rule. Nothing can penetrate them.
libgdx note
You might have noticed that we are using the Vector2 type from libgdx. This makes our life
considerably easier as it provides everything we need to work with Euclidean vectors. We will
use vectors to position entities, to calculate speeds, and to move thing around.
About the coordinate system and units
As the real world, our world has dimensions. Think of a room in a flat. It has a width, height and
depth. We will make it 2 dimensional and will get rid of the depth. If the room is 5 meters wide
and 3 meters tall we can say that we described the room in the metric system. It is easy to
imagine placing a table 1 meter wide and 1 meter tall in the middle. We cant go through the
table, to cross it, we will need to jump on top of it, walk 1 meter and jump off. We can use
multiple tables to create a pyramid and create some weird designs in the room.
In our star assault world, the world represents the room, the blocks the table and the unit, the
meter in the real world.
If I run with 10km/h that translates to 2.77777778 metres / second ( 10 * 1000 / 3600). To
translate this to Star Assault world coordinates, we will say that to resemble a 10km/h speed, we
will use 2.7 units/second.
Examine the following diagram of representing the bounding boxes and Bob in the world
coordinate system.

The red squares are the bounding boxes of the blocks. The green square is Bobs bounding box.
The empty squares are just empty air. The grid is just for reference. This is the world we will be
creating our simulations in. The coordinate systems origin is at the bottom left, so walking left at
10.000 units/hour means that Bobs positions X coordinate will decrease with 2.7 units every
second.
Also note that the access to the members is package default and the models are in a separate
package. We will have to create accessor methods (getters and setters) to get access to them from
the engine.
Creating the World
As a first step we will just create the world as a hard-coded tiny room. It will be 10 units wide
and 7 units tall. We will place Bob and the blocks following the image shown below.

The World.java looks like this:


view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

package net.obviam.starassault.model;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
public class World {
/** The blocks making up the world **/
Array<Block> blocks = new Array<Block>();
/** Our player controlled hero **/
Bob bob;
// Getters ----------public Array<Block> getBlocks() {
return blocks;
}
public Bob getBob() {
return bob;
}
// -------------------public World() {
createDemoWorld();
}
private void createDemoWorld() {
bob = new Bob(new Vector2(7, 2));
for (int i = 0;
blocks.add(new
blocks.add(new
if (i > 2)
blocks.add(new
}
blocks.add(new
blocks.add(new
blocks.add(new
blocks.add(new

i < 10; i++) {


Block(new Vector2(i, 0)));
Block(new Vector2(i, 7)));
Block(new Vector2(i, 1)));
Block(new
Block(new
Block(new
Block(new

Vector2(9,
Vector2(9,
Vector2(9,
Vector2(9,

2)));
3)));
4)));
5)));

blocks.add(new Block(new Vector2(6, 3)));


blocks.add(new Block(new Vector2(6, 4)));
blocks.add(new Block(new Vector2(6, 5)));

43
44

}
}

It is a simple container class for the entities in the world. Currently the entities are the blocks and
Bob. In the constructor the blocks are added to the blocks array and Bob is created. Its all hardcoded for the time being.
Remember that the origin is in the bottom left corner.
Check out the rest of the tutorial here.
Reference: Getting Started in Android Game Development with libgdx Create a Working
Prototype in a Day Tutorial Part 1 from our JCG partner Impaler at the Against the Grain blog.

19

Android Game Development with libgdx


Prototype in a day, Part 1b
Published on May 3, 2012 | 6,304 views | Filed in: Android Games

Creating the Game and Displaying the World


To render the world onto the screen, we need to create a screen for it and tell it to render the
world. In libgdx there is a convenience class called Game and we will rewrite the StarAssault
class a subclass of the Game class provided by libgdx.
About Screens
A game can consist of multiple screens. Even our game will have 3 basic screens. The Start
Game screen, the Play Screen and the Game Over screen. Each screen is concerned with the
things happening on it and they dont care about each other. The Start Game screen for example
will contain the menu options Play and Quit. It has two elements (buttons) and it is concerned
about handling the clicks/touches on those elements. It renders tirelessly those two buttons and if
the Play button is clicked/touched, it notifies the main Game to load the Play Screen and get rid
of the current screen. The Play Screen will run our game and will handle everything regarding
the game. Once the Game Over state is reached, it tells the main Game to transition to the Game
Over screen, whose sole purpose is to display the high scores and listen to clicks on the Replay
button.
Lets refactor the code and create just the main screen for the game for the time being. We will
skip the start and game over screens.
The GameScreen.java
view source

print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

package net.obviam.starassault.screens;
import com.badlogic.gdx.Screen;
public class GameScreen implements Screen {
@Override
public void render(float delta) {
// TODO Auto-generated method stub
}
@Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void show() {
// TODO Auto-generated method stub
}
@Override
public void hide() {
// TODO Auto-generated method stub
}
@Override
public void pause() {
// TODO Auto-generated method stub
}
@Override
public void resume() {
// TODO Auto-generated method stub
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}

The StarAssault.java will become very simple.


view source

print?
01
package net.obviam.starassault;
02
03 import net.obviam.starassault.screens.GameScreen;
04
05
import com.badlogic.gdx.Game;
06
07 public class StarAssault extends Game {
08
09
@Override
10
public void create() {
11
setScreen(new GameScreen());
12
}
13
}
GameScreen implements the Screen interface which is very much like an
ApplicationListener but it has 2 important methods added.
show() this is called when the main game makes this screen active
hide() this is called when the main game makes another screen active

has just one method implemented. The create() does nothing more than to
activate the newly instantiated GameScreen. In other words, it creates it, calls the show() method
and will subsequently call its render() method every cycle.
StarAssault

The GameScreen becomes our focus for the next part as it is where the game will live.
Remember that the game loop is the render() method. But to have something to render we first
need to create the world. The world can be created in the show() method as we dont have any
other screens that can interrupt our gameplay. Currently, the GameScreen is shown only when the
game starts.
We will add two members to the class and implement the render(float delta) method.
view source
print?
01
02
03
04
05
06
07
08
09

private World world;


private WorldRenderer renderer;
/** Rest of methods ommited **/
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

10
11

renderer.render();
}

The world attribute is the World instance which holds the blocks and Bob.
The renderer is a class which will draw/render the world onto the screen (I will reveal it
shortly).
The render(float delta)
Lets create the WorldRenderer class.
WorldRenderer.java

view source
print?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

package net.obviam.starassault.view;
import net.obviam.starassault.model.Block;
import net.obviam.starassault.model.Bob;
import net.obviam.starassault.model.World;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
public class WorldRenderer {
private World world;
private OrthographicCamera cam;
/** for debug rendering **/
ShapeRenderer debugRenderer = new ShapeRenderer();
public WorldRenderer(World world) {
this.world = world;
this.cam = new OrthographicCamera(10, 7);
this.cam.position.set(5, 3.5f, 0);
this.cam.update();
}
public void render() {
// render blocks
debugRenderer.setProjectionMatrix(cam.combined);
debugRenderer.begin(ShapeType.Rectangle);
for (Block block : world.getBlocks()) {
Rectangle rect = block.getBounds();
float x1 = block.getPosition().x + rect.x;
float y1 = block.getPosition().y + rect.y;

35
36
37
38
39
40
41
42
43
44
45
46
47

debugRenderer.setColor(new Color(1, 0, 0, 1));


debugRenderer.rect(x1, y1, rect.width, rect.height);
}
// render Bob
Bob bob = world.getBob();
Rectangle rect = bob.getBounds();
float x1 = bob.getPosition().x + rect.x;
float y1 = bob.getPosition().y + rect.y;
debugRenderer.setColor(new Color(0, 1, 0, 1));
debugRenderer.rect(x1, y1, rect.width, rect.height);
debugRenderer.end();
}
}

The WorldRenderer has only one purpose. To take the current state of the world and render its
current state to the screen. It has a single public render() method which gets called by the main
loop (GameScreen). The renderer needs to have access to the world so we will pass it in when
we instantiate the renderer. For the first step, we will render the bounding boxes of the elements
(blocks and Bob) to see what we have so far. Drawing primitives in OpenGL is quite tedious but
libgdx comes with a ShapeRenderer which makes this task very easy.
The important lines are explained.
#14 Declares the world as a member variable.
#15 We declare an OrthographicCamera. We will use this camera to look at the world from
an orthographic perspective. Currently the world is very small and it fits onto one screen, but
when we will have an extensive level and Bob moves around in it, we will have to move the
camera following Bob. Its analogous to a real life camera. More on orthographic projections can
be found here.
#18 The ShapeRenderer is declared. We will use this to draw primitives (rectangles) for the
entities. This is a helper renderer that can draw primitives like lines, rectangles, circles. For
anyone familiar with canvas based graphics, this should be easy.
#20 The constructor which takes the world as the parameter.
#22 We create the camera with a viewport of 10 units wide and 7 units tall. This means that
filling up the screen with unit blocks (width = height = 1) will result in showing 10 boxes on the
X axis and 7 on the Y.
Important: This is resolution independent. If the screen resolution is 480320, that means that
480 pixels represent 10 units, so a box will be 48 pixels wide. It also means that 320 pixels
represent 7 units so the boxes on the screen will be 45.7 pixels tall. It wont be a perfect square.
This is due to the aspect ratio. The aspect ratio in our case is 10:7.
#23 This lines positions the camera to look at the middle of the room. By default it looks at
(0,0) which is the corner of the room. The cameras (0,0) is in the middle as you would expect
from a normal camera. The following image shows the world and camera set-up coordinates.

#24 The internal matrices of the camera are updated. The update method must be called every
time the camera is acted upon (move, zoom, rotate, etc). OpenGL hidden beautifully.
The render() method:
#29 We apply the matrix from the camera to the renderer. This is necessary as we positioned
the camera and we want them to be the same.
#30 We tell the renderer that we want to draw rectangles.
#31 We will draw the blocks so we iterate through all of them in the world.
#32 #34 Extract the coordinates of the each blocks bounding rectangle. OpenGL works with
vertices (points) so for it to draw a rectangle have to know the coordinates for the starting point
and the width. Notice that we work in camera coordinates which coincides with the world
coordinates.
#35 Set the color of the rectangles to red.
#36 Draw the rectangle at the x1, y1 with the given width and height.
#39 #44 We do the same with Bob, but this time the rectangle is green.
#45 We let the renderer know that were done drawing rectangles.
We need to add the renderer and the world to the GameScreen (main loop) and see it in action.
Modify the GameScreen like this:
view source
print?
01 package net.obviam.starassault.screens;
02
03 import net.obviam.starassault.model.World;
04 import net.obviam.starassault.view.WorldRenderer;
05
06
import com.badlogic.gdx.Gdx;
07 import com.badlogic.gdx.Screen;
08 import com.badlogic.gdx.graphics.GL10;
09
10 public class GameScreen implements Screen {

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

private World world;


private WorldRenderer renderer;
@Override
public void show() {
world = new World();
renderer = new WorldRenderer(world);
}
@Override
public void render(float delta) {
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
renderer.render();
}
/** ... rest of method stubs omitted ... **/
}

The render(float delta) method has 3 lines. The first 2 lines clear the screen with black and
the 3rd line simply calls the renderers render() method.
The World and WorldRenderer are created when the screen is shown.
To test it on both the desktop and Android, we have to create the launchers for both platforms.
Creating the Desktop and Android Launchers
We have created 2 more projects in the beginning.
star-assault-desktop and star-assault-android, the latter being an Android project.
For the desktop project is dead simple. We need to create a class with a main method in it which
instantiates an application provided by libgdx.
Create the StarAssaultDesktop.java class in the desktop project.
view source
print?
1 package net.obviam.starassault;
2
3 import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
4
5 public class StarAssaultDesktop {
6 public static void main(String[] args) {
7 new LwjglApplication(new StarAssault(), "Star Assault", 480, 320, true);
8}
9
}

This is it. Line #7 is where everything happens. It instantiates a new LwjglApplication


application passing in a new StarAssault instance which is a Game implementation. The 2nd
and 3rd parameters tell the windows dimension. I opted for 480320 because it is a resolution
supported on many Android phones and I want to resemble it on the desktop. The last parameter
tells libgdx to use OpenGL ES 2.
Running the application as a normal Java program should produce the following result:

If you are getting some errors, track back and make sure the set-up is correct and all the steps are
followed, including checking gdx.jar at the export tab on the star-guard Project properties ->
Build Path.
The Android Version
In the star-assault-android project there is a single java class called StarAssaultActivity.
Change it to:
StarAssaultActivity.java

view source
print?
01
package net.obviam.starassault;
02
03
import android.os.Bundle;
04
05 import com.badlogic.gdx.backends.android.AndroidApplication;
06 import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
07

08 public class StarAssaultActivity extends AndroidApplication {


09 /** Called when the activity is first created. */
10 @Override
11 public void onCreate(Bundle savedInstanceState) {
12 super.onCreate(savedInstanceState);
1 AndroidApplicationConfiguration config = new
3 AndroidApplicationConfiguration();
1
config.useAccelerometer = false;
4
15
config.useCompass = false;
16
config.useWakelock = true;
17 config.useGL20 = true;
18 initialize(new StarAssault(), config);
19
}
20
}

Pay attention that the new activity extends AndroidApplication.


In line #13 an AndroidApplicationConfiguration object is created. We can set all types of
configurations regarding the Android platform. They are self explanatory but note that if we want
to use the Wakelock, the AndroidManifest.xml file also needs to be modified. This asks
permission from Android to keep the device on and to prevent dimming the screen if we dont
touch it.
Add the following line to the AndroidManifest.xml file somewhere inside the <manifest>tags.
view source
print?
1 <uses-permission android:name="android.permission.WAKE_LOCK"/>

Also in line #17 we tell Android to use OpenGL ES 2. This means we will be able to test it only
on a device as the emulator does not support OpenGL ES 2. In case there is a problem with it,
switch this to false.
Line #18 initialises the Android application and launches it.
Having a device connected to eclipse, it gets directly deployed and below you can see a photo of
the application running on a nexus one. It looks identical to the desktop version.

The MVC Pattern


Its quite impressive how far we came in such a short time. Note the use of the MVC pattern. Its
very efficient and simple. The models are the entities we want to display. The view is the
renderer. The view draws the models onto the screen. Now we need to interact with the entities
(especially Bob) and we will introduce some controllers too.
To read more on the MVC pattern, check out my other article or search for it on the net. Its very
useful.
Adding Images
So far its all nice but definitely we want to use some proper graphics. The power of MVC comes
in handy and we will modify the renderer so it will draw images instead of rectangles.
In OpenGL to display an image is quite a complicated process. First it needs to be loaded, turned
into a texture and then mapped to a surface which is described by some geometry. libgdx makes
this extremely easy. To turn an image from the disk into a texture is a one liner.
We will use 2 images hence 2 textures. One texture for Bob and one for the blocks. I have
created two images, a block and Bob. Bob is a copycat of the Star Guard chap. These are simple
png files and I will copy them into the assets/images directory. I have two images: block.png
and bob_01.png. Eventually Bob will become an animated character so I suffixed it with a
number (panning for the future).
First lets clean up the WorldRenderer a bit, namely, to extract the drawing of rectangles into a
separate method as we will be using it for debug purposes.
We will need to load the textures and render them accordingly to the screen.
Take a look at the new WorldRenderer.java
view source
print?
01
02
03
04

package net.obviam.starassault.view;
import net.obviam.starassault.model.Block;
import net.obviam.starassault.model.Bob;

05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

import net.obviam.starassault.model.World;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
public class WorldRenderer {
private static final float CAMERA_WIDTH = 10f;
private static final float CAMERA_HEIGHT = 7f;
private World world;
private OrthographicCamera cam;
/** for debug rendering **/
ShapeRenderer debugRenderer = new ShapeRenderer();
/** Textures **/
private Texture bobTexture;
private Texture blockTexture;
private SpriteBatch spriteBatch;
private boolean debug = false;
private int width;
private int height;
private float ppuX; // pixels per unit on the X axis
private float ppuY; // pixels per unit on the Y axis
public void setSize (int w, int h) {
this.width = w;
this.height = h;
ppuX = (float)width / CAMERA_WIDTH;
ppuY = (float)height / CAMERA_HEIGHT;
}
public WorldRenderer(World world, boolean debug) {
this.world = world;
this.cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
this.cam.position.set(CAMERA_WIDTH / 2f, CAMERA_HEIGHT / 2f, 0);
this.cam.update();
this.debug = debug;
spriteBatch = new SpriteBatch();
loadTextures();
}

53 private void loadTextures() {


54 bobTexture = new Texture(Gdx.files.internal("images/bob_01.png"));
55 blockTexture = new Texture(Gdx.files.internal("images/block.png"));
56 }
57
58
public void render() {
59
spriteBatch.begin();
60
drawBlocks();
61
drawBob();
62
spriteBatch.end();
63
if (debug)
64
drawDebug();
65
}
66
67 private void drawBlocks() {
68 for (Block block : world.getBlocks()) {
6 spriteBatch.draw(blockTexture, block.getPosition().x * ppuX,
9 block.getPosition().y * ppuY, Block.SIZE * ppuX, Block.SIZE * ppuY);
7
}
0
71
}
72
73
private void drawBob() {
74
Bob bob = world.getBob();
7 spriteBatch.draw(bobTexture, bob.getPosition().x * ppuX,
5 bob.getPosition().y * ppuY, Bob.SIZE * ppuX, Bob.SIZE * ppuY);
7
}
6
77
78
private void drawDebug() {
79 // render blocks
80 debugRenderer.setProjectionMatrix(cam.combined);
81 debugRenderer.begin(ShapeType.Rectangle);
82 for (Block block : world.getBlocks()) {
83 Rectangle rect = block.getBounds();
84 float x1 = block.getPosition().x + rect.x;
85 float y1 = block.getPosition().y + rect.y;
86 debugRenderer.setColor(new Color(1, 0, 0, 1));
87 debugRenderer.rect(x1, y1, rect.width, rect.height);
88 }
89
// render Bob
90
Bob bob = world.getBob();
91 Rectangle rect = bob.getBounds();
92 float x1 = bob.getPosition().x + rect.x;
93 float y1 = bob.getPosition().y + rect.y;
94 debugRenderer.setColor(new Color(0, 1, 0, 1));
95 debugRenderer.rect(x1, y1, rect.width, rect.height);
96 debugRenderer.end();
97
}
98
}

Ill point out the important lines:


#17 & #18 Declared constants for the viewports dimensions. Its used for the camera.
#27 & #28 Declare the 2 textures that will be used for Bob and the blocks.
#30 The SpriteBatch is declared. The SpriteBatch takes care of all the texture mapping,
displaying and so on for us.
#31 Its an attribute set in the constructor to know if we need to render the debug screen too or
not. Remember, the debug rendering will just render the boxes for the game elements.
#32 #35 these variables are necessary to correctly display the elements. The width and
height hold the screen size in pixels and are passed in from the operating system at the resize
step. The ppuX and ppuY are the number of pixels per unit.
Because we set the camera to have a view port of 107 in world coordinates (meaning we can
display 10 boxes horizontally and 7 boxes vertically) and we are dealing with pixels on the end
result, we need to map those values to the actual pixel coordinates. We have chosen to work in a
480320 resolution. That means that 480 pixels horizontally are equivalent of 10 units, meaning
a unit will consists of 48 pixels on the screen.
If we try to use the same unit for the height (48 pixels) we get 336 pixels (48 * 7 = 336). But we
have only 320 pixels available and we want to show the whole 7 blocks height. Doing the same
for the vertical part, we get that 1 unit vertically will be 320 / 7 = 45.71 pixels. We need to distort
every image a bit to fit in our world.
Its perfectly fine and OpenGL does that very easily. This happens when we change the aspect
ratio on our TV set and sometimes the image gets elongated or squashed to fit everything on the
screen, or we just simply choose the option to cut the image off but maintain the aspect ratio.
Note: we use float for this, even if the screen resolution deals with ints, OpenGL prefers floats
and so do we. OpenGL will work out the dimensions and where to place pixels.
#36 The setSize (int w, int h) method will be called every time the screen is resized and
it simply (re)calculates the units in pixels.
#43 The constructor changed just a little but it does very important things. It instantiates the
SpriteBatch and loads the textures (line #50).
#53 loadTextures() does what it says: loads the textures. Look how incredibly simple it is.
To create a texture, we need to pass in a file handler and it creates a texture out of it. The file
handlers in libgdx are very helpful, as we dont differentiate between Android or deskop, we just
specify that we want to use an internal file and it knows how to load it. Note that for the path we
skipped assets because assets is used as a source directory, meaning everything from that
directory gets copied into the root of the final bundle. So assets acts as a root directory.
#58 the new render() method contains just a few lines.
#59 & #62 enclose a SpriteBatch drawing block/session. Every time we want to render
images in OpenGL through the SpriteBatch we have to call begin(), draw our stuff and end()
when were done. It is important to do that, otherwise it wont work. You can read more on
SpriteBatch here.
#60 & #61 simply call 2 methods to render first the blocks and then Bob.
#63 & #64 if debug is enabled, call the method to render the boxes. The drawDebug method
was detailed previously.
#67 #76 the drawBlocks and drawBob methods are similar. Each method calls the draw
method of the spriteBatch with a texture. It is important to understand this.
The first parameter is the texture (the image loaded from the disk).
The second and third parameters tell the spriteBatch where to display the image. Note that we

use the conversion of coordinates from world coordinates to screen coordinates. Here is where
the ppuX and ppuY are used. You can do the calculations by hand and see where the images get
displayed. SpriteBatch by default uses a coordinate system with the origin (0, 0) in the bottom
left corner.
Thats it. Just make sure you modify the GameScreen class so the resize gets called on the
renderer and also to set the renderers debug to true.
The modified bits of GameScreen
view source
print?
01
02
03
04
05
06
07
08
09
10

/** ... omitted ... **/


public void show() {
world = new World();
renderer = new WorldRenderer(world, true);
}
public void resize(int width, int height) {
renderer.setSize(width, height);
}
/** ... omitted ... **/

Running the application should produce the following result:


without debug

and with debug rendering

Great! Give it a try on Android too and see how it looks.


Processing Input on Desktop & Android
Weve come a long way but so far the world is static and nothing interesting is going on. To
make it a game, we need to add input processing, to intercept keys and touches and create some
action based on those.
The control schema on the Desktop is very simple. The arrow keys will move Bob to the left
and right, z will make Bob jump and x will fire the weapon. On Android we will have a different
approach. We will designate some buttons for these functions and will lay it down on the screen
and by touching the respective areas we will consider one of the keys pressed.
To follow the MVC pattern, well separate the class that controls Bob and the rest of the world
from the model and view classes. Create the package net.obviam.starassault.controller
and all controllers will go there.
For the start we will control Bob by key presses. To play the game we to track the status of 4
keys: move left, move right, jump and fire. Because we will use 2 types of input (keyboard and
touch-screen), the actual events need to be fed into a processor that can trigger the actions.
Each action is triggered by an event.
The move left action is triggered by the event when the left arrow key is pressed or a certain
area of the screen is touched.
The jump action is triggered when the z key is pressed and so on.
Lets create a very simple controller called WorldController.
WorldController.java

view source
print?
01

package net.obviam.starassault.controller;

02
03
import java.util.HashMap;
04
import java.util.Map;
05 import net.obviam.starassault.model.Bob;
06 import net.obviam.starassault.model.Bob.State;
07 import net.obviam.starassault.model.World;
08
09
public class WorldController {
10
11
enum Keys {
12
LEFT, RIGHT, JUMP, FIRE
13
}
14
15
private World world;
16
private Bob bob;
1
7
1 static Map<Keys, Boolean> keys = new HashMap<WorldController.Keys,
8 Boolean>();
19
static {
20
keys.put(Keys.LEFT, false);
21
keys.put(Keys.RIGHT, false);
22
keys.put(Keys.JUMP, false);
23
keys.put(Keys.FIRE, false);
24
};
25
26
public WorldController(World world) {
27
this.world = world;
28
this.bob = world.getBob();
29
}
30
31 // ** Key presses and touches **************** //
32
33
public void leftPressed() {
34
keys.get(keys.put(Keys.LEFT, true));
35
}
36
37 public void rightPressed() {
38 keys.get(keys.put(Keys.RIGHT, true));
39
}
40
41
public void jumpPressed() {
42
keys.get(keys.put(Keys.JUMP, true));
43
}
44
45 public void firePressed() {
46 keys.get(keys.put(Keys.FIRE, false));
47
}

48
49 public void leftReleased() {
50 keys.get(keys.put(Keys.LEFT, false));
51
}
52
53 public void rightReleased() {
54 keys.get(keys.put(Keys.RIGHT, false));
55
}
56
57 public void jumpReleased() {
58 keys.get(keys.put(Keys.JUMP, false));
59
}
60
61 public void fireReleased() {
62 keys.get(keys.put(Keys.FIRE, false));
63
}
64
65
/** The main update method **/
66
public void update(float delta) {
67
processInput();
68
bob.update(delta);
69
}
70
71 /** Change Bob's state and parameters based on input controls **/
72 private void processInput() {
73
if (keys.get(Keys.LEFT)) {
74
// left is pressed
75
bob.setFacingLeft(true);
76
bob.setState(State.WALKING);
77
bob.getVelocity().x = -Bob.SPEED;
78
}
79
if (keys.get(Keys.RIGHT)) {
80
// left is pressed
81
bob.setFacingLeft(false);
82
bob.setState(State.WALKING);
83
bob.getVelocity().x = Bob.SPEED;
84
}
85 // need to check if both or none direction are pressed, then Bob is idle
86 if ((keys.get(Keys.LEFT) && keys.get(Keys.RIGHT)) ||
87 (!keys.get(Keys.LEFT) && !(keys.get(Keys.RIGHT)))) {
88 bob.setState(State.IDLE);
89
// acceleration is 0 on the x
90
bob.getAcceleration().x = 0;
91
// horizontal speed is 0
92
bob.getVelocity().x = 0;
93
}
94
}
95
}

#11 #13 define an enum for the actions Bob will perform. Each keypress/touch can trigger
one action.
#15 declare the World that is in the game. We will be controlling the entities found in the
world.
#16 declare Bob as a private member and it is just a reference to Bob in the game world, but we
will need it as its easier to refer to it than retrieving it every time we need him.
#18 #24 its a static HashMap of the keys and their statuses. If the key is pressed, its true,
false otherwise. It is statically initialised. This map will be used in the controllers update
method to work out what to do with Bob.
#26 This is the constructor that takes the World as the parameter and gets the reference to Bob
as well.
#33 #63 These methods are simple callbacks that are called whenever an action button was
pressed or a touch on a designated area happened. These methods are the ones that get called
from whatever input were using. They simply set the the value of the respective pressed keys in
the map. As you can see, the controller is a state machine too and its state is given by the keys
map.
#66 #69 the update method which gets called every cycle of the main loop. currently it does
2 things: 1 processes the input and 2 updates Bob. Bob has a dedicated update method which
we will see later.
#72 #92 the processInput method polls the keys map for the keys and sets the values on
Bob accordingly. For example lines #73 #78 check if the key is pressed for the movement to
the left and if so, then sets the facing for Bob to the left, his state to State.WALKING and his
velocity to Bobs speed but with a negative sign. The sign is because on the screen, left the
negative direction (origin is in the bottom left and points to the right).
The same thing for the right. There are some extra checks if both keys are pressed or none and in
this case, Bob becomes State.IDLE and his horizontal velocity will be 0.
Lets see what changed in Bob.java.
view source
print?
1
2
3
4
5
6
7
8
9

public static final float SPEED = 4f; // unit per second


public void setState(State newState) {
this.state = newState;
}
public void update(float delta) {
position.add(velocity.tmp().mul(delta));
}

Just changed the SPEED constant to 4 units (blocks) per second.


Also added the setState method because I forgot it before.
The most interesting is the newly acquired update(float delta) method, which is called from

the WorldController. This method simply updates Bobs position based on his velocity. For
simplicity we do only that without checking his state and because the controller takes care to set
the velocity for Bob according to his facing and state. We use vector math here and libgdx helps
a lot.
We simply add the distance travelled in delta seconds to Bobs current position. We use
velocity.tmp() because the tmp() creates a new object with the same value as velocity and
we multiply that objects value with the elapsed time delta. In Java we have to be careful on
how were using references as velocity and position are both Vector2 objects. More on vectors
here http://en.wikipedia.org/wiki/Euclidean_vector.
We have almost everything, we just need to call the correct events when they happen. libgdx has
an input processor which has a few callback methods. Because we are using the GameScreen as
the playing surface, it makes sense to use it as the input handler too. To do this, the GameScreen
will implement the libgdx InputProcessor.
The new GameScreen.java
view source
print?
001
package net.obviam.starassault.screens;
002
003 import net.obviam.starassault.controller.WorldController;
004 import net.obviam.starassault.model.World;
005 import net.obviam.starassault.view.WorldRenderer;
006
007
import com.badlogic.gdx.Gdx;
008
import com.badlogic.gdx.Input.Keys;
009
import com.badlogic.gdx.InputProcessor;
010
import com.badlogic.gdx.Screen;
011
import com.badlogic.gdx.graphics.GL10;
012
013 public class GameScreen implements Screen, InputProcessor {
014
015
private World world;
016
private WorldRenderer renderer;
017
private WorldController controller;
018
019
private int width, height;
020
021
@Override
022
public void show() {
023
world = new World();
024
renderer = new WorldRenderer(world, false);
025
controller = new WorldController(world);
026
Gdx.input.setInputProcessor(this);
027
}

028
029
@Override
030
public void render(float delta) {
031
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
032
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
033
034
controller.update(delta);
035
renderer.render();
036
}
037
038
@Override
039
public void resize(int width, int height) {
040
renderer.setSize(width, height);
041
this.width = width;
042
this.height = height;
043
}
044
045
@Override
046
public void hide() {
047
Gdx.input.setInputProcessor(null);
048
}
049
050
@Override
051
public void pause() {
052
// TODO Auto-generated method stub
053
}
054
055
@Override
056
public void resume() {
057
// TODO Auto-generated method stub
058
}
059
060
@Override
061
public void dispose() {
062
Gdx.input.setInputProcessor(null);
063
}
064
065 // * InputProcessor methods ***************************//
066
067
@Override
068
public boolean keyDown(int keycode) {
069
if (keycode == Keys.LEFT)
070
controller.leftPressed();
071
if (keycode == Keys.RIGHT)
072
controller.rightPressed();
073
if (keycode == Keys.Z)
074
controller.jumpPressed();
075
if (keycode == Keys.X)

076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

controller.firePressed();
return true;
}
@Override
public boolean keyUp(int keycode) {
if (keycode == Keys.LEFT)
controller.leftReleased();
if (keycode == Keys.RIGHT)
controller.rightReleased();
if (keycode == Keys.Z)
controller.jumpReleased();
if (keycode == Keys.X)
controller.fireReleased();
return true;
}
@Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean touchDown(int x, int y, int pointer, int button) {
if (x < width / 2 && y > height / 2) {
controller.leftPressed();
}
if (x > width / 2 && y > height / 2) {
controller.rightPressed();
}
return true;
}
@Override
public boolean touchUp(int x, int y, int pointer, int button) {
if (x < width / 2 && y > height / 2) {
controller.leftReleased();
}
if (x > width / 2 && y > height / 2) {
controller.rightReleased();
}
return true;
}
@Override
public boolean touchDragged(int x, int y, int pointer) {
// TODO Auto-generated method stub
return false;

125
126
127
128
129
130
131
132
133
134
135
136
137
138

}
@Override
public boolean touchMoved(int x, int y) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
}

The changes:
#13 the class implements the InputProcessor
#19 the width and height of the screen used by the Android touch events.
#25 instantiate the WorldController with the world.
#26 set the this screen as the current input processor for the the application. libgdx treats this as
a global input processor so each screen has to set a different one if they dont share the same. In
this case the screen itself handles the input.
#47 & #62 we set the active global input processor to null just for cleanup.
#68 the method keyDown(int keycode) is triggered whenever a key is pressed on the physical
keyboard. The parameter keycode is the value of the pressed key and this way we can poll it and
in case its a desired key, do something. This is exactly whats happening. Based on the keys we
want, we pass on the event to the controller. The method also returns true to let the input
processor know that the input was handled.
#81 the keyUp is the exact inverse of the keyDown method. When the key is released, it simply
delegates to the WorldController.
#111 #118 this is where it gets interesting. This happens only on touch-screens and the
coordinates are passed in along with the pointer and button. The pointer is for multi-touch and
represents the id of the touch it captures.
The controls are utterly simple and are made just for simple demo purposes. The screen is
divided into 4 and if the touch falls int to lower left quadrant, it is treated as a move left action
trigger and passes the same event as the desktop to the controller.
Exactly the same thing for the touchUp.
Warning: This is very buggy and unreliable, as the touchDragged is not implemented and
whenever the finger is dragged across quadrants it will mess up things. This will be fixed of
course, the purpose is to demonstrate the multiple hardware inputs and how to tie them together.
Running the application on both desktop and Android will demonstrate the controls. On desktop
the arrow keys and on Android by touching the lower corners of the screen will move Bob.
On desktop you will notice that using the mouse to simulate touches will also work. This is
because touchXXX also handles mouse input on desktop. To fix this add the following line to the
beginning of touchDown and touchUp methods:

view source
print?
1 if (!Gdx.app.getType().equals(ApplicationType.Android))
2 return false;

This returns false if the application is not Android and does not execute the rest of the method.
Remember that false means that the input was not handled.

As we can see, Bob has moved.


Short Recap
So far we have covered quite a bit of game development and we already have something to show.
Gradually we have introduced working pieces into our app and step by step we have achieved
something.
We still need to add:

Terrain interaction (block collision, jump)

Animation

A big level and camera to follow Bob

Enemies and a gun to blast them

Sounds

Refined controls and fine tuning

More screens for game over and start

Have more fun with libgdx

Make sure you check out Part 2 (which is still in progress) in order to tick the aforementioned
list. But go ahead and do it yourself by all means and any feedback is much appreciated.
Also check out libgdx and its awesome community. The source code for this project can be
found here: https://github.com/obviam/star-assault
To check it out with git:

git clone git@github.com:obviam/star-assault.git

You can also download it as a zip file.


Reference: Getting Started in Android Game Development with libgdx Create a Working
Prototype in a Day Tutorial Part 1 from our JCG partner Impaler at the Against the Grain blog.

20

Android Game Postmortem ArkDroid


Development
Published on December 30, 2011 | 5,334 views | Filed in: Android Games Tags: featured

Hello guys,
As you might have noticed, we have recently delved into the world of mobile game
programming. This was done after creating JCG Studios, an independent mobile game studio
based on Athens, Greece.
JCG here stands for Just Cool Games, it is our other acronym, except for Java Code Geeks of
course.
Our platform of choice is Android and our first attempt of developing a game from scratch
resulted in the creation of ArkDroid. As its name suggests, ArkDroid is an Arkanoid clone for
Android. It is what we would like to call Brick Breaker Evolved.

ArkDroid features cinematic story line, appealing visual effects, deep space music themes,
campaign and free play modes and sophisticated weaponry system among others. We would love
it if you took a look at it and let us know what you think about it.
Having finished the development of ArkDroid a while ago, I would like to share some of the
experiences I gathered while being a member of the development team. Consider this as a basic
game postmortem, similar to the ones you might have read if you have some experience in game
programming.

Lets begin with a short overview of the game creation. The development team consisted of two
people, Byron and me. The development lasted about 4 months, each of us dedicating about 15
hours per week during that period. It was actually a side project running along with our regular
jobs and Java Code Geeks. We followed the usual approach of creating both a full version and a
lite version.
Following are some insights regarding game programming in general and more specifically
about programming for the Android platform.

R.T.F.M. (Read The Fine Manual)


Do yourself a favor and make sure you have a good grasp of the Android fundamentals before
embarking on the journey of making an Android game. Check out the developers guide and
make sure to bookmark the Javadoc pages. These are also available in the Android SDK for
offline browsing. It would be quite easy to get started if you have previous experience into
making games, but make sure you dedicate the appropriate time before delving into the magic
world of Android game programming. Our Android tutorials could be of help for this. We also
recently introduced Android Game Development Tutorials.

Collaborate Efficiently
Collaboration is critical when a distributed team is involved. Dont worry, nothing fancy is
required. For our online communication, we used Skype and for a loose project management
we played with Google Docs. A text document and a spreadsheet should be more than enough for
two people in order to track bugs and assign new features. Regarding the code itself, a versioning
system goes without saying. We decided to go with good-old Subversion, since this is what we
have the most experience with, but any modern source management tool would be fine. There are
also a bunch of sites that provide private repositories, do your search.
Rev up your engine
Resist falling victim of the Not Invented Here syndrom and embrace the power that a game
engine can give you. When starting development, we evaluated some of the available Android
game engines and we decided to go with the very nice AndEngine. AndEngine is quite mature,
provides an abundance of features and shortcuts and I guarantee that it will help you kick-start
your project in no time. It should definitely be noted tha libgdx was a close second and we
decided to skip it because it is a bit low level for us. We decided in favour of the lower
development time that AndEngine ensures. That being said, if performance is critical to your
games success, libgdx is a no-brainer. As an added bonus, libgdx is cross-platform, meaning that
it can be used to write both desktop and mobile (Android) games.

Know thy engine


As stated above, AndEngine was used to provide the core framework for building our game.
Before writing a single line code however, we made sure to got through all the available
tutorials. Unfortunately, there are no Javadocs (weird) so you will have to rely only on the
examples and the public forums. And hey, you got the source code available, right?

Hit that device


One of the most major issues we had during development was the ridicuslouly slow time that the
applications take in order to be deployed into the SDKs emulator. I mean come on, I have a
cutting edge laptop and it takes forever (ok about a minute and so) to redeploy the game on it.
For this reason, Byron and I made sure to purchase real devices for ourselves and perform the
majority of debugging and testing on them instead of the emulator.
Test, test, test
And yes, as you might have guessed, I mean test in the real device. You have to test the game in
every possible way. Act as a non-experienced mobile user. Provide random input and witness
how your game is going to react on that. Make sure that all corners are covered. Be warned, due
to the nature of games, it might be difficult to even reproduce a bug, let alone debug the game
and fix it.
Cover the spectrum
Android fragmentation is a real thing and it can be a major PITA. Different resolutions, screen
sizes, CPU powers and the list goes on. So, if you are thinking of Android game programming in
a more professional way, you will have to get more that one device in order to cover all bases,
from low-end to the high-end devices.
GC is your enemy
Good games provide first of all a smooth experience to their players. You have to avoid hiccups

during game play and as you might have guessed, hiccups are caused by Garbage Collections in
Android. It is really a stop the world procedure which unfortunately gets noticed by the users.
The best advice on this is to make absolutely sure that you do not create unnecessary objects.
Your game consists actually of a main loop, that is executed multiple times per second, so this
makes things worse. The resources are rather scarce in the mobile world, so proceed with big
caution.
Be Patient
You probably have heard all those stories about creating a game in a weekend or a few hours
time. Yeah, right Let me warn you, creating a non-trivial game requires a great amount of
effort and above all, patience.

Assets? What is this?


Ok, Byron and I are programmers at heart. Hardcore. Creating art sounds a bit bizarre to us. I
believe that the term programmers art is a very successful and representative one. If you can
afford to hire someone to create your graphics and sound, do it without thinking twice.
Otherwise, you will have to make the most out of the available tools. We used GIMP for our
image editing needs and I think that we actually managed to create some decent art work (mainly
Byron).
Beta testers wanted
When near the end of development, make sure to beta test your game. Find some friends or
relatives and let them experiment with your game. Ideally, you should be around when they play
with it. Watch them and see what they liked, what troubled them and what felt weird to them.
This feedback is invaluable, trust me on that. We were lucky enough to have some great beta
testers which helped us track some bugs and gave helpful advice (thank you Pelagia, Eleftheria,
Ben).

Just ship
It is quite common among developers to find unfinished projects. Applications that could have
changed the world and games that could have written history, but instead they gather dust
forgotten inside old hard disks. Fight all excuses and take the dive:
- I cannot ship yet, it is not done
- Just ship
- Hey, this function does not perform as well
- Just ship!
- But I havent finished feature X
- Just ship!!
- Yes, but my competition has feature Y
- Just ship!!
- With only 100 levels?
- Just ship!!!
Just ship the thing, get your users feedback and build on that.
Dont quit your day job just yet
This is a very common advice but I would like to repeat it here. Dont rush into making quick
decisions like quitting your day job. Mobile market is a very strange beast and while it could
make you a millionnaire, it could also leave you scratching your head as why your super-duper
game does not make a damned sell.
Game development is life changing
I personally come from a hardcore enterprise programming background (JEE to the max). You
probably know the drill: persist some data, commit that transaction, generate some reports, move
the data again, etc etc. This can get boring after a while. Game dev however is a totally
refreshing change, a brave new world that I am happy to have found.
Enjoy the game
Finally, make sure that you make something you actually like yourself. If you get bored by your
very own game, it is almost certain that you will drop out midway or that you will end up with
a horrible game. We decided to start our endeavor with an all-time classic. Who does not love
Arkanoid?
So, thats all folks Dont forget to share! And of course, do not forget to check out our new
Android Game, ArkDroid. You feedback will be more than helpful!

Potrebbero piacerti anche