Zack February 2016

Libgdx: How can I load assets after screen has already rendered?

I have implemented the loading screen from this example on my Loading Screen that is a child of Game. This is how my asset init method and Screen class looks like. My init method in assets loads classes that contain my AtlasRegion. I have tested that this method is what makes my screen load a black screen as it loads a lot of resources.

    public void init (AssetManager assetManager) {
    this.assetManager = assetManager;
    // set asset manager error handler
    assetManager.setErrorListener(this);

    assetManager.load(Constants.TEXTURE_ATLAS_OBJECTS, TextureAtlas.class);
    assetManager.load(Constants.TEXTURE_ATLAS_UI, TextureAtlas.class);
    assetManager.finishLoading();

    TextureAtlas atlas = assetManager.get(Constants.TEXTURE_ATLAS_OBJECTS);
    TextureAtlas atlasUi = assetManager.get(Constants.TEXTURE_ATLAS_UI);

    //font = new BitmapFont(Gdx.files.internal("data/font.fnt"), Gdx.files.internal("data/font.png"), false);

    clickSound = Gdx.audio.newSound(Gdx.files.internal("data/sounds/click.wav"));

    // create game resource objects
    fonts = new AssetFonts(assetManager);
    skins = new AssetSkins();
    background = new AssetBackgroundImage();
    cards = new AssetCards(atlas);
    cardimages = new AssetImages(atlas);
    cardsjson = new AssetList();
    suitimages = new AssetSuitImages(atlas);
}

This is my Loading Screen class:

    public class LoadingScreen extends AbstractGameScreen implements Disposable {

    private Stage stage;

    private Image logo;
    private Image loadingFrame;
    private Image loadingBarHidden;
    private Image screenBg;
    private Image loadingBg;

    private float startX, endX;
    private float percent;

    private Actor loadingBar;

    public LoadingScreen(CardGame game) {
        super(game);
    }

    public InputProcessor getInputProcessor () {
        return (null)        

Answers


Tenfour04 February 2016

Remove the finishLoading call from your init method. That should do it. finishLoading forces the assets to finish loading immediately which is not what you want here. Calling update on it repeatedly, which you are already doing is the way to load assets asynchronously.

Here's a general structure for how it could be done. Call all the load methods on the asset manager before it ever gets to the render method. Then call update repeatedly until everything is loaded. Then get references to the assets before continuing.

private boolean loadComplete;

public void show(){
    //...
    loadComplete = false;
}

private void init(AssetManager assetManager){
    this.assetManager = assetManager;
    assetManager.load(/*whatever*/);
    assetManager.load(/*whatever*/);
    assetManager.load(/*whatever*/);
}

private void onAssetsLoaded(){
    loadComplete = true;
    myAtlas = assetManager.get("myAtlas.json", TextureAtlas.class);
    //and so on
}

public void render(float delta){
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    //load one asset at a time per frame until loading is complete
    if (assetManager == null || !assetManager.update()){
        //maybe draw a load screen image that's not a texture that's being managed 
        //by the assetManager. You could even play an animation. Otherwise, 
        //you can leave the screen blank.

        return;
    }

    //will only get here when asset manager is done. The first time, you still
    //need to get references to its assets
    if (!loadComplete)
        onAssetsLoaded();

    //the rest of you render method. Everything below here only happens after assets are loaded and asset references have been aquired

}


Zack March 2016

After trying so many recommended solutions, I finally managed to fix this problem thanks to this blog post

I used a callback which displays an android framelayout with an image as the assets load asynchronously.

Post Status

Asked in February 2016
Viewed 2,816 times
Voted 7
Answered 2 times

Search




Leave an answer