Управление активами и их загрузка через AssetManager (Libgdx)

У меня проблемы с AssetManager, предоставляемым Libgdx. Я получаю нулевой указатель:

Java.lang.IllegalArgumentException: текстура не может быть нулевой.

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)

Я проверил, что загружаемый файл присутствует и исправен, так что это что-то в моем коде. И я буквально понятия не имею, что с этим делать ... Мне сказали убедиться, что я создаю не новый экземпляр Assets, а создаю его существующий. Не уверен, что я сделал это правильно ... Это сам класс:

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();

    }
}

И на данный момент я объявляю это так в своем 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();
}

} А для примера загрузки ресурсов в класс Screen:

 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();
}

}


person Benni    schedule 14.06.2015    source источник


Ответы (1)


Это НЕ загрузит фоновую текстуру:

manager.load(background, Texture.class);

Вам нужно позвонить в

manager.finishLoading();

сразу после load () для этого. AssetManager.load () - это просто путь к активу. AssetManager.update () загружает следующий элемент из сохраненных путей в другом потоке, AssetManager.finishLoading () загружает ВСЕ элементы и ожидает завершения потока загрузки. Если вы хотите нарисовать изображение при загрузке других ресурсов, вам необходимо сначала загрузить это изображение (в данном случае «фон»).

С другой стороны, я думаю, что вы дважды храните вещи бесплатно (текстуры, звуковые карты объектов). Лучше всего использовать диспетчер ресурсов для получения текстур или любых ресурсов с помощью функции "get".

Я сделал это:

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 - это экземпляр Game, app.assets - экземпляр AssetManager. Когда я хочу получить актив, я делаю это (но это можно запустить только после завершения загрузки!):

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