Не могу остановить рендеринг предыдущих Screen1 () после setScreen (new Screen2 ()); - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть два идентичных класса: Screen1 и Screen2.Проблема в том, что когда я открываю Screen2 из Screen1, анимированный спрайт 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 голосов
/ 13 ноября 2018

Ваша проблема в том, что вы расширяете Game, реализуете Screen и вызываете super.update().

libgdx вызовет метод render класса Game.
Пока класс 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 (delat float)


Теперь, когда мы смотрим на ваш код.Вы переопределяете метод: render(float delta), который является методом рендеринга экрана.(Метод рендеринга в Game не имеет параметров).

Итак, первый вызов libgdx Game.render(); вызывает метод рендеринга Screen1 и в конце вашего переопределенного Screen1.render (float delta);метод, вы снова вызываете функцию Game.render () с super.render();.
, поэтому вы рекурсивно вызываете метод Screen1.render(float delta);.По этой причине вы переполняете память.

Я рекомендую вам не расширять Game и реализовывать Screen в одном классе. Класс, который будет создан в DesktopLauncher, должен расширять Game.
В моемcase 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));
    }

    ...
}

Чтобы изменить Screen в Screen1, передайте класс Game вКонструктор.

...