// Enqueue an asset from a remote URL
assets.enqueue("https://example.com/img/starling.jpg");
// Enqueue an asset from disk (native targets only)
var appDir:File = File.applicationDirectory;
assets.enqueue(appDir.resolvePath("sounds/music.mp3"));
// Enqueue all contents of a directory, recursively (native targets only).
assets.enqueue(appDir.resolvePath("textures"));
Asset Management
One thing should be clear by now: textures make up a big part of every application’s resources. Especially when we are talking about games, there is a lot to manage; from the user interface to the characters, items, backgrounds, etc. But that’s not all: you will probably need to deal with sounds and configuration files, too.
For referencing these assets, you’ve got several choices.
-
Add them to the Lime project.xml file (via the
<assets>
tag). -
Load them from disk (only possible for native applications).
-
Load them from an URL, e.g. from a webserver.
Since every option requires different code (depending on the asset type and loading mechanism), it’s difficult to access the assets in a uniform way. Thankfully, Starling contains a class that helps you with that: the AssetManager.
It supports the following types of assets:
-
Textures (either from Bitmaps or ATF data)
-
Texture atlases
-
Bitmap Fonts
-
Sounds
-
XML data
-
JSON data
-
ByteArrays
To accomplish this, the AssetManager uses a three-step approach:
-
You add pointers to your assets to a queue, e.g.
File
objects or URLs. -
You tell the AssetManager to process the queue.
-
As soon as the queue finishes processing, you can access all assets with corresponding
get
methods.
The AssetManager contains a |
AssetManager versions
Starling 2.4 features a new, much enhanced AssetManager. All the code examples that follow were written with this new version in mind.
The new AssetManager class can be found in the starling.assets
package.
For compatibility reasons, the old version is still available at its previous location (in starling.utils
), but it’s now marked as deprecated.
Upgrading to the new version should be really painless — the changes in the public API were kept at a minimum.
In exchange, you can profit from the new version’s much higher flexibility.
Enqueuing the Assets
The first step is to enqueue all the assets you want to use. How that’s done exactly depends on the type and origin of each asset.
Assets from disk or from the network
Enqueuing files from disk or from a remote server is rather straight-forward:
To load a texture atlas, just enqueue both its XML file and the corresponding texture.
Make sure that the imagePath
attribute in the XML file contains the correct filename, because that’s what the AssetManager will look for when it creates the atlas later.
assets.enqueue(appDir.resolvePath("textures/atlas.xml"));
assets.enqueue(appDir.resolvePath("textures/atlas.png"));
Bitmap Fonts work just the same.
In this case, you need to make sure that the file
attribute in the XML (the .fnt
file) is set up correctly.
assets.enqueue(appDir.resolvePath("fonts/desyrel.fnt"));
assets.enqueue(appDir.resolvePath("fonts/desyrel.png"));
Per-Asset Configuration
When you create a texture manually (via the Texture.from…()
factory methods), you’ve got a chance to fine-tune how it is created.
For example, you can decide on a texture format or scale factor.
The problem with those settings: once the texture is created, you cannot change them any more. So you need to make sure the correct settings are applied right when the texture is created. The asset manager supports this kind of configuration, too:
var assets:AssetManager = new AssetManager();
assets.textureOptions.format = Context3DTextureFormat.BGRA_PACKED;
assets.textureOptions.scale = 2;
assets.enqueue(EmbeddedAssets);
The asset manager will adhere to these settings for all the textures it creates.
However, it seems that this would only allow one set of properties for all the loaded textures, right?
Actually, no: you just need to enqueue them in several steps, assigning the right settings prior to each call to enqueue
.
assets.textureOptions.scale = 1;
assets.enqueue(appDir.resolvePath("textures/1x"));
assets.textureOptions.scale = 2;
assets.enqueue(appDir.resolvePath("textures/2x"));
This will make the textures from the 1x
and 2x
folders use scale factors of one and two, respectively.
Loading the Assets
Now that the assets are enqueued, you can load all of them at once. Depending on the number and size of assets you are loading, this can take a while.
The loadQueue
method accepts up to three different parameters, with separate callbacks for completion, error handling and progress.
Only the first parameter (onComplete
) is obligatory.
assets.loadQueue(onComplete, onError, onProgress);
function onComplete():Void { trace("done!"); } (1)
function onError(error:String):Void { trace("error:", error); } (2)
function onProgress(ratio:Float):Void { trace("progress:", ratio); } (3)
1 | You can always rely on onComplete to be called once at the very end. |
2 | onError may be executed multiple times (once for every asset that can’t be loaded). |
3 | Use onProgress if you want to show some kind of progress bar or loading indicator. |
That’s the one part where you need to be careful when migrating to the new AssetManager.
Previously, there was just a single callback parameter in the |
With an enabled verbose
property, you’ll see the names with which the assets can be accessed.
[AssetManager] Adding sound 'explosion' [AssetManager] Adding texture 'bird' [AssetManager] Adding texture 'atlas' [AssetManager] Adding texture atlas 'atlas'
Accessing the Assets
Finally: now that the queue finished processing, you can access your assets with the various get…
methods of the AssetManager.
Each asset is referenced by a name, which is the file name of the asset (without extension) or the class name of embedded objects.
var texture:Texture = assets.getTexture("bird"); (1)
var textures:Vector<Texture> = assets.getTextures("animation"); (2)
var explosion:SoundChannel = assets.playSound("explosion"); (3)
1 | This will first search named textures, then atlases. |
2 | Same as above, but returns all (sub) textures starting with the given String. |
3 | Plays a sound and returns the SoundChannel that controls it. |
If you enqueued a bitmap font along the way, it will already be registered and ready to use.
In my games, I typically store a reference to the asset manager at my root class, accessible through a |