Getting Started in Android Game Development

If you're interested in developing a game for the Android platform, there is a lot you need to know.  I'm the developer of Light Racer, Light Racer 3D and Wixel, which are currently available on the Android Market.  I've developed games before but the original Light Racer was my first Android application and I learned quite a bit about writing Android games that I'd like to share with everyone.  I even wrote an online book detailing the development of Light Racer 3D, which is full of how-tos and useful code snippets. If you have previous experience with game development, moving over to the mobile platform won't be all that difficult.  You will mostly just need to learn the architecture and API.  If you're new to game development, I have assembled a list of must-knows for getting started.  They apply to many different types of games, including action, strategy, simulation and puzzle.

Android is a Java-based environment.  This is nice for new developers as Java is widely accepted as a much easier language to get started in than C++, which is the norm for mobile development.  Google has also done an excellent job with documenting the API and providing examples to use.  There is an example to show functionality for almost 100% of the API, called API Demos.  If you're familiar with Java and have already used Eclipse, getting your first app working should be fairly simple.  If you've never coded anything in your life before, you will have a lot to absorb as you move forward, but don't get discouraged. 

Get the SDK

The first step in getting started with the Android platform is to get the Android SDK (Software Development Kit).  The SDK has the core libraries, an emulator, tools and sample code.  I highly recommend using Eclipse and the android eclipse plugin.  Eclipse IDE for Java Developers is fine if you are just doing Android.  If this is your first Java development project, you will want to download the full Java SE Development Kit (JDK) as it contains tools you will need for signing and deploying your application.

Learn the application architecture

As tempting as it may seem to just dive right in, it's very important to understand the android application architecture.  If you don't learn it, you may design things in such a way that will make it very difficult to fix problems with your game down the line.  You will want to understand Applications, Activities, Intents and how they are all related to each other.  Google has provided good information on the architecture here.  The really important thing is to understand why your game may need to consist of more than one Activity and what that means to designing a game with good user experience.  This is where things tie in to the Activity lifecycle.

Learn the activity lifecycle

The activity lifecycle is managed by the Android OS.  Your activity will be created, resumed, paused and destroyed as the OS dictates.  Handling these events correctly is very important to having an application that behaves well and does what the user perceives as correct.  It's very good to know how all of this works before you start designing your game because you will save yourself debugging time and costly redesign time later on.  For most applications, the default settings will work but for games, you may want to consider turning the SingleInstance flag on.  When set as default, android will create new instances of the activity as it sees fit.  For a game, you may only want to have 1 instance of the game activity.  This has some implications for how you need to manage the state of things but for me it solved some resource management issues and it should be considered.

The main loop

Depending on what type of game you are writing, you may or may not have a main loop.  If your game is not time-dependent or if it only responds to what the user does and will wait forever for user input without making any kind of visual changes, you may not need a main loop.  If you are writing an action game or a game that has animations, timers or any kind of automation, you should seriously consider using a main loop.

The main loop of a game is the part that "ticks" sub systems in a specific order and usually as many times per second as possible.  Your main loop will need to run on its own thread.  The reason for this is that Android has a main UI thread and if you don't run your own thread, the UI thread will be blocked by your game which will cause the Android OS to not be able to handle any of its normal update tasks. The order of execution is usually as follows:  State, Input, AI, Physics, Animation, Sound and Video. 

Updating State means to manage state transitions, such as a game over, character select or next level.  Often times you will want to wait a few seconds on a state and the State management is the part that should handle this delay and setting the next state after the time has passed.

Input is any key, scroll or touch from the user.  It's important to handle this before processing Physics because often times input will affect the physics so processing input first will make the game more responsive.  In Android, the input events come in from the main UI thread and so you must code to buffer the input so that your main loop can pick it up when the time comes.  This is not a difficult task.  Defining a field for the next user input and having the onKeyPressed or onTouchEvent set the next user action into that field is all that will be required.  All the Input update needs to do at that point is determine if it is valid input given the state of the game and let the Physics side handle responding to it. 

The AI update is analagous to a user deciding what they are going to "press" next.  Learning how to write AI is out of the scope of this article but the general idea is that the AI will press buttons just like the user does.  This will also be picked up and responded to by the Physics update.

