1
\$\begingroup\$

I'd like to know how I can change the screen from the Main Menu to the Game itself but im having quite the trouble and I would appreciate the help. What I want to do is when I press btn.Play it changes the screen from the main menu to the game.

Here's the code I got (sorry it's long):

Game:

@Override
public void create(){

    batch = new SpriteBatch();

    Up = new Texture("left.png");

    cam = new OrthographicCamera();
    cam.setToOrtho(false,1280,720);

    //creates the square in the middle of the screen
    square = new Rectangle();
    square.x = 630;
    square.y = 720 / 2 - 32 /2;
    square.width = 32;
    square.height = 32;

    //code
}

//code

public void render() {

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    cam.update();

    batch.setProjectionMatrix(cam.combined);
    batch.begin();
    batch.draw(Up, square.x, square.y);
    //code
    batch.end();
}

Screens (used to display the first screen) :

public class Screens extends com.badlogic.gdx.Game {


//creates the timing on the splash screen


@Override
public void create() {

    startTime = TimeUtils.millis();

    //sets the next screen as the splash screen
    setScreen( new SplashScreen(this));
}

@Override
public void render(){

    super.render();
    rendCount++;
}

@Override
public void dispose(){

    endTime = TimeUtils.millis();
}

SplashScreen:

public class SplashScreen implements Screen  {


public SplashScreen(Game g) {

    myGame = g;

    cam = new OrthographicCamera();
    cam.setToOrtho(false, 1280, 720);
}


@Override
public void show() {


    //image of the splash screen
    splashTexture = new Texture("splash.jpg");

    //timer starts
    timeStart = TimeUtils.millis();
}

@Override
public void render(float delta) {

    SpriteBatch batch = new SpriteBatch();

    //draws the image on screen
    batch.setProjectionMatrix(cam.combined);
    batch.begin();
    batch.draw(splashTexture, 0, 0);
    batch.end();
    rendCounter++;

    // if the timer is higher than 5 secs goes to the main screen
    if(TimeUtils.millis() > (timeStart+5000)) {
        myGame.setScreen(new MainScreen());
    }

}

@Override
public void dispose(){

    splashTexture.dispose();

}

Main Menu:

public class MainScreen implements Screen{

private SpriteBatch batch;
private OrthographicCamera cam;
private Stage stage;
private TextButton btnPlay, btnExit;
private BitmapFont font;
private Skin skin;
private TextureAtlas atlas;

public MainScreen() {

    cam = new OrthographicCamera();
    cam.setToOrtho(false, 1280,720);
    batch = new SpriteBatch();

}


@Override
public void show() {

    // creates the pack for the buttons, its skin, the font used on the buttons, and the stage(screen)

    atlas = new TextureAtlas("buttons.pack");
    skin = new Skin();
    skin.addRegions(atlas);
    font = new BitmapFont(Gdx.files.internal("font.fnt"), false);

    stage = new Stage();
    stage.clear();
    Gdx.input.setInputProcessor(stage);

    // sets the style of the buttons

    TextButton.TextButtonStyle style = new TextButton.TextButtonStyle();
    style.up = skin.getDrawable("btn_up");
    style.down = skin.getDrawable("btn_down");

    // sets the font of the buttons

    style.font = font;


    //creates the play button with the text, its position and the size

    btnPlay = new TextButton("Play", style);
    btnPlay.setSize(350, 150);
    btnPlay.setPosition(450, 400);

        btnPlay.addListener(new InputListener() {

            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

                return true;
            }

            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {

                new Game()
                dispose();

            }
        });

    btnExit = new TextButton("Exit", style);
    btnExit.setSize(350,150);
    btnExit.setPosition(450, 150);

    btnExit.addListener(new InputListener() {

        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

            return true;
        }

        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {

            Gdx.app.exit();
            dispose();

        }
    });

