我正在尝试将资源管理器实现到我的应用程序中。它应该只加载所有字体文件和背景音乐。所有这些都完美地工作。我的问题是,有时在 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中所有必需的资源一样。