The Physics update may or may not be actual physics.  For action games, the point of it is to take into account the last time it was updated, the current time it is being updated at, the user input and the AI input and determine where everything needs to be and whether any collisions have occured.  For a game where you visually grab pieces and slide them around, it will be the part that is sliding the piece or letting it drop into place.  For a trivia game, it would be the part deciding if the answer is right or wrong.  You may name yours something else, but every game has a part that is the red meat of the game engine and for this article, I'm referring to it as Physics.

Animations aren't as simple as just putting an animated gif into your game.  You will need to have the game draw each frame at the right time.  It's not as difficult as it sounds.  Keeping state fields like isDancing, danceFrame and lastDanceFrameTime allows for the Animation update to determine if its time to switch to the next frame.  That's all the animation update really does.  Actually displaying the change of animation is handled by the video update.
 
The Sound update handles triggering sounds, stopping sounds, changing volumes and changing the pitch of sounds.  Normally when writing a game, the sound update would actually produce a stream of bytes to be delivered to the sound buffer but Android manages its own sounds so your options for games are to use SoundPool or MediaPlayer.  They are both a little sensitive but know that because of some low level implementation details, small, low bitrate OGGs will yield the best performance results and the best stability.

The Video update takes into account the state of the game, the positions of players, scores, statuses, etc and draws everything to screen.  If using a main loop, you will want to use the SurfaceView and do a "push" draw.  With other views, the view itself will call the draw operation and the main loop won't have to do it.  SurfaceView gives the highest frames per second and is the most appropriate for games with animation or moving parts on screen.  All the video update should do is take the state of the game and draw it for this instance in time.  Any other automation is better handled by a different update task.

What's this code look like?  Here's an example.

public void run() {
    while (isRunning) {
        while (isPaused && isRunning) {
            sleep(100);
        }
        update();
    }
}

private void update() {
    updateState();
    updateInput();
    updateAI();
    updatePhysics();
    updateAnimations();
    updateSound();
    updateVideo();
}


3D or 2D?

Before you start on your game, you need to decide if you're going to go 3D or 2D.  2D games have a much lower learning curve and generally are easier to get good performance on.  3D games require much more in-depth math skills and may have performance issues if you are not very careful.  They also require the ability to use modeling tools like 3D Studio and Maya if you intend to have shapes more complex than Boxes and Circles.  Android supports OpenGL for 3D programming and there are many good tutorials on OpenGL that one can find to learn it.

Build simple, high quality methods

When getting started, make sure that you avoid writing one big long monolithic method that is "the game."  If you follow the main loop pattern that I described above, this should be fairly easy.  Each method you write should accomplish one very specific task and it should do so error-free.  For example, if you need to shuffle a deck of cards, you should have a method called "shuffleCards" and that should be all it does. 

This is a coding practice that applies to all software development but it's particularly important in game development.  Debugging can get very difficult in a stateful, real-time system.  Keep your methods small and the general rule of thumb is that each method should have 1 and only 1 purpose.  If you're going to programatically draw a background for a scene, you may want a method called "drawBackground."  Things like that will make it so that you develop your game in terms of building blocks and you will continue to be able to add what you need without making it too complex to understand.
 
It's all about efficiency!

Performance is a major issue for any game.  The goal is to make the game as responsive as possible and to also look as smooth as possible.  Certain methods like Canvas.drawLine are going to be slow.  Also drawing an entire screen-sized bitmap onto the main canvas every frame will also be costly.  Balancing things like that is necessary to achieve the best performance.  Make sure to manage your resources well and use tricks to use the least amount of CPU to achieve your task.  Even the best game will not be very fun if it can't perform well.  People in general have little tolerance for choppiness or poor response.

Tips and Tricks

Take a look at the example for LunarLander in the SDK.  It uses a SurfaceView and that would be the appropriate view to use for a game that needs the highest number of frames per second possible.  If you're going 3D, take a look at GLSurfaceView. It takes care of the OpenGL device initialization and provides a mechanism for rendering.  For LightRacer, I had to optimize the way I have everything drawn or else the framerate would be drastically lower.  I drew the background to a Bitmap only once which was when the view is initialized.  The light trails are in their own bitmap which gets updated as the racers move.  Those two bitmaps are drawn to the main canvas every frame with the racers drawn on top and then finally an explosion.  This technique made the game run at a playable rate.

It's also a good practice to have your bitmaps be the exact size you intend to draw them on screen, if applicable.  This makes it so that no scaling is needed and will save some CPU.

Use a consistent Bitmap Configuration (like RGBA8888) throughout the game.  This will save the graphics library CPU in having to translate the different formats.

