我在使用libGDX框架的Android游戏中工作,同时学习他们的wiki和Learning Libgdx Game Development书籍。本书的作者定义了一个Assets类,用于使用AssetManager加载游戏资产。每次游戏恢复时,都需要重新加载资源,因此他使用对Assets.intance.init(new AssetManager())的调用重新加载资源并创建新对象来存储纹理参考。
当我在游戏中执行此操作时,在恢复之后,我所有的都是黑盒子,我的纹理很好,所以我想这里的问题是我使用旧的引用。我在这里写了一部分代码:
AssetManager#初始化
public void init(AssetManager assetManager) {
/* Dispose previous asset manager */
if (this.assetManager != null) {
this.assetManager.dispose();
}
this.assetManager = assetManager;
assetManager.setErrorListener(this);
assetManager.load(Constants.TEXTURE_ATLAS, TextureAtlas.class);
/* Start loading assets and wait until finished */
assetManager.finishLoading();
Array<String> assetNames = assetManager.getAssetNames();
Gdx.app.debug(TAG, "Assets loaded: " + assetNames.size);
for (String assetName : assetNames) {
Gdx.app.debug(TAG, "Asset: " + assetName);
}
TextureAtlas atlas = assetManager.get(Constants.TEXTURE_ATLAS);
/* Create game resource objects. Here I get what I need from the atlas */
player = new AssetPlayer(atlas);
enemy = new AssetEnemy(atlas);
}
当我创建我的游戏对象时,我使用Assets.instance.player和Assets.instance.enemy存储对纹理的引用,因为本书的作者这样做可能是问题所在。事情就是重新读完这本书,我看不出他是如何解决这个问题的。
我很确定我可以解决更改游戏对象中引用的问题,但所有这些都变得如此混乱。我真正的问题是,我应该如何在游戏中管理游戏资产?我一直在搜索游戏示例,但大多数都没有使用AssetManager,而是使用静态变量来构建纹理。
我应该在游戏对象中保留纹理的引用吗?真的有必要在简历上重新加载资产吗?当所有对象都在一个不知道游戏何时恢复的worldController中时,我怎样才能在我的游戏对象中重新加载纹理?
答案 0 :(得分:3)
据我所知,你在这个级别正确地做到了。你确实需要重新加载纹理,因为你的OpenGL上下文丢失了,所有的指针都是#34;进入OpenGL内部状态是陈旧的。
正如您所指出的那样,因为您的AssetManager.player
属性指向一个新对象,所以缓存旧指针的任何内容在重新启动后都会过时,这可能是您遇到问题的根源。 (虽然很难说肯定。)
如果您查看Libgdx SuperJump演示,他们还会将所有资产指针缓存在静态字段中,但请注意render
调用会在每次调用时有效地查找纹理。见WorldRenderer.renderBob()。一种替代方法是在(重新)加载资产之后对您的对象进行一次传递以使它们更新并刷新&#34;他们指出了他们使用的资产。
答案 1 :(得分:0)
您是否尝试过在恢复方法上不调用Assets.intance.init(new AssetManager())
(也没有在暂停方法上调用Assets.intance.dispose()
)?
请阅读以下链接:
https://github.com/libgdx/libgdx/wiki/Managing-your-assets
最后(正在恢复加载屏幕)显示:
在Android上,您的应用可以暂停和恢复。托管OpenGL资源(例如纹理) 在这种情况下需要重新加载,这可能需要一些时间。如果你想 在履历上显示加载屏幕,您可以在创建自己的简历后执行以下操作 AssetManager。
Texture.setAssetManager(manager);
然后在您的ApplicationListener.resume()方法中切换到加载屏幕,然后再次调用AssetManager.update(),直到一切恢复正常。
如果您没有按上一片段所示设置AssetManager,则通常的托管纹理机制将启动,因此您不必担心任何事情。
所以,我认为不再需要作者的方法。
您只需要在“游戏”类(即实现Assets.intance.dispose()
的类)的dispose方法上调用ApplicationListener
。