libgdx / Android:应用程序被销毁/暂停后图形消失

时间:2015-06-30 12:10:05

标签: java android opengl-es libgdx textures

我正在做一些测试,我意识到在我的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;
    }
}

代码只是为了显示纹理的使用,删除了其他部分

3 个答案:

答案 0 :(得分:2)

您没有提供足够的信息,但您的问题很可能是因为您的代码中使用了static。别这么做。

当您按后退按钮时,您的应用程序将关闭。当您按下主页按钮时,您的应用程序将暂停。请注意,这是两个不同的事情。因此,使用主页按钮时可能不会经常遇到问题。这是因为当你的应用程序暂停时,该android可能决定关闭它(释放内存),但不能保证这样做。

无论哪种方式,这与opengl上下文丢失无关。它刚刚关闭。如果上下文真的丢失了,那么libgdx(及更高版本的android)将为你恢复它。

当您关闭应用程序然后立即再次启动它时,Android可能会为您的应用程序实例重复使用相同的VM。这也意味着任何static变量都具有上次运行应用时的值。如果这些变量中的任何一个包括(可能是间接的)任何资源,那么这些资源将不再有效。

tl; dr从未在Android应用程序中使用static

最常见的错误(没有看到您的代码只是猜测)是使用单例访问资产。例如。 MyGame.getInstance().assets.get("atlas",...);不要这样做,因为上述原因会失败。而是将对MyGame个实例的引用传递给任何需要它的类(例如Screennew 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;
...