Libgdx AssetsManager 作为静态变量



我正在尝试将资源管理器实现到我的应用程序中。它应该只加载所有字体文件和背景音乐。所有这些都完美地工作。我的问题是,有时在 android 上,当我离开应用程序并稍后重新加入它时,资产管理器文件会消失/错误/有问题。我知道这是因为资产的生命周期在 Android 上与静态变量不同,这就是出现此问题的原因。我的问题是如何解决这个问题?资源管理器必须是静态的,否则我无法从其他类获取资产。

到目前为止我的代码(如何改进?

public class Colors extends ApplicationAdapter {
//MAIN
private GameStateManager gsm;
private SpriteBatch sb;
private boolean tomenu = false;
//STATIC
public static int WIDTH = 480;
public static int HEIGHT = 800;
//Generell
private FreeTypeFontGenerator fontGenerator;
private FreeTypeFontGenerator.FreeTypeFontParameter fontParameter;
private BitmapFont font;
private Texture loaderb;
private Texture loader;
private Texture timelablogo;
//Asset Manager
public static AssetManager manager = new AssetManager();

@Override
public void create () {
    Gdx.gl.glClearColor(71/255f, 92/255f, 141/255f, 1);
    WIDTH = Gdx.graphics.getWidth();
    HEIGHT = Gdx.graphics.getHeight();
    Gdx.input.setCatchBackKey(true); //Backkey is catched and does not close the App
    gsm = new GameStateManager();
    sb = new SpriteBatch();
    font = new BitmapFont();
    loaderb = new Texture("Buttons/loadingbackground.png");
    loader = new Texture("Buttons/loader.png");
    timelablogo = new Texture("timelab.png");
    //ASSETMANAGER (alle assets[texturen,schirftne,sounds,..])
    manager.load("Sound/menubackground.ogg", Music.class);
    //FreetypeFontGenerator zum AssetManager hinzufügen
    FileHandleResolver resolver = new InternalFileHandleResolver();
    manager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
    manager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
    //Create Fonts and give them to the AssetManager
    FreetypeFontLoader.FreeTypeFontLoaderParameter params1 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params1.fontFileName = "Fonts/kenvector_future1.ttf";
    params1.fontParameters.size = WIDTH/7;
    params1.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future1.ttf", BitmapFont.class, params1);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params2 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params2.fontFileName = "Fonts/kenvector_future2.ttf";
    params2.fontParameters.size = WIDTH/25;
    params2.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future2.ttf", BitmapFont.class, params2);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params3 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params3.fontFileName = "Fonts/kenvector_future3.ttf";
    params3.fontParameters.size = WIDTH/15;
    params3.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future3.ttf", BitmapFont.class, params3);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params4 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params4.fontFileName = "Fonts/kenvector_future4.ttf";
    params4.fontParameters.size = WIDTH/12;
    params4.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future4.ttf", BitmapFont.class, params4);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params5 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params5.fontFileName = "Fonts/kenvector_future5.ttf";
    params5.fontParameters.size = WIDTH/18;
    params5.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future5.ttf", BitmapFont.class, params5);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params6 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params6.fontFileName = "Fonts/kenvector_future6.ttf";
    params6.fontParameters.size = WIDTH/15;
    params6.fontParameters.color.set(99/255f, 99/255f, 99/255f, 1);
    manager.load("Fonts/kenvector_future6.ttf", BitmapFont.class, params6);
}
@Override
public void render () {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    if(manager.update()) {
        if(!tomenu) {
            tomenu = true;
            manager.get("Sound/menubackground.ogg",Music.class).setLooping(true);
            manager.get("Sound/menubackground.ogg",Music.class).setVolume(0.7f);
            manager.get("Sound/menubackground.ogg",Music.class).play();
            //When everything is loaded a new State is pushed, which uses the font assets from this Assetsmanger
            gsm.push(new MenuStateNew(gsm,0,0,false,1));
        }
        gsm.update(Gdx.graphics.getDeltaTime());
        gsm.render(sb);
        sb.begin();
        font.draw(sb,WIDTH+"px*"+HEIGHT+"px closed BETA v11 "+String.valueOf((int)(1/Gdx.graphics.getDeltaTime()))+" FPS",5,20);
        sb.end();
    } else {
        sb.begin();
        font.draw(sb,WIDTH+"px*"+HEIGHT+"px closed BETA v11 "+String.valueOf((int)(1/Gdx.graphics.getDeltaTime()))+" FPS",5,20);
        sb.draw(loaderb,0,0,WIDTH,WIDTH*0.25f);
        sb.draw(loader,0,0,WIDTH*manager.getProgress(),WIDTH*0.25f);
        sb.draw(timelablogo,WIDTH/2-WIDTH/6,HEIGHT/2-WIDTH/6,WIDTH/3,WIDTH/3);
        sb.end();
    }
}
@Override
public void pause() {
    gsm.pause();
}
@Override
public void dispose () {
    sb.dispose();
    manager.dispose();
    font.dispose();
}

}

编辑 1:

我按照你说的实现了代码,但知道整个游戏更黑暗(没有错误(

我的代码现在看起来像这样(并导致屏幕变暗:/(

public class Colors extends ApplicationAdapter {
//MAIN
private GameStateManager gsm;
private SpriteBatch sb;
private boolean tomenu = false;
//STATIC
public static int WIDTH = 480;
public static int HEIGHT = 800;
//Generell
private BitmapFont font;
private Texture loaderb;
private Texture loader;
private Texture timelablogo;
//Asset Manager
private Assets assets;

@Override
public void create () {
    Gdx.gl.glClearColor(71/255f, 92/255f, 141/255f, 1);
    WIDTH = Gdx.graphics.getWidth();
    HEIGHT = Gdx.graphics.getHeight();
    //Assetmanager
    assets = new Assets();
    getAssets().load(); //starts loading assets
    Gdx.input.setCatchBackKey(true); //Backkey is catched and does not close the App
    gsm = new GameStateManager();
    sb = new SpriteBatch();
    font = new BitmapFont();
    loaderb = new Texture("Buttons/loadingbackground.png");
    loader = new Texture("Buttons/loader.png");
    timelablogo = new Texture("timelab.png");
}
public static Assets getAssets() {
    return ((Colors) Gdx.app.getApplicationListener()).assets;
}
@Override
public void render () {
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    if(getAssets().manager.update()) {
        if(!tomenu) {
            tomenu = true;
            getAssets().manager.get("Sound/menubackground.ogg",Music.class).setLooping(true);
            getAssets().manager.get("Sound/menubackground.ogg",Music.class).setVolume(0.7f);
            getAssets().manager.get("Sound/menubackground.ogg",Music.class).play();
            gsm.push(new MenuStateNew(gsm,0,0,false,1));
        }
        gsm.update(Gdx.graphics.getDeltaTime());
        gsm.render(sb);
        sb.begin();
        font.draw(sb,WIDTH+"px*"+HEIGHT+"px closed BETA v12 "+String.valueOf((int)(1/Gdx.graphics.getDeltaTime()))+" FPS",5,20);
        sb.end();
    } else {
        sb.begin();
        font.draw(sb,WIDTH+"px*"+HEIGHT+"px closed BETA v12 "+String.valueOf((int)(1/Gdx.graphics.getDeltaTime()))+" FPS",5,20);
        sb.draw(loaderb,0,0,WIDTH,WIDTH*0.25f);
        sb.draw(loader,0,0,WIDTH*getAssets().manager.getProgress(),WIDTH*0.25f);
        sb.draw(timelablogo,WIDTH/2-WIDTH/6,HEIGHT/2-WIDTH/6,WIDTH/3,WIDTH/3);
        sb.end();
    }
}
@Override
public void pause() {
    gsm.pause();
}
@Override
public void resume() { assets.manager.finishLoading(); }
@Override
public void dispose () {
    sb.dispose();
    assets.dispose();
    font.dispose();
}

}和资产类别:

public class Assets implements Disposable {
public AssetManager manager = new AssetManager();
public void load() {
    loadMusics();
    loadSounds();
    loadFonts();
}
private void loadSounds() {
    manager.load("Sound/menubackground.ogg", Music.class);
}
private void loadMusics() {
    manager.load("Sound/menubackground.ogg", Music.class);
}
private void loadFonts() {
    //FreetypeFontGenerator zum AssetManager hinzufügen
    FileHandleResolver resolver = new InternalFileHandleResolver();
    manager.setLoader(FreeTypeFontGenerator.class, new FreeTypeFontGeneratorLoader(resolver));
    manager.setLoader(BitmapFont.class, ".ttf", new FreetypeFontLoader(resolver));
    //Create Fonts and give them to the AssetManager
    FreetypeFontLoader.FreeTypeFontLoaderParameter params1 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params1.fontFileName = "Fonts/kenvector_future1.ttf";
    params1.fontParameters.size = WIDTH/7;
    params1.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future1.ttf", BitmapFont.class, params1);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params2 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params2.fontFileName = "Fonts/kenvector_future2.ttf";
    params2.fontParameters.size = WIDTH/25;
    params2.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future2.ttf", BitmapFont.class, params2);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params3 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params3.fontFileName = "Fonts/kenvector_future3.ttf";
    params3.fontParameters.size = WIDTH/15;
    params3.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future3.ttf", BitmapFont.class, params3);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params4 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params4.fontFileName = "Fonts/kenvector_future4.ttf";
    params4.fontParameters.size = WIDTH/12;
    params4.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future4.ttf", BitmapFont.class, params4);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params5 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params5.fontFileName = "Fonts/kenvector_future5.ttf";
    params5.fontParameters.size = WIDTH/18;
    params5.fontParameters.color = Color.DARK_GRAY;
    manager.load("Fonts/kenvector_future5.ttf", BitmapFont.class, params5);
    FreetypeFontLoader.FreeTypeFontLoaderParameter params6 = new FreetypeFontLoader.FreeTypeFontLoaderParameter();
    params6.fontFileName = "Fonts/kenvector_future6.ttf";
    params6.fontParameters.size = WIDTH/15;
    params6.fontParameters.color.set(99/255f, 99/255f, 99/255f, 1);
    manager.load("Fonts/kenvector_future6.ttf", BitmapFont.class, params6);
}
@Override
public void dispose() {
    manager.dispose();
}

}菜单状态新类(仅一个除外(:

public class MenuStateNew extends State implements GestureDetector.GestureListener {
//Generel
private int width = Colors.WIDTH;
private int height = Colors.HEIGHT;
private GestureDetector gsdt;
private float zeit;
private int mode;
//Buttons
private Texture btn_settings;
private Texture btn_settingsh;
private Sprite sp_settings;
private Rectangle ra_settings;
private Texture btn_easy;
private Texture btn_easyh;
private Texture btn_hard;
private Texture btn_hardh;
private Sprite sp_easy;
private Rectangle ra_easy;
private Texture btn_start;
private Texture btn_starth;
private Sprite sp_start;
private Rectangle ra_start;
private Texture btn_list;
private Rectangle ra_list;
//Fonts
private BitmapFont menufont = Colors.getAssets().manager.get("Fonts/kenvector_future6.ttf", BitmapFont.class);
//Background
private Array<Backgrounddot> backgrounddots;
//Sounds
private Sound s_click;
//Particle Effects
private ParticleEffect pe1;
private ParticleEffect pe2;
//Speicher
Preferences prefs;
public MenuStateNew(GameStateManager pgsm,int plastscore,int plastlevel,boolean highscore,int pmode) {
    super(pgsm);
    //Generell
    gsdt = new GestureDetector(this);
    Gdx.input.setInputProcessor(gsdt);
    mode = pmode;//1: easy,0: hard
}
@Override
public void render(SpriteBatch sb) {
    sb.begin();
    //Particles
    pe1.draw(sb);
    pe2.draw(sb);
    //BackgroundDots
    for(Backgrounddot bgd : backgrounddots) {
        sb.draw(bgd.getTxt_dot(),bgd.getDotposition().x,bgd.getDotposition().y,bgd.getDotwidth(),bgd.getDotwidth());
    }
    sb.draw(sp_settings,ra_settings.getX(),height-ra_settings.getY()-ra_settings.getHeight(),ra_settings.getWidth(),ra_settings.getHeight());
    sb.draw(btn_list,ra_list.getX(),height-ra_list.getY()-ra_list.getHeight(),ra_list.getWidth(),ra_list.getHeight());
    sb.draw(sp_easy,ra_easy.getX(),height-ra_easy.getY()-ra_easy.getHeight(),ra_easy.getWidth(),ra_easy.getHeight());
    sb.draw(sp_start,ra_start.getX(),height-ra_start.getY()-ra_start.getHeight(),ra_start.getWidth(),ra_start.getHeight());
    if(mode == 1) {
        menufont.draw(sb,"Last: "+prefs.getInteger("lastscore2")+" ("+prefs.getInteger("lastlevel2")+")",width/6,height*0.63f);
        menufont.draw(sb,"Best: "+prefs.getInteger("highscore2"),width/6,height*0.515f);
        menufont.draw(sb,"Level "+prefs.getInteger("level2"),width/6,height*0.4f);
    } else if(mode == 0) {
        menufont.draw(sb,"Last: "+prefs.getInteger("lastscore")+" ("+prefs.getInteger("lastlevel")+")",width/6,height*0.63f);
        menufont.draw(sb,"Best: "+prefs.getInteger("highscore"),width/6,height*0.515f);
        menufont.draw(sb,"Level "+prefs.getInteger("level"),width/6,height*0.4f);
    }
    sb.end();
}

我做错了什么吗?

我将扩展 Abhishek 的答案,提供一种解决方法,以便将Assets类传递给所有游戏对象。

这种方法肯定不是"最好的设计",但它方便,安全(据我所知(。

按照 Abhishek 创建 Assets 类的步骤进行操作,然后您可以在GdxGame类(基类(中添加以下函数

public static Assets getAssets() {
    return ((GdxGame) Gdx.app.getApplicationListener()).assets;
}

现在,每当您需要纹理或某些资产时,都可以调用 GdxGame.getAssets().getTextureRegion(...) .通过这种方式,您可以实际静态访问资产(方便(,并且仍然将资源管理器作为实例变量(安全(。

我在移动设备上,所以,对于任何格式错误表示歉意。

你应该创建一个存储资产的类。

public class Assets implements Disposable {
 public AssetManager manager = new AssetManager();
 public void load() {
     manager.load("data/mytexture.png", Texture.class);
     manager.load("data/myfont.fnt", BitmapFont.class);
     manager.load("data/mymusic.ogg", Music.class);
 }
 @Override
 public void dispose() { 
    manager.dispose();
 }
}

在 Game(Main( 类中保留对资产对象的引用,并将其作为引用传递到需要的地方。

public class Colors extends ApplicationAdapter {
  Assets assets;
  @Override
  public void create() {
    assets = new Assets();
    assets.load(); //starts loading assets

    assets.manager.finishLoading(); //Continues when done loading.
    //it won't continue until all assets are finished loading.
  }
 @Override
 public void dispose() {
    assets.dispose();
 }  
}

编辑

在构造函数中获取或初始化所有私有数据成员(资源(,然后在渲染方法中使用。

private BitmapFont menufont;
public MenuStateNew(GameStateManager pgsm,int plastscore,int plastlevel,boolean highscore,int pmode) {
    super(pgsm);
    //Generell
    gsdt = new GestureDetector(this);
    Gdx.input.setInputProcessor(gsdt);
    mode = pmode;//1: easy,0: hard
    menufont = Colors.getAssets().manager.get("Fonts/kenvector_future6.ttf", BitmapFont.class);
}

这只是menufont的一个例子,就像你需要在他的构造函数中初始化MenuStateNew中所有必需的资源一样。

相关内容

  • 没有找到相关文章

最新更新