javalibgdxtexturesloadingasset-management

Unable to draw loading screen in libGDX


I'm currently trying to implement a loading screen for a game.

private enum STATE {
    LOADING, START_MENU, PLAYING, PAUSE, GAME_OVER
}

private STATE state = STATE.LOADING;

These are the game states, so it starts with LOADING, so it can run the LOADING case in the render method.

public void show() {
    startMenuBackground = new Texture(Gdx.files.internal("startMenuBackground.png"));
    startMenuBackgroundSplit = new TextureRegion(startMenuBackground).split(32, 32);
    assetManager = new AssetManager();

    for (int appleImage = 0; appleImage < apple.length; appleImage++)
        assetManager.load("bits/" + appleImage + ".png", Texture.class);

    for (int bodyImage = 0; bodyImage < snakeBody.length; bodyImage++)
        assetManager.load("body/" + bodyImage + ".png", Texture.class);

    for(int backgroundImage = 0; backgroundImage < background.length; backgroundImage++)
        assetManager.load("background/" + backgroundImage + ".png", Texture.class);

    assetManager.load("KappaMan.png", Texture.class);
    assetManager.load("playButton/0.png", Texture.class);
    assetManager.load("playButton/1.png", Texture.class);
    assetManager.load("title.png", Texture.class);
    assetManager.load("AmenoSandstorm.mp3", Music.class);
    assetManager.load("beMad.mp3", Music.class);
    assetManager.load("collide.mp3", Music.class);
    assetManager.finishLoading();

This is the beginning of the show method which loads all assets for the game.

startMenuBackgroundSplit = new TextureRegion(startMenuBackground).split(32, 32);

This is how progress of the game loading is displayed. (I think this is the part that's causing the issue, and the reason the game just renders a black screen.)

case LOADING:
    if (assetManager.update()) {
        state = STATE.START_MENU;
    } else {
        progress = assetManager.getProgress();
        tilesToLoad = 576 * progress;
        tilesY = (int)tilesToLoad / 32;
        tilesX = (int)tilesToLoad % 32;
    }

    break;

Now I begin loading all assets for the game while it runs LOADING. So if it's true, it will go to the START_MENU, if not then it checks the progress. tilesY is the number of rows that I would need to load of the startMenuBackground, tilesX is the number of tiles I'd need to load on the bottom row of what progress there has been of the startMenuBackgroundSplit.

if (state == STATE.LOADING) {
    for (int tilesYLoad = 0; tilesYLoad < tilesY; tilesYLoad++) {
        if(tilesYLoad != tilesY - 1) {
            for(int tilesXLoad = 0; tilesXLoad < 32; tilesXLoad++)
                batch.draw(startMenuBackgroundSplit[tilesXLoad][tilesYLoad], tilesXLoad * 32, tilesYLoad * 32);

        } else {
            for(int tilesXLoad = 0; tilesXLoad < tilesX; tilesXLoad++)
                batch.draw(startMenuBackgroundSplit[tilesXLoad][tilesYLoad], tilesXLoad * 32, tilesYLoad * 32);
        }
    }
}

I have this code which will draw all the relevant tiles depending on the progress of loading all assets.

if (state == STATE.LOADING) {
    layout.setText(loadingFont, LOADING_TEXT);
    loadingFont.draw(batch, LOADING_TEXT, 0, layout.height);
}

There is also this to write loading at the bottom left.

I've commented out the START_MENU state, so I could see the state of the background when it would normally forward the user to the START_MENU screen. It displays the text. Loading..., but it doesn't display the background at all.

I can not tell what I have done wrong. Could I have guidance?


Solution

  • assetManager.finishLoading() blocks until everything is loaded. Which means your show() method will not finish until all your assets are loaded.

    Instead of calling finishLoading(), you should call assetManager.update() inside your render method. This allows your assets to be loaded, but also doesn't block, so your render method can do what you want.

    update() will return false if there are more assets to load, and true when everything is done loading. So you'll need to check the result from each call to update() and proceed accordingly.