Libgdx: как вернуться к предыдущему экрану

#java #libgdx

Вопрос:

Я работаю над игрой, и на начальном этапе я хочу, чтобы пользователь мог свободно переключаться между двумя/тремя экранами.
Из того, что я видел в Интернете, вы переключаете экраны, вызывая функцию setScreen в своем игровом экземпляре. Проблема в том, что, похоже, это работает только тогда, когда вы передаете новый экземпляр экрана в качестве параметра (я пытался передать весь экран на новый экран B, но вызов MyGame.setScreen(A), пока на B ничего не делает), и я хотел бы сохранить изменения, примененные пользователем, даже после того, как он покинет экран.
Я думал о хранении этой информации в классе, который я буду передавать в качестве параметра каждый раз, когда пользователь переключает экраны, но это решение кажется неэффективным и неправильным.
Существует ли какой-либо стандартный способ вернуться к предыдущему экрану без потери всех внесенных в него изменений? Работает ли MyGame.setScreen только на новых экземплярах экрана?

Вот код, который я пытался использовать, чтобы вернуться к старому экрану :

 public class TroopPlacingScreen implements Screen { private final Game game; OrthographicCamera camera; private final GameScreen gameScreen; private final int XSIZE=1000, YSIZE=500; private Stage stage; private long lastClick; private ImageButton saveAndContinue;  public TroopPlacingScreen(Game game, GameScreen gameScreen){  this.game=game;  camera= new OrthographicCamera();  camera.setToOrtho(false, XSIZE, YSIZE);  stage= new Stage(new ScreenViewport(), game.batch);  lastClick= TimeUtils.millis();  Sprite sprite= new Sprite(new   Texture(Gdx.files.internal("saveImage.png")));  SpriteDrawable spriteDrawable= new SpriteDrawable(sprite);  saveAndContinue= new ImageButton(spriteDrawable);  saveAndContinue.setSize(100,100);   saveAndContinue.setPosition(Gdx.graphics.getWidth()-250,   Gdx.graphics.getHeight()-100);  stage.addActor(saveAndContinue); }   @Override public void show() {  }  @Override public void render(float delta) {  ScreenUtils.clear(0, 0, 0, 1);  camera.update();  game.batch.setProjectionMatrix(camera.combined);  game.batch.begin();  game.batch.end();  stage.addActor(saveAndContinue);  if(saveAndContinue.isPressed()){  game.setFirstTurn(false);  game.setScreen(gameScreen);  }  }  stage.act();  stage.draw(); }  @Override public void resize(int width, int height) {  stage.getViewport().update(width, height, true); }  @Override public void pause() {  }  @Override public void resume() {  }  @Override public void hide() {  }  @Override public void dispose() {  } }  

Как я уже сказал, это было очень просто, и чтобы заставить его работать, я попытался также вызвать this.dispose() , gameScreen.show() , gameScreen.render() , и все возможные перестановки этих функций, когда была нажата кнопка saveAndContinue, но ничего не сработало.

Комментарии:

1. Вызов setScreen метода с уже созданным экраном должен сработать. Если вы отредактируете свой вопрос и добавите код, который не работает, мы можем обнаружить там проблему.

Ответ №1:

В соответствии с вашим кодом вы передаете gameScreen конструктор to, но не инициализируете переменную класса. Поэтому при вызове game.setScreen(gameScreen); вы передаете null вместо фактического экземпляра экрана.

Чтобы ваш код работал, просто инициализируйте переменную класса в конструкторе.

 this.gameScreen = gameScreen;  

Кроме того, лучше хранить экземпляры экрана в Game классе и иметь там метод, например setScreen() , который будет принимать перечисление экранов вместо того, чтобы передавать экземпляры экрана друг другу.

 public class MyGame extends Game {   // Make sure to initialize your screens  private ScreenA screenA;  private ScreenB screenB;   /** ... **/   public void setScreen(ScreenKey screenKey) {  switch(screenKey) {  case ScreenKey.A:  setScreen(screenA);  break;  case ScreenKey.B:  setScreen(screenB);  break;  }  }   public enum ScreenKey {A, B} }  

Затем в ScreenA вы можете использовать следующую инструкцию для переключения на ScreenB :

 game.setScreen(ScreenKey.B)  

Вместо оператора switch у вас также может быть карта Maplt;ScreenKey, Screengt; .

 public class MyGame extends Game {   // Make sure to initialize your screens  private Maplt;ScreenKey, Screengt; screens;   /** ... **/   public void setScreen(ScreenKey screenKey) {  setScreen(screens.get(screenKey));  }   public enum ScreenKey {A, B} }