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 and
Wuzzle, which are currently available on the
Android Market. I've developed games before but this was my first Android application and I learned quite a bit about writing Android games that I'd like to share with everyone. 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 SDKThe 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 architectureAs 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 lifecycleThe
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 loopDepending 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 methodsWhen 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, there is a GLView in the examples that handles a lot of initialization required to get a 3D display. 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.
Follow my current game programming experience in the
Light Racer 3D Development Journal
Bookmark or Share this article:
Related Articles on Robert Green's DIY:
29 Comments
Post a comment here or discuss this and other topics in the forumsThanks!
Thanks for the article, great pep-talk for us up-and-coming Android game developers!
Cool
Nice introduction on developing apps on Android.
I'm going to download the Android SDK, the Java SE SDK and eclipse
I'm going to see what I can of game I can milk out.
As a C/C++ programmer who had worked years with opengl
this is the first time ever I'm really diving into Java and Opengl SE
cheers
Great! I hope you have a
Great! I hope you have a good experience. Don't expect the Android platform to be a huge OpenGL performer. It can do a small number of polys but nothing like you're used to on a desktop. I'll be diving in to it in a month or so.
Thanks I see that they have
Thanks
I see that they have made a QUAKE port on it.
so it must be possible to use every processing powers for it.
Great article.
This is a very well written article.
Thank you for it.
How about the input from the UI thread?
Thanks for the very informative article.
If you used a separate game thread, how did you go about getting the input info to thre thread since they are handled on the UI thread?
Cheers,
Cass
Thanks! I'm glad you found
Thanks! I'm glad you found the article helpful.
I have the view listen for key events. The events are sent into the thread through a direct method call which must be synchronized with the surface holder. Check the Lunar Lander game for an example.
Further comments
Hi mate, thanks again for your prompt help. I've played your game and enjoyed it very much - well done. :)
My java is a little rusty, but I am trying to get some hints from you whilst studying the LunarLander app.
The approach you mentioned is illustrated on the following, right?
public boolean onKeyUp(int keyCode, KeyEvent msg) {
return thread.doKeyUp(keyCode, msg);
}
The ImageView llistens for the action and then passes it on to the thread.
On a similar note, if you were to need to listen for sensor variations, would you instantiate the sensormanager within the thread as it does not need to receive any input from any View?
Cheers again for you patience and help.
Cass Surek
Yes!
That is exactly how I do it in Light Racer 1 and 2.
I haven't dealt with the sensor yet but I would first try creating an instance within the thread, just like your other resources and managers. I like to have an init() method that loads graphics and sounds and gets a hold of my managers. I usually then have a release() method that cleans up everything init() created. It makes it easy to avoid memory problems by sticking to that.
Read about the design changes for Light Racer 2 in the Light Racer 3D Development Journal for how I do things.
Thanks!
SensorManager and Drawables
Hi again, worked beautifully, but I have used the sensor on the main UI thread, passing on details to the game thread as per the other methods.
I got to animate things using various Drawables, one for each frame. In my case, I need the character to do a specific movement, so I've created an array of Drawables which get drawn as the animation progresses. Is that the best approach in your opinion? Is there a more streamlined technique to draw the frames? I will have at least 10 movements, which might take a considerable amount of memory! :)
Many thanks!
Cass
You are on-track
I like to load all of the frames into a class I call GameResources. That way the object can animate itself by keeping track of time and displaying the appropriate gameResources.characterAnimationFrame[i].
Say for instance you have a player character. You might want to call the class Player. Player would have fields for its location and what its doing. It should also have other state fields for modifications to it, like if it is currently on fire or exploding or jumping, standing, running, etc. Player should manage its states based on the input it receives and the result of the physics updates. Player can also draw itself and depending on what state it's in and what frame of animation is now selected, the drawing code can pull the appropriate frame from the game resources and draw it. Does that make sense? That's how I handle things. I encapsulate all of the functionality of a logical part of the game into a class like that and make it responsible for dealing with drawing itself.
Also - I've been asked this before so I did put together an article on How to handle interpolated animations using a main loop which has the code you're probably looking for.
Thanks
Hi Robert, I had taken a similar approach to what you described before even reading the other post. :) Thanks! I have a class called Person which has an Update() method that evaulates various conditions and then draws itself based on the current movement of the character. The animation works fine, although I will have to find another way of keeping the various frames of the several movements at hand, but not loaded all the time. The whole collection of PNGs appears to be too big for the memory available (gave me errors already).
The glitch I am getting now is after I return from an XML preferences screen, I have to check the thread state, delete and recreate it, as it gets finalised when the main activity loses focus. I can recreate the thread, but it is rather annoying as it takes forever to load all resources again (they are loaded within the Person class).
Anyway, I am progressing thanks to your help! Sincerely grategul for all your attention. :)
Cheers
Cass Surek
Consider a resource manager
Instead of having your Person hold its resources, you could have all resources for the game managed by a single class. When you create the person, you pass it this resource manager. I call mine GameResources and it is just a collection of bitmaps, paints and fonts that all of my different game objects use. Each game object needs it to be able to draw itself so it is passed in to each on the constructor. I also have a release() method for every game object that nulls out the game resources reference just in case.
GameResources is created by the thread and is responsible for loading everything. It is also responsible for unloading/freeing everything with the release() method. What you can do is initialize it in your activity and hang on to it there. Pass it to the thread and have the activity take care of cleaning it up onDestroy().
How big are your PNGs?? I have about 100 frames of animation loaded at any given time and don't have any memory issues. They range from 15x30 to 60x60 to 30x120. If any don't need transparency, make sure to load them using RGB_565. It is way faster than ARGB_8888. ARGB_4444 uses less memory but is very slow to draw. I also keep a 320x480 clean background bitmap (RGB_565), a 320x480 dynamic background bitmap (RGB_565) and a 320x480 text layer (ARGB_8888). I'd like to get rid of my text layer because those full screen layer draws are really slow.
GameResources and animation
Hi Robert,
Yes, the GameResources object appears to be a nice solution to simplify the handling of the various bits of data.
How do you load images on RGB_565 or any of the others?
My problem is that I am currently using the movements of the person with relatively large images at 320x480, with alpha. It works, but it needs improvement as each of these PNGs have around 20k.
What do you reckon? I was wanting to come up with at least 10 movements of 3 frames each. That'd give me around 600kb of PNGs. I need to show only head and torso, so I suppose it would be best to separate them?
Many thanks and have a great week over there!
Cass Surek
PS: I've fixed the XML preferences screen I had on the previous post. Yay! :)
Switched this to Forum
Cass,
I hope you don't mind but we're running out of room here so I moved the discussion to the forum. Here is where you can continue (you'll have to register but it's relatively painless).
Thanks!
Android future
The technology seems to be pretty promising. Given the simplicity on its part. Its true that android and iPhone have very bright future for different reasons though. It all depends on the marketing strategy adopted by one over another. Undoubtedly Apple & Google, both have proven track records of their working methodologies. Let’s keep our finger crossed till Apple 3.0 comes out and Android’s 1.5 and G2 rocks the market.
1.5 is out now for developers
I saw that Google posted that 1.5 is available now for developers but it looks like many developers are having issues with it. I think it'll be a great release once the bugs are worked out. My guess is that many people are simply doing something wrong, but I haven't tried it myself yet. I plan to finish Light Racer 2.0 on 1.1, then start testing against 1.5 before the release and do all of Light Racer 3D against 1.5.
re: Getting Started in Android Game Development
Hi Mr. robert.. your article is very inspiring... thank you very much.. it's a good thing that there are people like you who are very willing to reach out other programmers... my best regards....
re: Getting Started in Android Game Development
Seems to be good. I have tried all this in the emulator. I doubt whether the application will be faster in the phone. When I tried adding sdcard to the emulator, I can sense the slow performance of my app..Smith
re: Getting Started in Android Game Development
You can find more info on implementing game loops in my "Game Loop" article athttp://dewitters.koonsolo.com/gameloop.html
re: Getting Started in Android Game Development
A very good introduction, thank you! I would like to request a second article, if you are interested. Perhaps in the second article you could go some more into the details of making your MIDlet talk to your main loop thread, the interactions.I have been working on a mobile Java project for some time, and if someone had had an article or tutorial covering the program flow like this, it would have been very helpful.For example, I ended up making a Class that implements Runnable, then in my MIDlet I start a new Thread and feed it my Runnable. As in: Thread MyThread = new Thread(MyRunnable);. Of course this avoids using the synchronized wait notify paradigm.Thanks again :)
re: Getting Started in Android Game Development
Great article!Highlights a lot of fundamentals that may not be obvious to beginners, particularly the details of the main loop.Keep them coming!
re: Getting Started in Android Game Development
ldso: This is an article about Android, not Java ME. There are no MIDlets in Android (which doesn't support Java ME).
re: Getting Started in Android Game Development
Whoa! That's one VERY informative post. I still have to get the Android SDK run without hitches on Netbeans (on Ubuntu 8.10). Once I've done that, I'll surely try out those tips. Thanks!
re: Getting Started in Android Game Development
I have been on a quest to find good information about writing applications in Android. I must say how much I appreciate the mind dump that you did. What a wealth of information in one short article. I general I am disappointed in the material that out there as far as developing in Android. Glad to see someone put something out there with some substance. Looking forward to your next article.
re: Getting Started in Android Game Development
Great article, thanks for all the information!My team is looking for a graphic designer to come on board and help us finish a simple game application we are developing, does anyone know someone they could recommend?Thanks!@Scottmunc
Great article! The links to
Great article! The links to the Android development information is great. Since this is also a game development blog though, can you link to a good 2D game development book. That would bridge the gap and make this article perfect.
IE: You showed us some awesome Android references and tutorials, but what about some awesome game development books / references so we have everything we need to start building a basic game?
Thanks!
L
Excellent understanding.
Thank you for your written expression and giving us a chance to improve android's market with your experience as a developer.
I'm currently building my first app for the android G1 market.
I've encounter problems until I read your post.
other than that, I hope I can finish my app without any errors.
Other Books
I've had a few different books over the years that I have learned from but I believe the most valuable one as far as general game programming was Game Coding Complete. There are a few others that give you some low-level tips like how to write really fast pixel-handling code and such but none of that really matters when targeting Android.
Post new comment