How to properly implement a dialog using libgdx

I am trying to implement a dialog box in my program. The main program does not use a scene. However, when users live at 0, I would like to open a dialog that will either restart the game or exit the game.

I created a separate class for Dialog using the following code.

public class GameOver { //dialog game over private Dialog dlgGameOver; private Skin skin; private Stage stage; private TextButton btnMain; private TextButton btnTryAgain; private GameScreen gameScreen; public GameOver(final GameScreen gameScreen){ //create the game over dialog this.gameScreen = gameScreen; skin = new Skin(Gdx.files.internal("uiskin.json")); dlgGameOver = new Dialog(" ",skin); stage = new Stage(); btnMain = new TextButton("Main", skin); btnTryAgain = new TextButton("Try Again", skin); dlgGameOver.text("Game over!"); dlgGameOver.button(btnTryAgain); dlgGameOver.button(btnMain); dlgGameOver.show(stage); btnMain.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { System.out.println("Button Pressed"); } }); btnTryAgain.addListener(new ChangeListener() { @Override public void changed(ChangeEvent event, Actor actor) { gameScreen.setIntLives(3); gameScreen.setIntScore(0); System.out.println("Button Pressed"); } }); Gdx.input.setInputProcessor(stage); } public Stage getStage() { return stage; } } 

The main screen of the game does not use a scene. In the update method, I create a GameOver class if the liver is at 0

 if(intLives == 0) { if(!boolGameOver) { dlgGameOver = new GameOver(this); boolGameOver = true; } else if(intLives !=0) { boolGameOver = false; } } 

In the rendering method, I draw a scene

 if(intLives == 0) { dlgGameOver.getStage().draw(); } else { //<rest of normal update code follows here> } 

This works great the first time you create a dialog. When you restart the game will restart (or actually reset the score and life). However, the second time you run out of life, the dialog is displayed as expected, but the buttons will not work. Somehow it seems that the second time the clicker is not initialized.

Am I doing something fundamentally wrong here? If my approach is completely wrong, I am also glad to hear it.

+5
source share
1 answer

The Dialog class is a little unintuitive without looking closer.

This is why I provide a small working example:

 import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Dialog; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.utils.Timer; import com.badlogic.gdx.utils.Timer.Task; public class TestGame extends ApplicationAdapter { Dialog endDialog; Skin skin; Stage stage; @Override public void create() { skin = new Skin(Gdx.files.internal("uiskin.json")); stage = new Stage(); Gdx.input.setInputProcessor(stage); endDialog = new Dialog("End Game", skin) { protected void result(Object object) { System.out.println("Option: " + object); Timer.schedule(new Task() { @Override public void run() { endDialog.show(stage); } }, 1); }; }; endDialog.button("Option 1", 1L); endDialog.button("Option 2", 2L); Timer.schedule(new Task() { @Override public void run() { endDialog.show(stage); } }, 1); } @Override public void render() { Gdx.gl.glClearColor(1, 0, 0, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); stage.act(); stage.draw(); } @Override public void dispose() { stage.dispose(); } } 

Each time you click on the "Dialog" parameter (option 1 or option 2), the result object is printed on system.out (here 1L or 2L, it can be any object), and the dialog is displayed again after 1 second.

uiskin is taken from libgdx tests.

To adapt it more to your needs, you can change the result method to:

 protected void result(Object object) { if (object.equals(1L)) { gameScreen.setIntLives(3); gameScreen.setIntScore(0); System.out.println("Button Pressed"); } else { // Goto main menut } }; 

And add the following buttons:

 endDialog.button("Retry", 1L); endDialog.button("Main Menu", 2L); 

Note that the Dialog class is created only once. (so my comment was not right)


Just to give you an idea of ​​what you can do with it:

Since any object can be used, you can use reflection:

 try { endDialog.button("doX", ClassReflection.getDeclaredMethod(this.getClass(), "doX")); endDialog.button("doY", ClassReflection.getDeclaredMethod(this.getClass(), "doY")); } catch (ReflectionException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

And the result will look like this:

 protected void result(Object object) { try { ((Method) object).invoke(TestGame.this); } catch (ReflectionException e) { // TODO Auto-generated catch block e.printStackTrace(); } }; 

Now you just need to implement these methods:

 public void doX() { System.out.println("doX"); } public void doY() { System.out.println("doY"); } 

Just to give you some ideas.

+7
source

Source: https://habr.com/ru/post/1233459/


All Articles