If you're determined to develop a 3D game but have no 3D knowledge, you will want to pick up a book or two on 3D game programming and study up on linear algebra.  At a bare minimum, you must understand dot products, cross products, vectors, unit vectors, normals, matrixes and translation.  The best book I have come across for this math is called Mathematics for 3D Game Programming and Computer Graphics.

Keep the sound small and at a low bitrate.  The less there is to load, the faster loading times will be and the less memory the game will use.

Use OGGs for sound, PNGs for graphics.

Make sure to release all media players and null out all of your resources when the activity is destroyed.  This will ensure that the garbage collector gets to everything and that you don't have any memory leaks between launches of the game.

Join the Android Google group and find community support.  There will be people that can help you along the way.

Above all, spend time testing and retesting and making sure that every little thing works exactly the way you would expect it to.  Polishing the game up is the longest and hardest part of development.  If you rush it out to market, you will probably have a disappointed crowd and you may feel that all your hard work is wasted.  It's not possible to have 100% of people love what you write but you should at least try to put out the highest quality work that you can.

Google has excellent documentation for getting started here.

Find working game code samples and how-tos in the Light Racer 3D Development Journal

63 Comments

Post a comment here or discuss this and other topics in the forums

Hi Robert, Thanks for

Hi Robert,
Thanks for your Great Article..

Title screens

Very interesting, especially the videos showing how things come together.

I've a question about the 3D version. How are you doing the menus? Is each 'page' a separate Activity with standard Android UI widgets on or are you drawing it all by hand?

And during the game, how are you drawing the 'Game over' box that appears?

I'm making my own game and I was thinking about just drawing all that stuff using textured shapes, but it seems there should be a better way.

Each menu screen is an

Each menu screen is an activity and that is all standard Android UI. The text box in-game is a textured quad. I upload the texture every time the text changes, but in my new engine, I have a character atlas and so I can draw out whatever text I need to without uploading anything.

Drawable Vs Bitmap?

Robert,
Thanks for this great information, it has been very useful as an overarching conceptual guide to programming a game for a beginner. I have a very specific question though...

There seems to be many ways to do a particular thing. For example, in the Lunar Lander example, the Background is drawn as a Bitmap and the image of the spacecraft is of type "Drawable." I haven't found any clear documentation as to what a Drawable is and how it differs from a Bitmap. Why not just draw the image of the spacecraft as a bitmap? When should Drawables be used vs bitmaps from an efficiency standpoint?

I am asking this because I have an action type game with a background that is bigger than the canvas size so I allow users to scroll around to reach all parts of the background. I also have maybe 15 other objects (3K-5K each or so) that I am drawing as bitmaps fixed on this background. When the user scrolls a jitter effect occurs as the objects are redrawn from what I am assuming is the delay between drawing the new background view and the new location of the objects. Would drawables be more appropriate for these objects? Or some other approach entirely?

I am redrawing the background by using the canvas.drawBitmap (bitmap, RectSrc, RectDst, paint) function and having the RectSrc be the canvas size and RectDst the Rect surrounding the new bounds of the background that should be mapped...in case this could be the culprit.

Thanks again for this great article!

Greg, A drawable is a

Greg,

A drawable is a resource that is exactly that - drawable. It is a bitmap or a gradient or a 9-patch, color.. stuff like that. In games you use bitmaps. If someone is using a drawable, it's because of a matter of convenience. Perhaps they only needed to do a simple draw and never actually needed the bitmap data. That's fine.

I load everything into Bitmaps because I use canvas.drawBitmap for 2D stuff. Actually I do everything in OpenGL now but if I were to keep doing canvas-based 2D, it would be that.

For having a large, scrollable background, I recommend using tiles. You can either use micro tiles and have a level editor to place them or you can use macro tiles (big chunks of land) and just know the arrangement of them. When I say micro tiles, I mean like Super Mario Brothers style, where you have a tile for bricks, a tile for ground, etc.. Macro is like if you have an image that is 640x1920 that you want to scroll through, you can break it up into 320x480 tiles and only draw the current 2-4 tiles that you need to see a 320x480 screen of image. You can obviously go smaller than that and draw 160x160 tiles or something which would work nicely for those dimensions.

Tiles are nice because they are less bytes that you have to work with at a time and you can make larger maps with them if you're clever and reuse some. I don't know what would be causing your jitter. If you're working with really large bitmaps, it could be that. You'd need to debug a little further to figure it out - IE, try it without the background drawing code in.

