我正在做一些测试,我意识到在我的Nexus 5上,当我按下后退键(或主页) - ,即当上下文发生变化时 - 我回去了在我的游戏中,openGL上下文丢失了。
UI没有纹理(它们显示为黑色)或皮肤(按钮为白色)。
我以为它是由libgdx自动管理的,对吧?那为什么会这样呢?
我创建纹理的方式是TextureAtlas
,如
TextureAtlas atlas;
TextureRegion bg;
atlas = new TextureAtlas(Gdx.files.internal("mainMenu.atlas"));
bg = atlas.findRegion("bg");
然后它与batch.draw(bg, x, y, w, h);
我还尝试直接创建TextureRegion
加载纹理而不是TextureAtlas
(以防万一,但它应该相同),我得到相同的结果......
任何?
编辑:更具体的代码:
屏幕类基础知识:
public class MainMenuScreen extends ScreenManager.Screen {
private Game game;
private InputMultiplexer inputMultiplexer = new InputMultiplexer();
private MainMenuUi screenUi;
private MainMenuView screenView;
private TextureAtlas atlas;
public MainMenuScreen(ConbiniGame game) {
this.game = game;
atlas = new TextureAtlas(Gdx.files.internal("mainMenu.atlas"));
screenUi = new MainMenuUi(game);
screenView = new MainMenuView(atlas);
inputMultiplexer.addProcessor(screenUi.getInputProcessor());
inputMultiplexer.addProcessor(screenView.getInputProcessor());
Gdx.input.setInputProcessor(inputMultiplexer);
}
// ...
}
正在使用TextureAtlas的MainMenuView类...
public class MainMenuView {
private Stage stage;
private OrthographicCamera camera;
private Viewport viewport;
private TextureAtlas atlas;
TextureRegion bg;
public MainMenuView(TextureAtlas atlas) {
atlas = atlas;
bg = atlas.findRegion("bg");
camera = new OrthographicCamera();
camera.setToOrtho(false);
viewport = new FitViewport(1080, 1920, camera);
stage = new Stage(viewport);
}
public void update(float delta) {
stage.act(delta);
}
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.getBatch().begin();
stage.getBatch().draw(bg, 0, 0, stage.getCamera().viewportWidth, stage.getCamera().viewportHeight);
stage.getBatch().end();
stage.draw();
}
public InputProcessor getInputProcessor() {
return stage;
}
}
代码只是为了显示纹理的使用,删除了其他部分
答案 0 :(得分:2)
您没有提供足够的信息,但您的问题很可能是因为您的代码中使用了static
。别这么做。
当您按后退按钮时,您的应用程序将关闭。当您按下主页按钮时,您的应用程序将暂停。请注意,这是两个不同的事情。因此,使用主页按钮时可能不会经常遇到问题。这是因为当你的应用程序暂停时,该android可能决定关闭它(释放内存),但不能保证这样做。
无论哪种方式,这与opengl上下文丢失无关。它刚刚关闭。如果上下文真的丢失了,那么libgdx(及更高版本的android)将为你恢复它。
当您关闭应用程序然后立即再次启动它时,Android可能会为您的应用程序实例重复使用相同的VM。这也意味着任何static
变量都具有上次运行应用时的值。如果这些变量中的任何一个包括(可能是间接的)任何资源,那么这些资源将不再有效。
tl; dr从未在Android应用程序中使用static
。
最常见的错误(没有看到您的代码只是猜测)是使用单例访问资产。例如。 MyGame.getInstance().assets.get("atlas",...);
不要这样做,因为上述原因会失败。而是将对MyGame
个实例的引用传递给任何需要它的类(例如Screen
:new MenuScreen(this);
)。
答案 1 :(得分:0)
在制作我的第一个LibGDX游戏时,我遇到了同样的问题-Flappy Bird克隆-原来问题根本不是与Texture有关,而是与我用于速度的MEMBER Vector2 / Vector3变量有关。
为了使小鸟从给定的高度掉落,我声明: 1.一个用于重力的成员int变量(初始化为-15), 2.鸟位置的Vector2成员变量,初始化为(50,300),并且 3.另一个用于速度的Vector2成员变量,初始化为0,0
现在,在update()方法中,我使用velocity.add(0,gravity)将重力作为值传递给速度的y轴参数
然后我使用Velocity.scl(dt)对其进行缩放 然后,我将该速度添加到位置,然后使用速度再次对其进行缩放。 scl(1 / dt)。 这最后一行是导致该错误的原因,但是由于它对于游戏的功能至关重要,因此我无法删除。 我的解决方案是将速度变量从成员变量更改为局部变量,并且在游戏暂停时纹理不再消失。
答案 2 :(得分:0)
实际上,可以使用Singleton或其他静态模式进行纹理管理。要避免黑矩形问题,您应该做的唯一一件事是: 根据游戏实体制作静态内容:
private static TextureStore sStore = null;
private static MyGdxGame sGame;
static public TextureStore getStore()
{
if(sStore==null||sGame!=MyGdxGame.getGame())
{
sStore = new TextureStore();
sGame = MyGdxGame.getGame();
}
return sStore;
}
在游戏实体中
@Override
public void create()
{
sGame = this;
...