Libgdx切换屏幕

问题描述:

我似乎在切换libGDX中的屏幕时出现问题。它切换到GameScreen,但它不切换回主屏幕或屏幕上的游戏。 我的游戏类:Libgdx切换屏幕

@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)); 

} 

我GameScreen类(实现屏幕):

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

通过将g.runner.setScreen(新的GameOver(this))移动到另一个线程来解决此问题。

+0

使用线程来实现这个目的最终会引发你的攻击 – Madmenyo

+0

我有2个独立的线程:一个用于渲染,另一个用于更新(滴答),为什么它在渲染线程中工作,但它没有在更新线程中。 – Martis

有很多方法可以解决问题,我不想通读您发布的来源,但您发布的行确实不会改变屏幕。

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,以便我可以设置新的(或推送现有的)屏幕。

但正如我所说的,你可能已经删除了或者还没有实现的代码应该调用Game类中的方法来改变屏幕。

+0

GameOver方法本质上将屏幕设置为GameOver。将应用程序侦听器强制转换为游戏也不起作用。 – Martis

+0

'((Game)Gdx.app.getApplicationListener).setScreen(new GameOver(this);'将更改屏幕,检查您的语句是否运行,如果屏幕显示'show'方法运行,它可能会立即切换屏幕 – Madmenyo