Thank you so much for the

Thank you so much for the feedback...will be performing some tests later based on your comments

good 3D tutorial

"If you're going 3D, there is a GLView in the examples that handles a lot of initialization required to get a 3D display."

i don't see a GLView in the sdk's examples.

Updated

I was referring to the Kube and other 3D examples that were provided with Android 1.1. One of those had a class called GLView in them. I now recommend using 1.5's GLSurfaceView. The text has been updated to reflect this.

G8 article. I m new 2 game

G8 article. I m new 2 game development. Its inspiring . Hope it will help us.

Excellent

Excellent Article

ticks without main loop and thread

When I programmed a TETRIS, and I was thinking a long time on how to avoid a thread.
Here is my result:


import android.os.Handler;
...
public class Tetris extends Activity implements OnClickListener {
...
class TickHandler extends Handler {
@Override
public void handleMessage(Message msg) {
... // do your update() here
Trigger();
}
public void Trigger() {
removeMessages(0);
sendMessageDelayed(obtainMessage(0), TickTime);
}
}
...
}

The Hander goes into the same queue as the OnClickListener and the Activity's onKeyDown.

That works though I believe

That works though I believe that using a thread offers a little less CPU overhead and a little more control for you. Effectively what your code does is it has the UI thread drive your game. This is fine but if the UI thread gets busy for more than 100ms, you'll definitely see the result.

Thank you

Thanks a lot for your article... It has helped me out with a few issues i had..

Excellent Sir.. thank you so

Excellent Sir.. thank you so much for being selfless..

Great Article

This helped me a lot. I am just a beginner to game development.

New to This

Hi :)

Great article and information! It would be nice to have complete code to show how it all comes together.
I am particulary interested in developing simple apps to start allowing the user to select from various custom wallpaper images I create.
I am becoming familiar with java and have Eclipse and all the SDK's installed and working.
My talent lies mostly in 3d but is there simple code to create a basic wallpaper app? or would you be willing to share some insight and tips :)

Thank you!!

Great article

Great article, thanks for all the start off points. Im an iphone developer and im moving into the android field, because I have some hunch that the phone will become more popular that the iPhone. Google just has too much money to mess this up. Cant wait to see what happens!

where is the code of this game...

Hi,
please share the code of atleast Light Racer 2D, so that we can understand more...
BTW great article and very clear.

Thanks,

Sorry, Light Racer is not

Sorry, Light Racer is not an open source game. I'm supporting myself by developing games derived from that codebase and while my newest engine is very far away from where Light Racer was, I still can not afford to release that code. I hope I gave enough snippets to help people out with the general game development issues. If not, go ahead and ask for anything specific and I'll see what I can do.

thank you

thanks for this great intro.

Android will surpass the iPhone

Great article. There needs to be information on how to developer android based applications, because in my opinion it is the next wave for mobile phone development. With the nexus one coming out in 2010 and the Firefox mobile viewer, it should be easier than ever to create apps. Oh and did I mention? Firefox mobile will not be available on the iPhone, but rather the android and blackberry!

Great article!

This is one of the best intros I've read(and I've read a lot).

I'm not new to game programming, but I'm just starting out on Android and still learning my way around the SDK.

Your tips on best practices are very helpful. I'm glad to see people like you in the Android community and I have great hopes for Android's future.

Thanks!

This is really good one :D,

This is really good one :D, and hi everyone I'm newbie in Android also, nice to meet yall

Game Engine

Hey..

I am new to Android Game Development. I read your article about programming the multiplayer engine for your games but did not understand much. Could you please tell me where I can learn how to build a game engine from scratch for Android phones or could you please tell me yourself? I'd really appreciate it. Thank you.

As Robert said, try to do

As Robert said, try to do everything slowly. Read his article for few times slowly analyzing the content. Find more articles on the internet, try to do something and you will definitely succeed. I am a mobile developer by myself, and sometimes there are some newbies coming to our company in order to learn something. It is hard to learn them do android, windows mobile or iphone applications from nothing. But they are learning slowly, trying to do something, asking me about their problems, and after some time they can do such apps for themselves.
What about this article, thanks a lot Robert. I will definitely use it as a methodical thing for teaching some newbies in my company. It is well written and understandable. I will be waiting for another great articles from you in the nearest future.

Sincerely,

Kevin Gickson

Hi Mehjabeen. Building a

Hi Mehjabeen. Building a game engine for Android is not much different than building one for other platforms with the exception of Dalvik VM optimizations. I recommend picking up some books on game engine development. They'll have everything you need.

Start slow. Get a few things to work. Understand them then refactor to make room for more. ALWAYS watch your performance. It's a major issue with mobile game development.

Good luck!

I shall do that for sure. Our

I shall do that for sure. Our aim is actually to make a 2D multiplayer game for Android phones. Are there any multiplayer game engines that already exist for Android?

As far as I know, there's

As far as I know, there's mine (Light Racer Elite / 3D) and Chickenbrick's (Project INF). I don't think there is an abstract multiplayer engine because the netcode always depends on the world model and overall architecture so it's tough to just make a package that would actually work for most games. I recommend getting your game working then thinking about what design changes will be needed to add input and output pipelines.

Here's a good link - http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

Those guys did a good job. If you can use constant rate snapshots and a pipeline, you'll have a great multiplayer engine.

Some additional notes on performance

Hi Guys,

I'm woking on a game engine for Android and have also been coming across some performance stuff.
I wanted to outline a few no-go habits here. The most sensitive resources on the android is maybe the float calculations (no hardware float support) and the dalvik VM garbage collector. If you don't want to develop your own floating point libs, you can't really get around the float problem and I won't go into details here regarding floating point libs.

Regarding the GC I have a few tips for you:
* The golden rule is to avoid short term object allocation. All objects that are only used to do calculations should be better used in static fashion
* Try to avoid any strings in your code as they will mostly result in short lifetime objects. (yes, also debug messages will increase the object count dramatically, and specially in a game loop). You can fork the construction of the debug messages into a scope where you check for a global debug flag or something.
* When you use strings as id/references declare them somewhere as static finals.
* Don't use Set's. Try to use Lists (ArrayList, Vector).
* Start the standalone DDB console of the android toolkit and launch the Allocation Tracker feature in otder to see who / where / when you instance what objects and in what count. Check the reference to the code points and try to avoid any object creation if not absolutely needed. (i.e. instead of instancing a new ArrayList when you have a class that collects something and you need a fresh ArrayList just call ArrayList.clear())
* In a 30 fps game loop each object that gets instanced can be a show stopper. You need to minimize the count of instanced objects specially for objects which have a short lifetime anyway.
* NEVER use iterators (List.iterator() / for(Object o : objectList) ) they are causing lot of objets to be isntanced. Use the standard approach for(int i = 0; i < objectList.size(); i++)
* NEVER call a mehtode twice where potential calculations / allocations are involved . Create a local veriable and store the result with one singe call. i.e ArrayList.toArray() will allocate new memory for a copy of the internal elements and return a copy of the internal array. Avoid calling such a method twice and just store it localy.
* Try to use caches where possible.
* Also very important is that you understand Autoboxing and take into account the negative performance impact when using autoboxing. Every time a primitive type needs to be boxed into a complex type it will cause an other possible short lifetime object to be allocated. Generally the best thing to do is to use primitive data types where possible.

Have a nice day all of you :o)
Think geek, be smart!

Regards
Gion

Optimizing Canvas drawing?

Thanks for the great article, it certainly helped me get my feet wet. You mentioned that one thing you had to do to optimize your light racer game was to make it so that you only drew your game's background when needed. I'm having trouble understanding how this is possible -- right now I'm using the background to "clear" the canvas every frame in my doDraw() method, so that I can re-draw on each frame. I'd like to be able to optimize my game, but how exactly do you maintain the background image without having to render it every frame, and at the same time move a sprite from one position to another w/o "copying" it (causing the trailing effect)?

Post new comment

The content of this field is kept private and will not be shown publicly.
Add image
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <table> <tr> <td>
  • Lines and paragraphs break automatically.
  • Images can be added to this post.
  • Image links with 'rel="lightbox"' in the <a> tag will appear in a Lightbox when clicked on.
  • Image links with 'rel="lightshow"' in the <a> tag will appear in a Lightbox slideshow when clicked on.
  • Links to HTML content with 'rel="lightframe"' in the <a> tag will appear in a Lightbox when clicked on.
  • Links to video content with 'rel="lightvideo"' in the <a> tag will appear in a Lightbox when clicked on.
  • Links to inline or modal content with 'rel="lightmodal"' in the <a> tag will appear in a Lightbox when clicked on.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.