    stage.addActor(btnPlay);
    stage.addActor(btnExit);

}

@Override
public void render(float delta) {

    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    Gdx.gl.glClearColor(0, 0, 0, 1);

    batch.setProjectionMatrix(cam.combined);

    stage.act();

    batch.begin();
    stage.draw();
    batch.end();

}

@Override
public void dispose() {
    batch.dispose();
    stage.dispose();
    atlas.dispose();
    skin.dispose();
    font.dispose();

}
\$\endgroup\$
2

1 Answer 1

2
\$\begingroup\$

One way of doing this that's quite easy is to let there be a single class that extends Game, that launches the first Screen (this is pretty much what you have).

What you also need to do though is to pass a reference to that Game to all your Screens so that they can call setScreen themselves when they want to go to another screen.

In a somewhat simplified example the root would the the Game class, in your code this is Screens;

package com.androidstudiosandbox;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;

public class MyAndroidStudioSandboxGame extends Game {
  @Override
    public void create () {
        setScreen(new SplashScreen(this));
    }

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

As you can see, this calls setScreen in the create passing an instance to the SplashScreen;

package com.androidstudiosandbox;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.utils.TimeUtils;

public class SplashScreen implements Screen {

    private Game game;
    private long showTime;

    public SplashScreen(Game game) {
        this.game = game;
    }

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

        if (TimeUtils.timeSinceMillis(showTime) > 2000) {
            game.setScreen(new MenuScreen(game));
        }
    }

    @Override
    public void show() {
        showTime = TimeUtils.millis();
    }

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

    @Override
    public void pause() { }

    @Override
    public void resume() { }

    @Override
    public void hide() { }

    @Override
    public void dispose() { }
}

As the SplashScreen has a reference to the initial Game instance, it can call game.setScreen when the time has elapsed and pass a new instance of a MenuScreen that also gets the Game instance passed;

package com.androidstudiosandbox;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;

public class MenuScreen implements Screen {

    private final Stage stage;

    public MenuScreen(final Game game) {

        stage = new Stage();
        Gdx.input.setInputProcessor(stage);

        TextButton button = new TextButton("My button", some_skin);
        button.addListener(new ClickListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                game.setScreen(new GameScreen(game));
            }
        });

        stage.addActor(button);
    }

    @Override
    public void show() { }

    @Override
    public void render(float delta) {
        stage.act(delta);

        Gdx.gl.glClearColor(1, 1, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        stage.draw();
    }

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

    @Override
    public void pause() { }

    @Override
    public void resume() { }

    @Override
    public void hide() { }

    @Override
    public void dispose() { }
}

The MenuScreen sets up a Stage and a TextButton and wires up the click handler of the button to call setScreen when the button is pressed. Note that the game argument to the constructor needs to be final here as the click handler is a seperate class.

package com.androidstudiosandbox;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.utils.TimeUtils;


public class GameScreen implements Screen {
    private Game game;

    public GameScreen(Game game) {
        this.game = game; // Store this to call game.setScreen(new MenuScreen(game)) to return to the menu
    }

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

        // Do game logic and rendering
    }

    @Override
    public void show() { }

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

    @Override
    public void pause() { }

    @Override
    public void resume() { }

    @Override
    public void hide() { }

    @Override
    public void dispose() { }
}

The actual game play is then handled by the GameScreen, this class also takes a reference to Game so that the player can return to the MenuScreen again (that part I've left out though).

\$\endgroup\$
4
  • \$\begingroup\$ You do not need to pass Game as a reference since the ApplicationListener can be accessed by Gdx.app.getApplicationListener() and casted as Game. So ((Game)Gdx.app.getApplicationListener()).setScreen(new MyScreen()); would be enough whenever you want to change screen. \$\endgroup\$
    – Madmenyo
    Feb 12, 2016 at 13:21
  • \$\begingroup\$ Yeah but Im getting this error: com.mygdx.game.Screens cannot be cast to com.mygdx.game.Game \$\endgroup\$
    – gafflx
    Feb 15, 2016 at 17:40
  • \$\begingroup\$ @gafflx Don't cast it to your Game class, you need to cast it to the libGDX Game class. \$\endgroup\$
    – bornander
    Feb 16, 2016 at 6:32
  • \$\begingroup\$ @bornander like so: public class Screens extends com.badlogic.gdx.Game ? \$\endgroup\$
    – gafflx
    Feb 16, 2016 at 15:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .