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\$
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

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ i don't have super.render() i use Screen not Standar class, don't work this with screens \$\endgroup\$ – Mr. Developer Dec 14 '15 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\$ – RuslanK Dec 14 '15 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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ i don't have super.render() i use Screen not Standar class, don't work this with screens \$\endgroup\$ – Mr. Developer Dec 14 '15 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 Dec 14 '15 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.