setScreen(new Screen2())之后无法停止渲染previos Screen1();

时间:2018-11-12 21:44:24

标签: java libgdx

我有两个相同的类:Screen1和Screen2。问题是,当我从Screen1打开Screen2时,Screen1的动画精灵将继续渲染。我在日志中看到它。一段时间后,发生内存溢出。如何停止呈现关闭的屏幕?

public class Screen1 extends Game implements Screen, InputProcessor {

    private SpriteBatch batch;
    private TextureAtlas atlasBarrelBlue;
    private Sprite sprite1;
    private float sprite1positionX;
    private float sprite1positionY;
    private float spriteBarrelWidth;
    private float spriteBarrelHeight;
    private Texture backgroundTexture;
    private Animation<TextureAtlas.AtlasRegion> animationBarrelBlue;
    private float dTime = 0;
    private Vector2 vector2;

    @Override
    public void show() {

        batch = new SpriteBatch();
        vector2 = new Vector2();
        atlasBarrelBlue = new TextureAtlas(Gdx.files.internal("data/barrels/barr4"));
        animationBarrelBlue = new Animation<TextureAtlas.AtlasRegion>(1 / 24f, atlasBarrelBlue.getRegions(), Animation.PlayMode.LOOP);

        spriteBarrelWidth = Gdx.graphics.getWidth() / 50 * 4;
        spriteBarrelHeight = Gdx.graphics.getHeight() / 50 * 11;
        backgroundTexture = new Texture("data/fones/fone1.png");

        sprite1positionX = Gdx.graphics.getWidth() / 50 * 7;
        sprite1positionY = Gdx.graphics.getHeight() / 50 * 32;

        Gdx.input.setInputProcessor(this);

    }

    @Override
    public void render(float delta) {

        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        dTime += Gdx.graphics.getDeltaTime();

        sprite1 = new Sprite(animationBarrelBlue.getKeyFrame(dTime, true));
        Gdx.app.log("111", "111");
        sprite1.setPosition(sprite1positionX, sprite1positionY);
        sprite1.setSize(spriteBarrelWidth, spriteBarrelHeight);

        batch.begin();
        batch.draw(backgroundTexture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        sprite1.draw(batch);
        batch.end();

        super.render();
    }

    @Override
    public void dispose() {
        batch.dispose();
        atlasBarrelBlue.dispose();
        backgroundTexture.dispose();
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {

        vector2.set(screenX, Gdx.graphics.getHeight() - screenY);
        if (sprite1.getBoundingRectangle().contains(vector2)){
            setScreen(new Screen2());
        }

        return false;
    }
}

Dyspose()和hide()方法无济于事。当我从Screen2转到Screen1时,也会发生同样的事情。

1 个答案:

答案 0 :(得分:0)

您的问题是您扩展游戏,实现Screen并调用super.update()

libgdx将调用Game类的render方法。
当Game类拥有一个屏幕并调用您用render设置的当前屏幕的setScreen()方法时。

当我们查看render类的Game方法时:

@Override
public void render () {
    if (screen != null) screen.render(Gdx.graphics.getDeltaTime());
}

screen是您用setScreen()设置的屏幕

所以Libgdx调用=> Game.render()和Game.render()调用=> Screen.render(浮动增量)


现在,当我们查看您的代码时。您将覆盖方法:render(float delta),这是屏幕的渲染方法。 (游戏的渲染方法没有参数。)

因此,第一个libgdx调用Game.render();会调用Screen1的render方法,并在覆盖的Screen1.render(float delta)的末尾;方法,则使用super.render();再次调用Game.render()函数。
因此,您递归调用Screen1.render(float delta);方法。这就是导致内存溢出的原因。

我建议您不要在同一个课程中扩展Game并实现Screen 将在DesktopLauncher中创建的类应该扩展Game。
在我的情况下,TextAdventure:

public class TextAdventure extends Game {

    @Override
    public void create () {
        setScreen(new Screen1(this));
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        super.render();
    }
}

并且在Screen1类中仅实现Screen,而不调用super.render()!:

public class Screen1 implements Screen {

    Game myGame;

    public Screen1(Game myGame) {
        this.myGame = myGame;
    }

    public void changeToScreen2(){
        myGame.setScreen(new Screen2(myGame));
    }

    ...
}

要在Screen1中更改屏幕,请在构造函数中传递Game类。