Loading and preparing assets via AssetProvider
To load and prepare assets we have some handy delegates that AssetProviders
provides that handles all of the hard work for us. This also prevents us from having to use var
as a null or lateinit var
. Note: We can not access any of these variables in the class’s init
method or else we will get an exception for accessing too early. The Game
class provides a create
class which can be used similarly.
We must first create a provider:
val provider = AssetProvider(context)
Loading an asset we can use the load
method with returns a GameAsset
object which can be used as a delegate to access that actual asset we need, which in this case is the Texture
.
val texture by provider.load<Texture>(resourcesVfs["texture.png"])
This loads a Texture
via a delegate and assigns it to the texture
variable. Great! Now if you are thinking how can use a top level variable that requires this texture to be loaded and prepared, such needing a slice from it. Well not to fret, we also have a delegate for that too!
If we need a top level variable, and need to avoid null
and lateinit var
we can use the prepare
method.
val texture by provider.load<Texture>(resourcesVfs["texture.png"])
val slices by provider.prepare<TextureSlice> { texture.slice(16, 16) }
The prepare
method is essentially the same as the Kotlin’s lazy
delegate but will prepare each asset once all other assets have finished loading.
We can check if the AssetProvider
has finished loading by using the isFullyLoaded
property. We need to make sure we call update()
in the render loop in order ensure the assets are finished loading and fully prepared.
class MyGame(context: Context) : ContextListener(context) {
val provider = AssetProvider(context)
val texture by provider.load<Texture>(resourcesVfs["texture.png"]) // loads on a separate thread
val slices by provider.prepare<TextureSlice> { texture.slice(16, 16) }
override suspend fun Context.start() {
// access any of the variables from above
// do any of the rendering and update logic here
onUpdate {
if(!provider.isFullyLoaded) {
provider.update()
return
}
// We are loading now! Do whatever logic we need to do here.
// e.g. render pass setup and such
}
}
}