Introduction
The last couple of years a lot of cross-platform game frameworks have
emerged. These frameworks came to fill a gap that due to the growing
interest for mobile games and the diversity of the platforms kept
getting bigger and bigger. And today is easier than ever before to adopt
a game engine and develop your first game. The most difficult part is
to select the proper gaming framework. However, from all the available
options there is one that clearly stands out:
libgdx. These are some of the features of libgdx that make it one of a kind:
- Cross platform: Deploys on Desktop, Android, HTLM5 and iOS (with the aid of RoboVM)
- You can debug and test your game in a desktop environment and then deploy it for the Android platform with almost zero effort.
- Great performance
- Good documentation, excellent community support
- Many features for 2D and 3D games.
- Friendly Open Source license (Apache 2.0). It can be freely used for commercial applications.
In this article I am going to provide an overview of the libgdx. A
simple 2D game, called "Fruit Catcher" will be used as an example. In
this game fruits fall off the sky. You carry a basket and you move it
around, either by touching the screen or sliding your phone, to catch
them. To make it more interesting seasonal fruits worth more points. You
of course know that you must prefer seasonal fruits! Since, as I said,
libdgx documentation is very good, I am not going to cover basic
information here. You can read how to set up and run a project in the
Wiki. You can also read how to create a
simple game and how to extend it to use
Game Screens.
Here I am going to cover some important game concepts and also provide
tips that will help you move from a sample game to one that is ready to
be deployed in the market. Although libgdx is a cross-platform
framework, emphasis will be given on deploying for the Android platform.
Before starting writing code however, we must cover two topics that are important for game designing.
Game Resources
I suspect that most of you reading this are developers and not
designers. In my opinion however creating a game is more an art than a
development process. Great games usually stand out because of their good
graphics and nice sound and music. That doesn't mean that a single
developer has no luck of creating a game. It is difficult for a
developer to create all the resources from scratch, but it is much
easier to locate the appropriate resources online and then use the
appropriate tools to adapt them. And because no one that reads this is a
lawyer, this a list of URLs that provide resources you can freely use
in your games:
- Images: Openclipart. Public domain SVG graphics.
- Sounds: freesound. Creative Commons Licensed sounds. Pay attention to the individual sound license.
- Fonts: Font Squirrel. It
may come as a surprise, but you can't use native fonts in your games.
Font Squirrel provides fonts that are free for commercial use. libgdx
provides a tool that will allow you to easily integrate these fonts.
This list is of course not exhaustive. There are other resource
centers as well. When searching however, take note of the license. Do
not just use the first image you find in the Web. You need to make sure
you have the right the use it. Also, the above list doesn't cover other
types of resources, such as 3D models.
Tools
After you have found the appropriate resources online (or having paid
a designer to create them for you), you are still not ready to start
coding. Most of the times the resources will need some editing. There is
a basic level of designing that you can avoid doing. The good thing is
that this kind of design is actually fun and that are free tools you can
use:
- Inkscape: Professional vector
graphics editor. It is good to design all your images in a vector
format. This will allow you to easily resize them for any current or
future screen resolution.
- Gimp: Image manipulation program.
It has similar features to Photoshop. Most game engines require bitmap
(usually PNG) images. After exporting an image from Inkscape, you may
need to do some final touching before incorporating into your games.
Gimp's UI isn't that user friendly and requires some time to getting
used to. However Gimp is feature-full and there are many tutorials and
videos available online.
- Audacity: Cross-platform software for recording and editing sounds.
All the above tools are free, open-source and of a professional
level. They are more than enough for any task you are going to need.
Besides the above general tools, there are also many game specific
tools. There are tools for creating bitmap fonts, tools for packing many
small images to a big one, tools for creating tile maps. libgdx has
good support for this king of tools and some of them will be presented
later in this article.
Game Main Loop
Games do have some software design patterns of their own. The most
ubiquitous of them is of course the game loop. I am sure you have heard
of it. The game loop is actually a while-loop, where all the processing
is taking place. In this loop you display all images, play sounds, apply
physics and game logic. You try to do that as fast as possible. When
the loop is finished, it immediately starts over again. The number of
times the loop runs in one second equates to "Frame per seconds" (FPS).
The highest the FPS is, the more smooth the game will appear to be.
Most game frameworks implement the game loop by providing a function
(or method). This method does all the processing and the framework takes
care of calling it as fast as possible. Let's call this method the
"Loop method". The "Loop method" in pseudo-code is presented below:
void gameMain(float delta) {
renderWorld();
getUserInput();
update(delta);
}
This pseudo-code also relates to the well known MVC pattern, which is
also popular in game development. The "Loop method" accepts a single
float argument. This is called delta and is actually the time passed
since the last time the loop method was called. You can think of it as
the inverse of FPS. That is: delta = 1 / FPS.
The renderWorld method renders all images on the screen. This is the
"View" of the game that draws all images in the appropriate locations.
All images are drawn every time the loop runs, even if their position
hasn't changed. Next the loop reads the user input. This may come from
the touch screen, a keyboard, a mouse, the accelerormeter, a gaming
pad... Although above it appears to be part of the loop method, it is
more common to be implemented as a separate class (the "Controller")
that updates the "Model". The last part applies the physics and the game
logic. This is where the delta information is needed. The game may
require a full physics engine or just some simple object movement and
collision detection. In any case a timing information is needed to
implement this. In this part stuff like updating the score and checking
game over conditions will take place. If you have worked with XNA or
MonoGame, you may find this part similar to the Update method. This
method actually updates the "Model" or state of the game. In MonoGame
special consideration is taken so that the Update method is called in
regular intervals, regardless of how long the rendering is taking to
execute. In other words the framework always calls the update method,
which shouldn't take long to execute, a specific number of times per
second and then uses the remaining time to render the world as
frequently as possible. libgdx doesn't support a separate update method.
Therefore you should implement this pattern yourselves. If the
renderWorld takes too long to execute (lower-end device, too many
objects to render), it shouldn't be called in every loop, so that the
update method is regularly called and the game state remains consistent.
If you fail to do so, you may find yourself in a situation where
objects fly through obstacles and all kind of strange things happen.
libgdx supports the game main loop pattern through the
ApplicationListener interface. This interface defines the following methods:
void create() void dispose() void pause() void render() void resize(int width, int height) void resume()
The above methods provide entry points for all events you are going
to need to handle in a game's lifecycle. The render method is the main
loop method, we have described above. libgdx provides static constructs
to read the delta time (
Gdx.graphics.getDeltaTime()) and process user input (
Gdx.input).
Although you can process input directly from inside the render method,
libgdx also provides more advanced mechanisms that allow you to
implement a separate Controller class (
InputProcessor). As explained above a separate update method isn't provided and you would need to implement this pattern yourselves.
From the other ApplicationListener methods the create and dispose
methods are very important for the game resources handling. Since in
your games you are going to deal a lot with OpenGL resources, garbage
collection won't help and you would need to manually dispose of them. We
usually allocate resources for the game in the create method. This is
called only once, when the game is started. In the dispose method we
have our chance to dispose of these resources. Resource handling is of
course usually more complicated than this. In order to start a game
quickly and avoid out of memory errors, a more complex resource handling
is needed. You may need to pre-allocate some resources and de-allocate
some of them earlier in low memory conditions. We'll discuss more on
this later.
Game Screens
The image below displays the screens of a typical game. The game
consists of various screens. Every time only a single screen is being
displayed. When developing a game it is very convenient to be able to
think in terms of these screens. First implement the initial menu
screen, then the game start screen, the main game screen (which is
usually the most difficult one), the game over screen and so on.

