[LibGDX] Text Input listener.

    So I made a little 3 rank high score system out of pure messines and that is working correctly for the most part. The part that I cannot figure out is how in the heck to get input from the android user.

Here is my full code sorry for the mess (It’s 4:26 am) and I’ve been working on trying to fix this for the past few hours.
Ignore most of the dang nab nonsense, especially if its nonsense. It’s just me trying to figure out how in the heck to get text input.

EDIT: Removed curse words, sorry im tired.

if(!gameProcessor.player.isAlive()){
				if(gameProcessor.asteroidsDestroyed > HighScore1){
					HighScore3 = HighScore2;
				    scorePreferences.putInteger("score3", HighScore3);
				    HighScore2 = HighScore1;
				    scorePreferences.putInteger("score2", HighScore2);
					HighScore1 = gameProcessor.asteroidsDestroyed;
					scorePreferences.putInteger("score1", HighScore1);
					MyTextListener listener = new MyTextListener();
					Gdx.input.getTextInput(listener , "New High Score!", "Input your name", "Your name");
				        HighScoreName1 = listener.input;
					scorePreferences.flush();
                                        loopMusic.stop();
					gameCore.setScreen(this);
					
					}
				}
				else if(gameProcessor.asteroidsDestroyed > HighScore2){
					HighScore3 = HighScore2;
					scorePreferences.putInteger("score3", HighScore3);
					HighScore2 = gameProcessor.asteroidsDestroyed;
					scorePreferences.putInteger("score2", HighScore2);
					MyTextListener listener = new MyTextListener();
					HighScoreName2 = null;
					Gdx.input.getTextInput(listener, "New High Score!", "Input your name", "Your name");
					HighScoreName2 = listener.returnText();
					scorePreferences.putString("name2", HighScoreName2);
					loopMusic.stop();
				        scorePreferences.flush();
				        gameCore.setScreen(this);
					}
				}
				else if(gameProcessor.asteroidsDestroyed > HighScore3){
					HighScore3 = gameProcessor.asteroidsDestroyed;
					scorePreferences.putInteger("score3", HighScore3);
					MyTextListener listener = new MyTextListener();
					Gdx.input.getTextInput(listener, "New High Score!", "Input your name", "Your name");
					HighScoreName3 = listener.returnText();
					HighScoreName3 = null;
					scorePreferences.putString("name3", HighScoreName3);
					loopMusic.stop();
					
					
					if(listener.hasInputed = true){
						scorePreferences.flush();
						gameCore.setScreen(this);
					}
				}
				else{
					loopMusic.stop();
					gameCore.setScreen(this);
				}
			}
		
		}

Also, I just used the basic template from this thing

	private String newText;

	@Override
	public void input(String text) {
		System.out.println(text);
		newText = text;
	}

	@Override
	public void canceled() {
		System.out.println("Canceled");
	}
	
	public String getText(){
		return newText;
	}

The input method is called after you press “okay”.
The canceled is called after you cancel the dialog (“cancel”, quit button, escape).

				Gdx.input.getTextInput(listener, "New High Score!", "Input your name", "Your name");
				if (listener.getText() != null)
				{
					HighScoreName2 = listener.getText();
					System.out.println(HighScoreName2);
					...
					..
					.
				}

Or you can use TextField (txtField.getText()): http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/TextField.html

I tried doing that and the game is still going ahead and restarting the game withought me pressing ok after I input my text. The game restarts with gameCore.setScreen(this);. When I now reach the the top score all 3 score inputs get executed, I thought if else was supposed to stop this? And finally, now the game isn’t even accepting my high scores, the table always stays at 0 which I suppose means the preference aren’t flushing.


	if(!gameProcessor.player.isAlive()){
				if(gameProcessor.asteroidsDestroyed > HighScore1){
					HighScore3 = HighScore2;
				    scorePreferences.putInteger("score3", HighScore3);
				    HighScore2 = HighScore1;
				    scorePreferences.putInteger("score2", HighScore2);
					HighScore1 = gameProcessor.asteroidsDestroyed;
					scorePreferences.putInteger("score1", HighScore1);
					MyTextListener listener = new MyTextListener();
					Gdx.input.getTextInput(listener , "New High Score!", "Input your name", "Your name");
					
					if(listener.returnText() != null){
						HighScoreName1 = listener.returnText();
						scorePreferences.putString("name1", HighScoreName1);
						scorePreferences.flush();
						loopMusic.stop();
						gameCore.setScreen(this);
					}
				}
				
				else if(gameProcessor.asteroidsDestroyed > HighScore2){
					HighScore3 = HighScore2;
					scorePreferences.putInteger("score3", HighScore3);
					HighScore2 = gameProcessor.asteroidsDestroyed;
					scorePreferences.putInteger("score2", HighScore2);
					MyTextListener listener = new MyTextListener();
					Gdx.input.getTextInput(listener, "New High Score!", "Input your name", "Your name");
					
					if(listener.returnText()!= null){
					HighScoreName2 = listener.returnText();
					scorePreferences.putString("name2", HighScoreName2);
					loopMusic.stop();
					scorePreferences.flush();
					gameCore.setScreen(this);
						}
					}
				else if(gameProcessor.asteroidsDestroyed > HighScore3){
					HighScore3 = gameProcessor.asteroidsDestroyed;
					scorePreferences.putInteger("score3", HighScore3);
					MyTextListener listener = new MyTextListener();
					Gdx.input.getTextInput(listener, "New High Score!", "Input your name", "Your name");
					
					if(listener.returnText() != null){
					HighScoreName3 = listener.returnText();
					scorePreferences.putString("name3", HighScoreName3);
					loopMusic.stop();
					scorePreferences.flush();
					gameCore.setScreen(this);
						}
					}
				
				else{
					loopMusic.stop();
					gameCore.setScreen(this);
				}
		}

