0
\$\begingroup\$

Many tutorials I've seen put the loading of assets via AssetManager in a dedicated screen which displays some progress bar or image while the loading happens in background. Each "real" screen then gets the resources it needs from the asset manager, typically in the constructor, eg

public class GameScreen extends ScreenAdapter {

  private MyGame game;

  private Texture t1;
  private Sound s1;

  public GameScreen(MyGame game) {
    this.game = game;

    AssetManager am = game.getAssetManager();

    t1 = am.get("....", Texture.class);
    s1 = am.get("....", Sound.class);
  }
  // use t1 and s1

Now another source I've seen takes this concept a bit further and also does the actual get()s in the asset loading class, so screens don't have to do them themselves, eg

// in the Loader class

public AssetManager am = new AssetManager();
public Texture t1;
public Sound s1;

...
am.load(...);
am.load(...);
am.load(...);

// finishLoading() or update()....
...
t1 = am.get(...);
s1 = am.get(...);
...

// in the screen class

t1 = game.am.t1;
s1 = game.am.s1;
...
// use t1 and s1

Now my question is: is this good practice? What's the expensive part of loading assets, the AssetManager's .load()s or also the .get()s? (I thought it was only the .load()s.) Is removing the get()s from the screens really a performance gain?

\$\endgroup\$
0
\$\begingroup\$

Removing the gets from the individual screens is often done so that if multiple screens use the same resource they don't all have to qualify them by a name, instead they're fields on the asset manager.

This is done not for performance but ease of access and making sure each asset resource name is only referenced once.

So for two separate screens that are both using the same texture the code will be

public class ScreenA {
   ...    
   public void render() {
      game.assetManager.someTexture.draw(...); 
   }
}

public class ScreenB {
   ...    
   public void render() {
      game.assetManager.someTexture.draw(...); 
   }
}

instead of

public class ScreenA {
   private final Texture texture;

   public ScreenA(...) {
     texture = game.assetManager.get(Gdx.files.internal("graphics/sometexture.png"));
   }

   public void render() {
      texture.draw(...); 
   }
}

public class ScreenB {
   private final Texture texture;

   public ScreenB(...) {
     texture = game.assetManager.get(Gdx.files.internal("graphics/sometexture.png"));
   }

   public void render() {
      texture.draw(...); 
   }
}

The first way allows for the actual file-name of the resource to be the concern of the AssetManager and no other. It makes it easier to manager and allows for convenient refactoring.

\$\endgroup\$
0
\$\begingroup\$

The AssetManager's load method only adds the items to the queue of items to be loaded by the AssetManager. The actual loading is done in the finishLoading() (blocking) or update()(non blocking) methods. The get method only returns an already loaded item.

So the most expensive method is the finishLoading method as this will only return once all items are loaded. Usually in a loading screen the update() method will called during in the render method as it returns a value to show how much loading is done which can then be used to show loading progress on screen.

I don't believe there will be much, if any performance gains from calling get in the loading class compared to the screen class as get in either class is just retrieving an already loaded asset.

\$\endgroup\$
  • \$\begingroup\$ Thanks, I've updated the question to show that finishLoading()/update() are run in the loading class. \$\endgroup\$ – persson Jul 26 '17 at 9:48

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.