Libgdx 切换画面

Libgdx switching screens

我似乎在 libGDX 中切换屏幕时遇到问题。它切换到 GameScreen,但不会切换回主屏幕或游戏结束屏幕。 我的游戏 class:

@Override
public void create() {
    menu();
}

public void play(){
    this.setScreen(new GameSc(this));
    play = true;
}
public void menu(){


    this.setScreen(new GameMenu(this));
    menu = true;
}
public void gameOver(){

    this.setScreen(new GameOver(this));

}

My GameScreen class(实现屏幕):

public GameSc(GameRunner runner) {
    this.runner = runner;

    background = new Texture(Gdx.files.internal("Textures/background.png"));
    batch = new SpriteBatch();




    box = new Box(this);

    txt = new Texture(Gdx.files.internal("Textures/Enemies/Boxers/Enemy.png"));

    snakes = new ArrayList<Snake>();
    enemies = new ArrayList<Enemy>();

    shape = new ShapeRenderer();

    Gdx.gl.glClearColor(1f, 1f, 1f, 1f);

    new Thread(new Runnable() {

        @Override
        public void run() {
            while(true){
                update();
            }

        }
    }).start();

    snakeThread();
    enemyThread();
}

@Override
public void show() {


    //initialize

}



@Override
public void resize(int width, int height) {



}



@Override

public void render(float dt) {

    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    //Drawing an image.
    batch.begin();
    batch.draw(background, 0,0 , Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    batch.end();
    box.render(batch);
            for (int i = 0; i < snakes.size(); i++) {

                snakes.get(i).render(shape);
            }

    for (int i = 0; i < enemies.size(); i++) {
        enemies.get(i).render(batch);
    }

}
public void update(){

    box.update();
    for (int i = 0; i < snakes.size(); i++) {
        snakes.get(i).update();
    }

    for (int i = 0; i < snakes.size(); i++) {

        if(!(snakes.get(i).isAlive)){
            snakes.remove(i);
            System.out.println(snakes.size());
        }


    }

}

private void snakeThread(){
    new Thread(new Runnable() {
    Random r = new Random();
    //float[]anglem = {30,40,50,60,70,80,90,100};   

    @Override
    public void run() {
        while(true){
            int x = r.nextInt(Gdx.graphics.getWidth()-50);
            int y = r.nextInt(Gdx.graphics.getHeight()-50);
            int delay = r.nextInt((6000-2000)+1)+2000;
            int speed = MathUtils.random(50, 150);
            float angle = (float) r.nextInt((110-30)+1)+30;
            int length = MathUtils.random(15, 25);
            try {
                spawnSnake(x, y, angle, length, speed);
                //System.out.println(delay);
                Thread.sleep(delay);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }
}).start();

    box.update();
}

private void enemyThread(){
    new Thread(new Runnable() {

        @Override
        public void run() {
            while(true){
                int x = MathUtils.random(Enemy.UNIFORM_WIDTH, Gdx.graphics.getWidth()-Enemy.UNIFORM_WIDTH);
                int y = 0;
                int speed = 15;
                int delay = MathUtils.random(400, 600);


                try {
                    spawnEnemy(x, y, speed, txt);
                        for (int i = 0; i < enemies.size(); i++) {
                            if(enemies.get(i).getY()<0){
                                enemies.remove(i);
                            }

                        }

                    Thread.sleep(delay);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }
    }).start();

    box.update();
}


public void spawnSnake(int x, int y, float angle, int length, int speed){
    Snake snake = new Snake(angle,new Vector2(x,y),speed,length);
    snakes.add(snake);

}

public void spawnEnemy(int x, int y, int speed, Texture currentTexture){
    Enemy enemy = new Enemy(x , y , speed, Enemy.UNIFORM_WIDTH, Enemy.UNIFORM_HEIGHT, txt);
    enemies.add(enemy);

}



@Override
public void pause() {


}

@Override
public void resume() {


}

@Override
public void dispose() {
    if(runner.menu==false){
        runner.getScreen().dispose();
        shape.dispose();
        batch.dispose();
        }


}



@Override
public void hide() {
    // TODO Auto-generated method stub

}

这是我更换屏幕的方式(不起作用):

if (bounds.contains(g.snakes.get(i).snake.get(y).x, g.snakes.get(i).snake.get(y).y) && isAlreadyTouched) {
                    isAlreadyTouched = false;
                    g.runner.play=false;
                    g.runner.gameOver();
                    }

您可以找到完整的来源 here

解决问题的方法有很多,我不想通读你发布的源代码,但你发布的行肯定不会改变屏幕。

if (bounds.contains(g.snakes.get(i).snake.get(y).x, g.snakes.get(i).snake.get(y).y) && isAlreadyTouched) {
                    isAlreadyTouched = false;
                    g.runner.play=false;
                    g.runner.gameOver();
                    }

我不确定您的源架构,可能会有 g.runner.gameOver(); 或 g.runner.play = false 触发的侦听器事件,然后以下解决方案会造成混乱你终于。

if (bounds.contains(g.snakes.get(i).snake.get(y).x, g.snakes.get(i).snake.get(y).y) && isAlreadyTouched) {
                    isAlreadyTouched = false;
                    g.runner.play=false;
                    g.runner.gameOver();
                    //Now set a screen
                    ((Game)Gdx.app.getApplicationListener).setScreen(new GameOver(this);
                }

我个人喜欢像上面那样使用屏幕。每当我需要更改屏幕时,我都会将 ApplicationListener 转换为 Game,这样我就可以设置一个新的(或推送现有的)屏幕。

但正如我所说,您可能已经删除或尚未实现应调用游戏中方法的代码 class 以更改屏幕。

通过将 g.runner.setScreen(new GameOver(this)) 移动到另一个线程设法解决了这个问题。