[LibGdx] Initializing variables.

Should I initialize the instance variables in my constructor or in show() method. Is there any effect where should I initialize them?

private BitmapFont font;
private Stage stage;
private Skin skin;
private Table table;
private TextureAtlas buttonAtlas;

private TextButton[] button;
private TextButton.TextButtonStyle textButtonStyle;

public MenuScreen(MyGame game) {
    super(game);
}

@Override
public void show() {
    super.show();

}

The constructor gets called first, then show. I don’t think there’s a difference, both should work.

edit: except if you store screen instantiation. which I normally don’t, I just call new GameScreen()

I’m not sure I understand what you’re asking, the constructor gets only called once, show() gets called every time the screen is shown again.

If you want them to be initialized only once, put them in the constructor, if you want to do it every time your main screen gets shown, do it in show().

This code is what I use, it provides a simple way to do everything. Explanation is below the code.

Base classes:

CustomGame.java


import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.utils.ObjectMap;

/**
 * @author Ivan Vinski
 * @since 1.0
 */
public abstract class CustomGame implements ApplicationListener {
  public enum State {
    ALL_GOOD, NOT_INITIALIZED, TO_RESET
  }

  private ObjectMap<Class<?>, CustomScreen> screens = new ObjectMap<Class<?>, CustomScreen>();
  private ObjectMap<Class<?>, State> states = new ObjectMap<Class<?>, State>();
  private CustomScreen screen;

  public final boolean registerScreen(CustomScreen screen) {
    Class<?> clazz = screen.getClass();
    if (screens.containsKey(clazz)) {
      return false;
    }
    screens.put(clazz, screen);
    states.put(clazz, State.NOT_INITIALIZED);
    return true;
  }

  @Override
  public void render() {
    Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
    if (screen != null) {
      screen.render(Gdx.graphics.getDeltaTime());
    }
  }

  @Override
  public void resize(int width, int height) {
    if (screen != null) {
      screen.resize(width, height);
    }
  }

  @Override
  public void pause() {
    if (screen != null) {
      screen.pause();
    }
  }

  @Override
  public void resume() {
    if (screen != null) {
      screen.resume();
    }
  }

  @Override
  public void dispose() {
    for (CustomScreen screen : screens.values()) {
      State state = states.get(screen.getClass());
      if (state != State.NOT_INITIALIZED) {
        screen.dispose();
      }
    }
  }

  public CustomScreen getScreen() {
    return screen;
  }

  public <T extends CustomScreen> void setScreen(Class<T> clazz) {
    if (screen != null) {
      screen.hide();
      Gdx.input.setInputProcessor(null);
    }

    screen = screens.get(clazz);

    if (screen != null) {
      State state = states.get(clazz);
      if (state == State.NOT_INITIALIZED) {
        screen.init(this);
        states.put(clazz, State.ALL_GOOD);
      } else if (state == State.TO_RESET) {
        screen.dispose();
        screen.init(this);
        states.put(clazz, State.ALL_GOOD);
      }
      screen.show();
      Gdx.input.setInputProcessor(screen.input());
    }
  }

  public <T extends CustomScreen> void resetScreen(Class<T> clazz) {
    if (screens.containsKey(clazz)) {
      states.put(clazz, State.TO_RESET);
    }
  }

  public static CustomGame getInstance() {
    return getInstance(CustomGame.class);
  }

  public static <T extends CustomGame> T getInstance(Class<T> castTo) {
    return (T) Gdx.app.getApplicationListener();
  }
}

CustomScreen.java


import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;

/**
 * @author Ivan Vinski
 * @since 1.0
 */
public interface CustomScreen extends Screen {
  void init(CustomGame game);

  InputProcessor input();
}

Implementations:

Implementation of CustomGame.java


/**
 * @author Ivan Vinski
 * @since 1.0
 */
public class MyGame extends CustomGame {
  @Override
  public void create() {
    registerScreen(new ScreenA());
    registerScreen(new ScreenB());
    setScreen(ScreenA.class);
  }
}

Implementation of CustomScreen.java


import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

/**
 * @author Ivan Vinski
 * @since 1.0
 */
public class ScreenA extends InputAdapter implements CustomScreen {
  private Batch batch;
  private OrthographicCamera camera;
  private Texture texture;
  private float x, speed;

  @Override
  public void init(CustomGame game) {
    batch = new SpriteBatch();
    camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    camera.position.set(camera.viewportWidth / 2f, camera.viewportHeight / 2f, 0f);
    texture = new Texture(Gdx.files.internal("badlogic.jpg"));
    speed = 10f;
  }

  @Override
  public void show() {
    x = 0f;
  }

  @Override
  public void render(float delta) {
    camera.update();
    x += speed * delta;

    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    batch.draw(texture, x, 0);
    batch.end();
  }

  @Override
  public void hide() {
    speed *= 2;
  }

  @Override
  public void dispose() {
    batch.dispose();
    texture.dispose();
  }

  @Override
  public InputProcessor input() {
    return this;
  }

  @Override
  public boolean keyDown(int keycode) {
    if (keycode == Input.Keys.ESCAPE) {
      MyGame.getInstance().setScreen(ScreenB.class);
      return true;
    }

    return super.keyDown(keycode);
  }

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

  @Override
  public void pause() {
  }

  @Override
  public void resume() {
  }
}

Explanation:
As you see in the examples (implementations), you need to call registerScreen(CustomScreen) method to be able to setScreen(Class<T extends CustomScreen>) to that screen. You can always call getInstance() to access the CustomGame easily or you can call getInstance(Class<T extends CustomGame>) to automatically cast it to your implementation of CustomGame meaning that you can access any non-static variables easily.

setScreen(Class<T extends CustomScreen>) method takes care of everything depending on the state it’s in and it automatically sets the input to the InputProcessor specified in screen’s input() method. You can easily reset any screen by calling resetScreen(Class<T extends CustomScreen>), but it needs to be called before setScreen(Class<T extends CustomScreen>) method since that method determines should it initialize or reset screen.

Also, screen is cleared automatically before calling render(float) method and all screens are disposed automatically if they have been initialized.