This code is in your update() loop?

Because you need to set the scorePreferences and change the HighScore1, 2, 3 only once.
If “asteroidsDestroyed > HighScore1”, your HighScore2 will receive the old HighScore1 value, so in the next loop the “asteroidsDestroyed > HighScore2” will return true and will create a listener again (“When I now reach the the top score all 3 score inputs get executed”).
And the screen is restarted because after doing this, the code enter in the last Else. I think you can solve this with only one boolean variable to allow your save state to be executed once.

//Global vars
private boolean isScoreSaved = false; //not saved
private int scorePosition = 0; //Only to know which Highscore was saved
private MyTextListener listener = new MyTextListener();


....................


	if(!gameProcessor.player.isAlive() && !isScoreSaved) //only if score not saved
	{
		if(gameProcessor.asteroidsDestroyed > HighScore1)
		{
		   HighScore3 = HighScore2;
		   scorePreferences.putInteger("score3", HighScore3);
		   HighScore2 = HighScore1;
		   scorePreferences.putInteger("score2", HighScore2);
		   HighScore1 = gameProcessor.asteroidsDestroyed;
		   scorePreferences.putInteger("score1", HighScore1);
		   Gdx.input.getTextInput(listener , "New High Score!", "Input your name", "Your name");
		   
		   isScoreSaved = true;
		   scorePosition = 1;
		}
		
		else if(gameProcessor.asteroidsDestroyed > HighScore2)
		{
		   HighScore3 = HighScore2;
		   scorePreferences.putInteger("score3", HighScore3);
		   HighScore2 = gameProcessor.asteroidsDestroyed;
		   scorePreferences.putInteger("score2", HighScore2);
		   Gdx.input.getTextInput(listener, "New High Score!", "Input your name", "Your name");
		   
		   isScoreSaved = true;
		   scorePosition = 2;
		}
		   
		else if(gameProcessor.asteroidsDestroyed > HighScore3)
		{
		   HighScore3 = gameProcessor.asteroidsDestroyed;
		   scorePreferences.putInteger("score3", HighScore3);
		   Gdx.input.getTextInput(listener, "New High Score!", "Input your name", "Your name");
		   
		   isScoreSaved = true;
		   scorePosition = 3;
		}
		   
		else //No highscore
		{
		   loopMusic.stop();
		   gameCore.setScreen(this);
		}
	}
	else if (!gameProcessor.player.isAlive() && isScoreSaved) //if score was saved
	{
		if(listener.returnText() != null)
		{
			if (scorePosition == 1)
				scorePreferences.putString("name1", listener.returnText());
			else if (scorePosition == 2)
				scorePreferences.putString("name2", listener.returnText());
			else if (scorePosition == 3)
				scorePreferences.putString("name3", listener.returnText());
				
			loopMusic.stop();
			scorePreferences.flush();
			gameCore.setScreen(this);
		}
	}

I wish I could give you multiple medals for this. Thank you for teaching me a new way of thinking! ;D

Quick question though, how does this work??? I thought you needed bracket for if statements

 if (scorePosition == 1)
		            scorePreferences.putString("name1", listener.returnText());
		         else if (scorePosition == 2)
		            scorePreferences.putString("name2", listener.returnText());
		         else if (scorePosition == 3)
		            scorePreferences.putString("name3", listener.returnText());

If you have only one instruction inside of if statement (works with other statements), you don’t need to use brackets. :smiley:

//One instruction
if (x > 0)
	x = 0;
else
	x = 1;
	
//Two or more instructions
if (x > 0)
{
	x = 0;
	System.out.println(x);
}
else
{
	x = 1;
	System.out.println(x);
}

There is still on thing that is bothering me though, the game is still restarting before asking for the input.

Skipping the curly brackets for single statements is widely regarded as a bad practice, as you are likely to add another statement overlooking the fact it is not enclosed by the if.

I wasn’t on planning on using that way anyways. It seemed like it would get confusing very quickly.

