#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} }