简体   繁体   中英

Libgdx switching screens

I seem to have a problem switching screens in libGDX. It switches to GameScreen, but it doesn't switch back to main screen nor to game over screen. My game 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 (which implements screen):

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

}

This is how i change a screen (doesn't work):

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();
                    }

You can find the whole source here .

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

There are many ways to tackle a problem and I don't want to read through the source you posted but the line you posted does certainly not change the screen.

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();
                    }

I'm not sure about the architecture of your source, there might be listener events that get triggered by g.runner.gameOver(); or g.runner.play = false` and then the following solution would create a mess for you eventually.

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

I personally like to work with screens like I did above. Whenever I need to change a screen I cast the ApplicationListener to Game so I can set a new (or push a existing) screen.

But like I said, you might have deleted or not yet implemented code that should call the methods in your Game class to change the screen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM