Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

libgdx: best way to load all assets in the game

Tags:

java

libgdx

In my play screen has a lot of textures Texture, fonts FreeType, images scene2d.Image and buttons scene2d.Button. So, when I set play screen

((Game) Gdx.app.getApplicationListener()).setScreen(new PlayScreen());

it takes a few seconds to open the screen.

I want to open it quickly, What is the best way to achieve that?

Do I create a new class to create all assets then load them on the screens?

like image 986
iibrahimbakr Avatar asked Nov 11 '15 13:11

iibrahimbakr


1 Answers

You should use the AssetManager. The manager allows you to load your assets when you start the game. It also has the functionality to show you the percentage of assets loaded so you can show a progress bar. There are plenty of sources out there that show you how to use the AssetManager. Some show you examples with a static AssetManager but this is discouraged by badlogic and can cause black images.

You should make a class where you store your assets you want to handle with the manager and the manager will load it asynchronously. I like to work with the AssetDescriptor and using static descriptors to lookup my textures. but there are many different ways you can work with the AssetManager. You can just add a something to the manager like so manager.load("images/sometexture.png, Texture.class); and look it up by doing manager.get("images/sometexture.png"); this way it simple looks up the textures by it's path.

public class Assets {
public AssetManager manager = new AssetManager();

    public static final AssetDescriptor<Texture> someTexture = 
        new AssetDescriptor<Texture>("images/sometexture.png", Texture.class);

public static final AssetDescriptor<TextureAtlas> uiAtlas =
        new AssetDescriptor<TextureAtlas>("ui/uiskin.pack", TextureAtlas.class);

public static final AssetDescriptor<Skin> uiSkin =
        new AssetDescriptor<Skin>("ui/uiskin.json", Skin.class,
                new SkinLoader.SkinParameter("ui/uiskin.pack"));

public void load()
{
    manager.load(someTexture);
    manager.load(uiAtlas);
    manager.load(uiSkin);
}

public void dispose()
{
    manager.dispose();
}
}

In the entry point I create a splash screen with a logo then I start loading my assets. Here is how you load the assets.

public class MyGame extends Game
{
  public void create()
  {
    Assets assets = new Assets();
    assets.manager.load(); //starts loading assets

    //option 1
    assets.manager.finishLoading(); //Continues when done loading.
    //it won't continue until all assets are finished loading.
  }

  //option 2
public void update()
  {
    //draw something nice to look at
    if (manager.update())
    {
      //Assets have finished loading, change screen maybe?
      setScreen(new MenuScreen(assets)); //your screen should take a Assets object in it's constructor.
    }
  }  
}

Perhaps you can load your menu assets like you normally and let the asset manager work while the user is in the menu. That is up to you. This is how you load a asset.

someTexture = assets.manager.get(Assets.someTexture);
atlas = assets.manager.get(Assets.uiAtlas);
skin = assets.manager.get(Assets.uiSkin);

The same rules apply for looking up regions in your atlas, best is to do this a single time for each region in your atlas. You have to pass around the Assets object around to anywhere you need to load assets. It makes it tempting to make it public static but it can cause issues.

like image 76
Madmenyo Avatar answered Nov 06 '22 18:11

Madmenyo