libgdx supports this pattern through the
Game abstract class and the
Screen interface.
This is a very thin construct and you need to provide implementations
both for the Game and the Screen objects. The Game class is nothing more
than an ApplicationListener that delegates the rendering to one or more
screen objects. This makes it easier to think in Screen terms. It also
makes resource handling easier. The Screen interface provides a dispose
method, which however isn't called automatically. You should call it
yourselves in order to dispose of the screen's resources. This is a good
thing, because it allows a more flexible resource handling. A screen
may remain pre-loaded so that it can be re-used quickly. In general this
pattern will allow you to implement a resource handling service. This
service will pre-load resources and it will dispose of the resources
that aren't going to be used shortly. For example when going from Level 1
to Level 2, you need to dispose of the Level 1 resources and pre-load
the Level 2 ones, while still in the Level screen. A separate service
class will be responsible for loading and unloading resources. The Game
Screen pattern makes it easy to invoke this service at the appropriate
times.
If you look at the game screens, you will definitely notice that most
of them are very simple. With the exception of the action screen, all
screens just display a message and offer a couple of action points for
the users. They are only simple UIs. libgdx provides
Scene2d in order to facilitate the creation of such screens. Copying from the libgdx Wiki:
scene2d is well equipped for laying out, drawing, and handling
input for game menus, HUD overlays, tools, and other UIs. The scene2d.ui
package provides many actors and other utilities specifically for
building UIs.
I haven't personally used Scene2d in Fruit Catcher, but I believe that you should consider it for your own applications.
Rendering Images
The following code snippet displays what you need to do in order to
render an image to the screen (It is taken from the simple game example
in libgdx wiki). First you need to create a camera and a SpriteBatch
object in the create method. There you also create Texture objects that
you load images in them. In the render method you use the SpriteBatch
object to draw the textures. You must not forget to dispose of the
textures and the SpriteBatch objects in the dispose method.
Collapse 
|
Copy Code
Texture bucketImage;
OrthographicCamera camera;
SpriteBatch batch;
@Override
public void create() {
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
batch = new SpriteBatch();
dropImage = new Texture(Gdx.files.internal("droplet.png"));
...
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(bucketImage, bucket.x, bucket.y);
batch.end();
}
@Override
public void dispose() {
bucketImage.dispose();
batch.dispose();
...
}
Drawing images with libgdx is easy. (If you believe that the above
code is complicated, you should do a research about drawing images with
OpenGL without the aid of a framework). However, the above code is only
appropriate for very simple games. In real situations you would need to
add a couple of abstraction layers to your image drawing code.
First of all, if you have a lot of small images, you shouldn't load
them one by one. Instead, you should "pack" them into a big image, load
this image into a Texture and then select regions from it. The image
below depicts the small images in Fruit Catcher all packed into a single
one.

libgdx makes it very easy to create packed images. You can do that
straight from the desktop project. All you have to do is to add the
gdx-tools.jar in the classpath and write a couple of lines of code. This
is how I do it in Fruit Catcher. I define the maximum height and width
to be 1024. If the images do not fit in one 1024x1024 image, more than
one will be created. This will be completely transparent for you, as the
code to select a region won't change. The TexturePacker2.process takes
all the images from a specific folder, packs them and copies the packed
images to the Android project assets folder. It also creates an "atlas"
file. This is a simple text file, which contains the locations of the
individual images into the packed one. In Fruit Catcher three "atlases"
are created: one for the small images, one for text images in English,
and one for text images in German.
Settings settings = new Settings();
settings.maxWidth = 1024;
settings.maxHeight = 1024;
TexturePacker2.process(settings, "images", "../FruitCatcher-android/assets", "game");
TexturePacker2.process(settings, "text-images", "../FruitCatcher-android/assets", "text_images");
TexturePacker2.process(settings, "text-images-de", "../FruitCatcher-android/assets", "text_images_de");
After you have called the above code, you need to refresh the Android
project in order for the changes to be picked up. Also, you should pay
attention to a naming convention the TexturePacker2 utility uses in
order to support animations. You can name a series of images like this:
image_n.png,
where n is an integer. Number n actually denotes the frame index. If
you have a sprite that consists of a number of frames, this convention
will make it easy to load these frames.
TextureAtlas atlas = new TextureAtlas(Gdx.files.internal("game.atlas"));
TextureRegion startTexture1 = atlas.findRegion("star", 1);
TextureRegion startTexture2 = atlas.findRegion("star", 2);
TextureRegion buttonTexture = atlas.findRegion("button");
In complex games, with a lot of images, it may take considerable time
to load all the images. What games usually do is to display a "loading"
screen in the beginning and start loading the images and other required
assets. When everything is loaded, the game can start. There is a delay
at the start, which the users can put up with and then the game runs
smoothly. libgdx supports this pattern with the aid of
AssetManager.
As you've seen loading images isn't so simple in real applications.
You may need to use an AssetManager, a TexturePacker or both. You may
also need to implement a custom loading and unloading scheme that runs
in the in-between screens of your game. For these reasons, I believe
that it would be better to create a separate service that will provide
all images to other code layers. I call this service
ImageProvider
in Fruit Catcher. Having this service will allow you to experiment with
different loading and unloading techniques without affecting the whole
source base. It would really pay off, if you design your game like this
from the beginning.
Rendering Text
If you have never developed a game before, it may come as a surprise
that special consideration is needed in order to display text. However,
you should understand that for performance reasons gaming frameworks use
OpenGL and there is no way to combine this with native code that can
use system fonts. Luckily, libgdx makes it very easy to create a bitmap
font and then use it in your application. libgdx has adopted the
Hiero Bitmap Font Tool.
This is an open source tool. Previously it was difficult to find a
working version of it. Now libgdx maintains it as a tool and you can run
it straight from libgdx binaries. Hiero can load any system font and
convert into a bitmap font, in a format that libgdx understands. It can
also load TTF fonts directly, without having to install them. When
working with Hiero pay attention to the license. Only use fonts that you
have the right to do so. After you have created the bitmap font, it is
very easy to load it and then use it to display text.
BitmapFont font = new BitmapFont(Gdx.files.internal("fonts/poetsen.fnt"),
Gdx.files.internal("fonts/poetsen.png"), false);
font.draw(spriteBatch, line_string, lineX, lineY);
State
Something that you may not realize from the beginning, is that your
game must be able to store its state and then resume from it. This is
especially important in mobile devices that may be interrupted from a
phone call. When the player returns to the game after an interruption,
she would expect to find it in the state she had left it. If she was
about to achieve a high score and finds out she has to start from the
beginning, she would be angry and you should expect some very negative
reviews.
Your game must be able to start from the beginning and from a well
known state as well. The game must constantly update its state and must
persist it in a non volatile location at appropriate times. libgdx
provides
JSON utilities
that will allow you to serialize and deserialize classes in a
cross-platform way. In Fruit Catcher there are two separate state
classes: GameScreenState that is used to store the state of the current
game (number of points collected, time remaining, fruits in the sky) and
GameState, which holds information about a game session. Both are saved
in the pause method of e game. If you have more complex state objects
that take a lot of time to serialize, you should serialize them in
regular intervals and not wait for the pause method.
Calling Android Native Code
Calling Android native code may be necessary in some situations:
- Displaying ads
- In-app purchases
- Using native user input
- Connecting with leaderboards
In the
Wiki
you can read how to integrate a libgdx game with AdMob. I have used the
described techniques to display AdMob ads in Fruit Catcher. However, I
needed native code also for getting user's name, when a high score is
achieved and for displaying the top 5 of scores. Integration with native
code is actually taking place inside
AndroidApplication
class. This is a class provided by libgdx that extends an Android
Activity. In order to call native code from libgdx you should do the
following:
- Create an interface that defines methods as entry points for actions
that require calling native code. Your implementation of
AndroidApplication will implement this interface. I call this interface
GameEventListener. This interface is part of the libgdx and not of the Android project. It is also accessible from the desktop project as well.
- Your implementation of com.badlogic.gdx.Game will accept a
GameEventListener as an argument constructor. This can be passed as null
for platforms you don't care to implement native functionality. I need
the desktop version of Fruit Catcher for quick debugging and testing. I
don't need however displaying ads and high scores for it. I simply pass a
null GameEventListener for it. In my Game class I check for null,
before calling a GameEventListener method.
- After the above you will have entry points methods in the
AndroidApplication class. These methods will be called by the libgdx
engine. Because libgdx doesn't run in the UI thread you can't access the
UI from them. Instead you need to use a message handler to post
messages that will trigger the appropriate UI action.
Compiling instructions
The zip file at the top of the article doesn't contain the libgdx
binaries (this would have made the zip file too big). However, it is
very easy to add them. Download libgdx and run gdx-setup-ui.jar. This
allows you to create a new project or update an existing one. Click
"Update", select the location, where you have extracted the zip file and
the required files will be added. One thing, that won't be added is the
gdx-tools.jar file. You need to add this manually to the libs folder of
the desktop project.
I have also made the code available in
GitHub. You can clone the repository from there. All required binaries are included. Finally, you can download the game from
Google Play. Please note that this version of the game displays ads. The APK at the top of the page is Ad free.
Summary
If this article was too long for you and you immediately scrolled sown to the bottom, this is a summary.
- libgdx is a cross-platform open source gaming framework that you can use freely in commercial applications.
- libgdx implements the Game Main Loop pattern with the
ApplicationListener interface. It also implements the Game Screens
pattern.
- libgdx makes it easy to render images on the screen. It also
provides tools for packing small images into a large one and loading
images on the background, while displaying a splash screen.
- With libgdx you can embed a bitmap font with a single line of code.
And you can create a bitmap font out of any font installed in your
system with a provided utility.
- Calling native code is usually required (displaying ads, in-app
purchases, native input text, integration with leaderboard services).
- It is necessary to save the state of your game regularly. libgdx makes this easy with a cross-platform json serializer.
History
- 2013/12/28: First submission
- 2014/01/04: Added compiling instructions
License