2
\$\begingroup\$

I would like to bring up a loading screen, for this would make the load async. How can I do this? I looked on the libGDX website but I do not understand very well, maybe because of my poor English.

Here's the code :

public void show() {
        stage = new Stage();

        Gdx.input.setInputProcessor(stage);

        loading = new com.badlogic.gdx.scenes.scene2d.ui.Image(new TextureRegion(new Texture(Gdx.files.internal("loading.png"))));
        loading.setPosition(Gdx.graphics.getWidth() / 2 - loading.getWidth() / 2, Gdx.graphics.getHeight() / 2 - loading.getHeight() / 2);
        loading.setOrigin(loading.getWidth() / 2, loading.getHeight() / 2);
        loading.setZIndex(1);

        loading.addAction(rotateTo(1440, 20));

        stage.addActor(loading);

        game.setScreen(game.gameScreen);
    }

What I would do is an async method like this:

asyncmethod()

public asyncmethod()
{
     game.setScreen(game.gameScreen);
}

public void show() {
        stage = new Stage();

        Gdx.input.setInputProcessor(stage);

        loading = new com.badlogic.gdx.scenes.scene2d.ui.Image(new TextureRegion(new Texture(Gdx.files.internal("loading.png"))));
        loading.setPosition(Gdx.graphics.getWidth() / 2 - loading.getWidth() / 2, Gdx.graphics.getHeight() / 2 - loading.getHeight() / 2);
        loading.setOrigin(loading.getWidth() / 2, loading.getHeight() / 2);
        loading.setZIndex(1);

        loading.addAction(rotateTo(1440, 20));

        stage.addActor(loading);

        asyncmethod();
    }
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

In a nutshell you should use power of AssetManager instead of async thread.


public static AssetManager manager = new AssetManager();

public MyAppListener implements ApplicationListener {

    public void create()
    {
        loading = new com.badlogic.gdx.scenes.scene2d.ui.Image(new TextureRegion(new Texture(Gdx.files.internal("loading.png"))));
        loading.setPosition(Gdx.graphics.getWidth() / 2 - loading.getWidth() / 2, Gdx.graphics.getHeight() / 2 - loading.getHeight() / 2);
        loading.setOrigin(loading.getWidth() / 2, loading.getHeight() / 2);
        loading.setZIndex(1);

        loading.addAction(rotateTo(1440, 20));

        stage.addActor(loading);

        // add assets to queue (will be loaded later)
        manager.load("data/mytexture.png", Texture.class);
        manager.load("data/myfont.fnt", BitmapFont.class);
        manager.load("data/mymusic.ogg", Music.class);
    }

    public void render() {

        // loads a part of assets step by step and let you show your loading screen 
        if(manager.update()) {
            // we are done loading, let's move to another screen!
            game.setScreen(game.gameScreen);
            return;
        }

        // display loading information
        super.render();
    }
}

Here is the wiki page - https://github.com/libgdx/libgdx/wiki/Managing-your-assets

\$\endgroup\$
2
  • \$\begingroup\$ i don't have super.render() i use Screen not Standar class, don't work this with screens \$\endgroup\$ Commented Dec 14, 2015 at 13:16
  • \$\begingroup\$ @Mr.Developer it doesn't matter. Just call manager.update() while you are drawing loading screen. Screen has render(float delta) method. \$\endgroup\$
    – sn8p
    Commented Dec 14, 2015 at 15:29
1
\$\begingroup\$

If you wish for your loading screen to be visible whenever an asynchronous process is taking place instead of just regarding asset management, you could always make use the the com.badlogic.gdx.utils.async classes

public class MyAppListener extends Game {

AsyncExecutor asyncExecutor = new AsyncExecutor(10);

AsyncResult<Void> task;

Stage stage;

public void asyncMethod() {
     //do stuff
     setScreen(gameScreen);
}

public void create()
{
    stage = new Stage();

    loading = new Image(new TextureRegion(new Texture(Gdx.files.internal("loading.png"))));
    loading.setPosition(stage.getWidth()/2f, stage.getHeight()/2f, Align.center);
    loading.setOrigin(Align.center);
    loading.setZIndex(1);

    loading.addAction(rotateTo(1440, 20));

    stage.addActor(loading);

    //create our async task that runs our async method
    task = asyncExecutor.submit(new AsyncTask<Void>() {
        public Void call() {
            asyncMethod();
            return null;
        } 
    });
}

public void render() {

    // checks to see if the task is done.  If not draw the load screen
    if(!task.isDone()) {
        stage.act();
        stage.draw();
        return;
    }

    // display the game's current screen
    super.render();
}
}

It's useful to put your load screen within your application listener instead of in a separate Screen object. If you have your load screen as a Screen and change to it, then change it back to the original screen when the task is done, you might enter into an infinite loop as you'll keep going into show and hide methods of each Screen.

The only downside of having the loading screen in your application listener is that it'll always be in memory. However, it's such a small object that having it in memory at all times is a non-issue.

\$\endgroup\$
2
  • \$\begingroup\$ i don't have super.render() i use Screen not Standar class, don't work this with screens \$\endgroup\$ Commented Dec 14, 2015 at 13:16
  • 1
    \$\begingroup\$ As stated in the bottom of my answer, it's recommended that you do not put your load screen into a Screen class. Contain your game's content in a Screen, which is managed and rendered by your game's top level class, which is going to be either the Game class or ApplicationListener class in your project. As a load screen is nothing more than eye-candy and contains no serious logic, just render it directly within your ApplicationListener's render method. \$\endgroup\$
    – nhydock
    Commented Dec 14, 2015 at 14:25

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .