1
\$\begingroup\$

I'm making a JRPG in libGDX, and I'm working with Screens. I have a main Screen called GameScreen, a screen for battles called BattleScreen and I want to make a screen for managing party members and items, as well as for shops. My question is, how can I draw one of those 3 screens without having to reload the whole game when going back to GameScreen.

GameScreen loads everything when Show() is called, so I'll have to save all information everytime I call another screen, so I can continue when I go back to GameScreen. This of course isn't good, and I'm looking for another way to draw a Screen over another one so that all vars wont be lost, or another solution.

\$\endgroup\$
  • 1
    \$\begingroup\$ Why would you load the screen date in the Show method? Show is called every time the screen is shown, it's obviously not the right place to load the data your screen need. Load the data in the screen constructor or in the Init method and you should be fine. \$\endgroup\$ – nathan Dec 4 '15 at 14:44
  • \$\begingroup\$ Show() is the initializer for a Screen object. There is also Create() but that one will also be called when I want to switch back to the Game Screen. \$\endgroup\$ – GigaNova Dec 4 '15 at 19:01
1
\$\begingroup\$

Carry your relevant variables/screens in other's screen using constructors. For example.

//main class extending Game class of libgdx
public class mygame extends Game { 

public String var1="i will use it in screen1";
public String var2="i will use it in screen2";

Screen1 scn1;  //instantiating screen 1
Screen2 scn2;  // instantiating screen 2

public void create() {
scn1=new Screen1(this);  //scn1 object will be associated with same instance of this class
scn2=new Screen2(this); //scn2 object will be associated with same instance of this class

   setScreen(scn1);
}

 public void render() {
        super.render(); //important!
    }

public void dispose() {
//dispose
}  
}



//Screen1 class
public class Screen1 implements Screen{
mygame game;

public Screen1(mygame mg)
{
game=mg;
}

@Override
public void render(float delta) {
System.out.println("using game class variable var1:"+game.var1);
game.setScreen(game.scn2);  //calling screen 1
}
@Override
    public void resize(int width, int height) {}
@Override
    public void show() {}
    @Override
    public void hide() {}
    @Override
    public void pause() {}
    @Override
    public void resume() {}
    @Override
    public void dispose() {}
}


//Screen2 class
public class Screen2 implements Screen{
mygame game;

public Screen2(mygame mg)
{
game=mg;
}

@Override
public void render(float delta) {
System.out.println("using game class variable var2:"+game.var2);
game.setScreen(game.scn1); //calling back screen 1
}
@Override
    public void resize(int width, int height) {}
@Override
    public void show() {}
    @Override
    public void hide() {}
    @Override
    public void pause() {}
    @Override
    public void resume() {}
    @Override
    public void dispose() {}
}
\$\endgroup\$
  • \$\begingroup\$ This wont work as I have alot of work done in the seperate show() of every screen, so everytime I switch between them it creates everything all over again, using alot of memory and also not working like I want it to. \$\endgroup\$ – GigaNova Dec 6 '15 at 22:04
  • \$\begingroup\$ @GigaNova I would recommend moving away from the LibGDX Game class and would instead recommend the ApplicationListener interface as it works a lot better :) \$\endgroup\$ – Ammar Tarajia Dec 23 '15 at 14:01
  • \$\begingroup\$ @AmmarTarajia you do know that Game extends ApplicationListener? \$\endgroup\$ – GigaNova Dec 23 '15 at 14:08
  • \$\begingroup\$ @GigaNova Sorry about that, I'm thinking of another library that was similar to LibGDX. The interface was called Application so I got that wrong as well. Wow. \$\endgroup\$ – Ammar Tarajia Dec 23 '15 at 14:12
1
\$\begingroup\$

Solution

An easy and efficient way to manage screens is by using an enum which stores multiple constants. This is useful as you can refer to each screen with a meaningful name such as MENU instead of assigning a numerical index. This is also advantageous to other solutions as it is much simpler than other built-in systems such as the Scene2D system and can also be used for 3D games and multi-purpose applications.

Example:

public enum Screen {
    MENU,
    IN-GAME,
    BATTLE,
    INVENTORY
}

private Screen screen = Screen.MENU;

public void render() throws IllegalStateException {
    switch(screen) {
    case MENU:
        Menu.render();
        break;

    //Other cases here    

    default:
        throw new IllegalStateException();
}
\$\endgroup\$
0
\$\begingroup\$

How do you manage your Screens? If you use com.badlogic.gdx.Game class, it just calls screen.hide() on the previous screen and screen.show() on the next screen.

/** Sets the current screen. {@link Screen#hide()} is called on any old screen, and {@link Screen#show()} is called on the new
 * screen, if any.
 * @param screen may be {@code null} */
public void setScreen (Screen screen) {
    if (this.screen != null) this.screen.hide();
    this.screen = screen;
    if (this.screen != null) {
        this.screen.show();
        this.screen.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    }
}

So you should move your initialization to any other method than show() e.g. init()

public class MyGame extends Game
{
    GameScreen gameScreen;
    BattleScreen battleScreen;

    public void create ()
    {
        gameScreen = new GameScreen();
        gameScreen.init();
        battleScreen = new BattleScreen();

        setScreen(gameScreen);
    }

    // when you need to show the BattleScreen
    setScreen(battleScreen);

    // when you need to show the GameScreen again with all loaded resources and states
    setScreen(gameScreen);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.