Android Development Tools R17 break your Libgdx Project?

Some kind folks on the forums informed me that the latest Android ADT plugin breaks libgdx projects. The reason for this is that an Android Eclipse project no longer adds the sources of referenced Java projects to the APK it compiles. Why they had to do this is beyond me, the fix is simple however.

  • Click on your Android Project
  • Select Properties
  • Select Java Build Path
  • Select Order and Export
  • Check all your references, e.g. the gdx.jar, the gdx-backend-android.jar, your main code project etc.

That’s it. Here’s a before and after image for a project that uses the jars.


You don’t necessarily have to check the .jar files in this case if they are in your Android project’s libs/ folder.

If you run from SVN, just check the referenced gdx and gdx-backend-android project in the same settings dialog.

Now i have to redo all the tutorials…

Libgdx HTML5 Backend Update

I spent almost a week and a half on the HTML5 backend now and i’m happy to say that i could actually add more than i expected.

New Additions

  • Reflection. Yes, that’s a stupid idea with GWT, but it enables a few things. You can’t use it for your own apps at the moment. Not sure i’ll open up that can of worms. If you are interested in how it works, check out this bozo.
  • Json parsing with reflection. If you read into an ObjectMap things will just work. If you want to deserialize into your own POJOs i’ll have to add something so your POJOs are reflected.
  • The entire scene2d package, including the UI stuff. This was enabled by adding basic Reflection capabilities
  • All of Box2D works now, expect for GearJoint, WheelJoint and RopeJoint. The former two are currently broken in the JBox2D trunk, once those are fixed we have everything apart from RopeJoint.
  • Preferences
  • Fullscreen support
  • Tons of other stuff under the hood that won’t affect you
  • Binary file support, altough i recommend not using it, it’s slow by nature

You can try out most of our tests in HTML5 now. Some box2d tests might be slow due to ShapeRenderer. The box2d simulation itself runs blazingly fast 🙂

Todo

  • Replace gwt-voices with something else, e.g. a Sound Manager 2 wrapper. I didn’t dig into the gwt-voices sources to much, but for some reason it refuses to work at all in Safari and partially in Firefox. Done, custom wrapper around SoundManager 2, a fantastic API that works perfectly.
  • Fix the backspace button problem so UI textfields work. Done
  • Add a very simple HttpUtils class that allows one to send POST/GET requests to a server. Note that due to the “Same Origin Policy” you’ll be restricted to send requests to the domain your app/game is hosted on.
  • Go through the list of FIXMEs in the source. Done, anything that’s marked as FIXME is either undoable for now, or non-critical.

I’ll most likely not support local files for the time being. Preferences should be sufficient for most games for now.

What Won’t Work

Tilemaps, Audio recorder/device, that’s about it. If i can find a nice Gzip decoder for GWT we can add Tilemaps in as well. Other than that we’ll be pretty much feature complete.

Simple Tutorial

I didn’t have time to write a tutorial on how to port your game yet. Here’s a nice tutorial by Molded Bits on how to get started with the new backend. The markers for files in the assets.txt file are: i -> image, t -> text file, b -> binary file. For now i won’t pack the backend jar with the nightlies as i want things to mature a tiny bit. I’ll follow up with something more in depth that will also show you how you can debug the emitted Javascript easily if necessary.

Ports

Here are a few recent ports.

Pax Britannica by Stefan Wagner.

Mathematiles by Nex

Vector Pinball (see libgdx trunk/demos/)

Gdx invaders (see libgdx trunk/demos/)

AssetManager explained

A long time ago i promised to write an article on our AssetManager. Well, today i finally found the time, so here we go.

Why would i want to use the AssetManager?

If your game is very simple, and loading resources doesn’t take a lot of time you don’t want to use the AssetManager. In all other cases i’d recomend using it due to the following nice behaviours:

  • Loading of most resources is done asnychronously, so you can display a reactive loading screen while things load
  • Assets are reference counted. If two assets A and B both depend on another asset C, C won’t be disposed until A, B and C have been disposed. This also means that if you load an asset multiple times, it will actually be shared and only take up memory once!
  • A single place to store all your assets.
  • Allows to transparently implement things like caches (see FileHandleResolver below)

Still with me? Then read on.

Creating an AssetManager

This part is rather simple:

This sets up a standard AssetManager, with all the loaders libgdx has in store at the moment. Let’s see how the loading mechanism works.

Loading Assets

To load assets, the AssetManager needs to know how to load a specific type of asset. This functionality is implemented via AssetLoaders. There’s two variants, SynchronourAssetLoader and AsynchronousAssetLoader. The former loads everything on the rendering thread, the later loads parts of the asset on another thread, e.g. the Pixmap needed for a Texture, and then loads the OpenGL dependent part on the rendering thread. The following resources can be loaded out of the box with the AssetManager as constructed above.

  • Pixmaps via PixmapLoader
  • Textures via TextureLoader
  • BitmapFonts via BitmapFontLoader
  • TextureAtlases via TextureAtlasLoader
  • TiledAtlases via TiledAtlasLoader
  • TileMapRenderers via TileMapRendererLoader
  • Music instances via MusicLoader
  • Sound instances via SoundLoader

Loading a specific asset is simple:

These calls will enqueue those assets for loading. The assets will be loaded in the order we called the AssetManager#load() method. Some loaders allow you to also pass parameters to them via AssetManager#load(). Say we want to specify a non-default filter and mipmapping setting for loading a texture:

Look into the loaders mentioned above to find out about their parameters.

So far we only enqueued assets to be loaded. The AssetManager does not yet load anything. To kick this off we have to call AssetManager#update() continuously, say in our ApplicationListener#render() method:

As long as AssetManager#update() returns false you know it’s still loading assets. To poll the concrete state of loading you can use AssetManager#getProgress(), which returns a number between 0 and 1 indicating the percentage of assets loaded so far. There are other methods in AssetManager that give you similar information, like AssetManager#getLoadedAssets() or AssetManager#getQueuedAssets(). You have to call AssetManager#update() to keep loading!

If you want to block and make sure all assets are loaded you can call:

This will block until all the assets that have been enqueued are actually done loading. Kinda defeats the purpose of asynchronous loading, but sometimes one might need it (e.g. loading the assets needed to display the loading screen itself).

Getting Assets

That’s again easy:

This of course assumes that those assets have been successfully loaded. If we want to poll whether a specific asset has been loaded we can do the following:

Disposing Assets

Easy again, and here you can see the real power of the AssetManager:

If that font references a Texture that you loaded manually before, the texture won’t get destroyed! It will be reference counted, getting one reference from the bitmap font and another from itself. As long as this count is not zero, the texture won’t be disposed.

Assets managed via the AssetManager shouldn’t be disposed manually, instead call AssetManager#unload()!

If you want to get rid of all assets at once you can call:

or

Both will dispose all currently loaded assets and remove any queued and not yet loaded assets. The AssetManager#dispose() method will also kill the AssetManager itself. After a call to this method you should not use the manager anymore.

And that’s pretty much everything there is. Now for the nitty gritty parts.

I only supply Strings, where does the AssetManager load the assets from?

Every loader has a reference to a FileHandleResolver. That’s a simple interface looking like this:

By default, every loader uses an InternalFileHandleResolver. That will return a FileHandle pointing at an internal file (just like Gdx.files.internal(“data/mytexture.png”). You can write your own resolvers! Look into the assets/loaders/resolvers package for more FileHandleResolver implementation. One use case for this would be a caching system, where you check if you have a newer version downloaded to the external storage first, and fall back to the internal storage if it’s not available. The possibilities are endless.

You can set the FileHandleResolver to be used via the second constructor of AssetManager:

This will make sure all default loaders listed above will use that loader.

Writting your own Loaders

I can’t anticipate which other types of resources you want to load, so at some point you might want to write your own loaders. There are two interfaces called SynchronousAssetLoader and AsynchronousAssetLoader you can implement. Use the former if your asset type is fast to load, use the later if you want your loading screen to be responsive. I suggest basing your loader on the code of one of the loaders listed above. Look into MusicLoader for a simple SynchronousAssetLoader, look into PixmapLoader for a simple AsynchronousAssetLoader. BitmapFontLoader is a good example of an asynchronous loader that also has depdendencies that need to be loaded before the actual asset can be loaded (in that case it’s the texture storing the glyphs). Again, you can do pretty much anything with this.

Once you are done writting your loader, tell the AssetManager about it:

Resuming with a Loading Screen

On Android your app can be paused and resumed. Managed OpenGL resources like Textures need to be reloaded in that case, which can take a bit of time. If you want to display a loading screen on resume, you can do the following after you created your AssetManager.

In your ApplicationListener#resume() method you can then switch to your loading screen and call AssetManager#update() again until everything is back to normal.

If you don’t set the AssetManager as shown in the last snippet, the usual managed texture mechanism will kick in, so you don’t have to worry about anything.

And this concludes the long awaited article on the AssetManager.