We have only two “setScreen”.

The only way the game can change the screen before the input is here:

      else //No highscore
      {
         loopMusic.stop();
         gameCore.setScreen(this);
      }

This only happens if the gameProcessor.asteroidsDestroyed <= HighScore3.

The second way, only executes if isScoreSaved == true AND if listener.returnText() != null.

Can you show your listener.returnText()?

Edit-
I tested here and is working (desktop version).

This is my returnText() in my Text input listener

public String returnText(){
		return input;
	}

I’m also now trying to organize my High score names so that they drop down with their points too. Current problem is that if I get a 1st place high score and write my name, then get a 2nd place high score, the 1st place name still drops down to the 2nd place leaving the 1st place without a name. Sorry if I frankensteined your code, I’m going full on rage mode on it (plus im stupid).

else if (!gameProcessor.player.isAlive() && isScoreSaved) //if score was saved
		   {
			 if (scorePosition == 1){
		            HighScoreName3 = HighScoreName2;
		            scorePreferences.putString("name3", HighScoreName3);
		            HighScoreName2 = HighScoreName1;
		            scorePreferences.putString("name2", HighScoreName2);
		            scorePreferences.putString("name1", listener.returnText());
		            isScoreSaved = false;
		            gameCore.setScreen(this);
		         }
		       if (scorePosition == 2){
		            HighScoreName3 = HighScoreName2;
		            scorePreferences.putString("name3", HighScoreName3);
		            scorePreferences.putString("name2", listener.returnText());
		            isScoreSaved = false;
		            gameCore.setScreen(this);
		         }
		        if (scorePosition == 3){
		            scorePreferences.putString("name3", listener.returnText());
		            isScoreSaved = false;
		            scorePosition = 0;
		            gameCore.setScreen(this);
		   
		         }
		            
		         loopMusic.stop();
		         scorePreferences.flush();
		        
		   }

No problem, I forgot about the other Highscore names xD.
By the way, in your Override input() method in your myTextInputListener you are setting input = text, right?

You need to check if(listener.returnText() != null), your input will only receive the string value after you hit “Okay”, before that it always returns null. So, the screen will restart ONLY after you press “okay” button in dialog. Your current code is saving null in your scorePreferences.

I tested this and is working, you can write your name and after you click on “OK” button, the screen is restarted (now with your changing name code).

else if (!gameProcessor.player.isAlive() && isScoreSaved) //if score was saved
         {
			 if(listener.returnText() != null)
			 {
				if (scorePosition == 1){
					  HighScoreName3 = HighScoreName2;
					  scorePreferences.putString("name3", HighScoreName3);
					  HighScoreName2 = HighScoreName1;
					  scorePreferences.putString("name2", HighScoreName2);
					  HighScoreName1 = listener.returnText();
					  scorePreferences.putString("name1", HighScoreName1);
				   }
				 if (scorePosition == 2){
					  HighScoreName3 = HighScoreName2;
					  scorePreferences.putString("name3", HighScoreName3);
					  HighScoreName2 = listener.returnText();
					  scorePreferences.putString("name2", HighScoreName2);
				   }
				  if (scorePosition == 3){
				  HighScoreName3 = listener.returnText();
					  scorePreferences.putString("name3", HighScoreName3);
				   }
				scorePreferences.flush();	  
				loopMusic.stop();   
				gameCore.setScreen(this);
			}
         }

BTW, This prints “null” in console before you click on “ok”: System.out.println(listener.returnText());

Works perfectly now, thanks again! Well, also we forgot to set the isScoreSaved back to false after we set the names. Or else my game just gets stuck in the play State. ;D ;D

Ok so I noticed that when the dialogue to enter your name comes up, you can press the cancel button which will do nothing but glitch out my game and make you invincible. I can’t figure out how to make the game go back to the menu screen if a person accidentaly presses that button.

According to the wiki:

[quote]The canceled() method will be called if the user closed the dialog on the desktop or pressed the back button on Android.
[/quote]
And that is indeed true. Meaning, nothing gets called if I press the cancel button on the dialogue on android. So how would I make that button return something?

Are you overriding the cancelled method in the input listener? You can override it to do something when it gets called.

I might be interpreting your question incorrectly. Is the method not actually getting called or just not doing anything?

The text input listener has no method for getting a notification of wether the cancel button has been pressed when the dialogue is up. An example is the picture below, the user can enter their name and press ok and be brought back to the menu and restart, but there is no method that I can find that makes the cancel button do something instead of just close the dialogue. I would like to know when that button is pressed to return back to the menu as well.

Can you not just put your own code inside the implementation of the listener? So inside public void cancelled() you could put something like


public void cancelled(){
    game.setScreen(new MainMenu(game));
}

This is if i’m understanding the issue

Yes, I can. The problem is though, that that method only responds to closing the dialogue on desktop or pressing the back button on the android device, not hitting that cancel button.