Managing and loading assets via AssetManager (Libgdx)

1.3k views Asked by At

Im having some issues with the AssetManager provided by Libgdx. I get a nullpointer:

Java.lang.IllegalArgumentException: texture cannot be null.

at com.badlogic.gdx.graphics.g2d.TextureRegion.<init>(TextureRegion.java)
at com.test.test.screens.screens.MainScreen.show(MainScreen.java)
at com.badlogic.gdx.Game.setScreen(Game.java)
at com.test.test.screens.screens.SplashScreen.render(SplashScreen.java)

I´ve checked and the file it´s loading is present and correct, so it´s something in my code. And I literally have no idea what to do about it.. I was told to make sure I create not a new instance of Assets but creating an existing instance of it. Not sure if I´ve done it correctly though.. This is the class it self:

public class Assets {

    public final AssetManager manager = new AssetManager();
    private ObjectMap<String, Texture> textures;
    private ObjectMap<String, Sound> sounds;
    public  final String background = "test.jpg";

public Assets() {
    textures = new ObjectMap<String, Texture>();
    sounds = new ObjectMap<String, Sound>();
    manager.load(background, Texture.class);

}

public boolean update() {
    boolean done = manager.update();
    if (done) {
        finishLoading();

    }
    return done;
}

private void finishLoading() {
    textures.put(background, manager.get(background, Texture.class));

}

public Texture getTexture(String name) {
    return textures.get(name);
}
    public void dispose()    {

        manager.clear();

    }
}

And at the moment I declare it like this in my MainClass:

public class MainClass extends Game  {
public SpriteBatch batch;
public purchaseInterface pi;
//Calls the Assets to be implemented in other classes
public Assets assets;
public MainClass(purchaseInterface purchase, GalleryOpener opener){
    this.gallery= opener;
    this.pi = purchase;
}
@Override
public void create () {
    batch = new SpriteBatch();
    assets = new Assets();
    setScreen(new SplashScreen(this));
    }

@Override
public void resize(int width, int height) {
    super.resize(width, height);

}

@Override
public void render () {
    super.render();


}

@Override
public void dispose() {
    super.dispose();
    batch.dispose();
    assets.dispose();
}

public Assets getAssets() {
    return assets;
}


@Override
public void pause() {
    super.pause();
}


@Override
public void resume() {
    // TODO Auto-generated method stub
    super.resume();
}

} And for the example of loading assets to a Screen class:

 public Assets assets;
public MainScreen(MainClass gam) {
    game = gam;
    assets = game.getAssets();
    loadStore();
    camera = new OrthographicCamera(screenWidth,screenHeight);
    view = new StretchViewport(screenWidth, screenHeight, camera);
    view.apply();
    camera.translate(camera.viewportWidth / 2, camera.viewportHeight / 2);

}

public void loadStore()  {
    background = assets.getTexture(assets.background);
}



@Override
public void render(float delta) {

    camera.update();

    game.batch.setProjectionMatrix(camera.combined);

    game.batch.begin();

    game.batch.draw(background, 0, 0, 1000, 2000);

    game.batch.end();

}

@Override
public void resize(int width, int height) {
    view.update(width, height, true);
}

@Override
public void show() {
}




@Override
public void hide() {
    // TODO Auto-generated method stub

}

@Override
public void pause() {
    // TODO Auto-generated method stub

}

@Override
public void resume() {
}

@Override
public void dispose() {
    background.dispose();
}

}

1

There are 1 answers

0
gopher On

This will NOT load the background texture:

manager.load(background, Texture.class);

You need call the

manager.finishLoading();

right after the load() for that. AssetManager.load() is just store the path of an asset. AssetManager.update() loads the next item from the stored paths in an other thread, AssetManager.finishLoading() loads ALL of the items and waits for the loading thread to finish. When you would like to draw an image while you loading the other assets, you need to load first that image (in this case the "background").

The other thing, I think you store things twice for nothing (textures, sounds objectmaps). The best practice is use the asset manager to get the textures or any assets with the "get" function.

I did this:

public class LoadingScreen extends Screen {

    ...

    @Override
    public void show() {
       app.assets.load("data/textures/loading.pack", TextureAtlas.class);
       app.assets.finishLoading(); // this is waits for the loading finish

       app.assets.load("data/textures/menu.pack", TextureAtlas.class);
       app.assets.load("data/textures/sprites.pack", TextureAtlas.class);
       ...

    }

    @Override
    public void render(float delta) {
        if (app.assets.update()) { // this is loads the next item in an other thread
            app.loadingFinished(); // this is where you will create the other screens
        }            
        ...
    }

    ...

"app" is a Game instance, "app.assets" is an AssetManager instance. When I want to have an asset I do this (but this only can run after loading is finished!):

TextureAtlas atlas = app.assets.get("data/textures/sprites.pack", TextureAtlas.class);