# Frage bzgl. TextAdventure



## psychoblade (14. Dez 2011)

Hallo Java Community,

ich möchte ein TextAdventure programmieren welches folgendermaßen aufgebaut ist.

Ein JFrame ist mit einem JLabel des Raumes belegt in welchen man ist.
Desweiteren wird eine JTextArea zur Textausgabe genutzt sowie ein JTextField zum einlesen des Befehls.

Nun soll das Spiel folgendermaßen funktionieren : Man ist in einem Raum wo die Frage nach der Aktion gestellt wird, worauf der Spieler sich zwischen 
1.befragen der Personen
1.1 Person a
1.2 Person b
2.Raum wechseln 
2.1 Kaminzimmer
2.2 Küche
entscheiden soll.

Nun zu meinem Problem. Das JTextField wird vom ActionListener(actionperformed methode) überwacht und soll die Befehle einlesen.
 Das ist leider auch das Problem . Wenn die Fallunterscheidung kommt per if , dann soll auf die Eingabe gewartet werden und je nach dem gehandelt werden.
Aber if wartet natürlich nicht darauf wann etwas eingeben wird sondern überprüft einfach was im JTextField steht (sei es null oder der alte eingebe Wert).

Habt ihr einen Tipp wie ich die Programmlogik entweder anhalten kann für die Eingabe im JTextField oder alternativ eine andere Möglichkeit der Programmlogik ?

Vielen Dank im voraus.

mit freundlichen Grüßen psychoblade


----------



## pro2 (14. Dez 2011)

http://www.java-forum.org/java-basics-anfaenger-themen/58848-jtextfield-return-reagieren.html

Sowas z.B.?


----------



## psychoblade (14. Dez 2011)

Nein glaube ich nicht.

Es ist so gemeint:


```
class mylistener implements ActionListener
	{
		
		public void actionPerformed(ActionEvent e)
			{
			  if(field.getText().equals("wechseln") {
                               if(field.getText().equals("Kaminzimmer"){
                               ...mach was...
                          }
                             else if(field.getText().equals("Küche"){
                             ....mach was......
                          }
                     
			}
                        if(field.getText().equals("befragen"){
                        ....mach was.....
                        }
       }
}
```

Das ist das Problem was ich habe.
wenn der Benutzer etwas eingeben hat, dann wird das ganze if durchlaufen und nicht darauf gewartet das etwas neues eingeben wird 

Verständlich irgendwie ? 
Es muss ja eine Möglichkeit geben das ich dieses "Was möchtest du tun " so realisiere das erst wenn etwas eingeben wurde , der mit dem Befehl zusammenhängende Code ausgeführt wird


----------



## pro2 (14. Dez 2011)

Soo ganz versteh ich das Problem immer noch nicht. Aber du könntest auch einfach eine Combo Box verwenden (mit oder ohne zusätzlichen Button) oder mehrere Buttons oder ein Dropdown Menü oder oder oder..
Bei denen könntest du dann einfach die einzelnen Möglichkeiten hinzufügen und je nach Inhalt/ausgewähltem Item deinen Code ausführen. Ist auch irgendwie benutzerfreundlicher 

edit: Ah ok, jetzt hab ich dein Problem endlich verstanden. Muss irgendwie blind gewesen sein.. meine alternativ Vorschläge gelten natürlich immer noch.


----------



## psychoblade (14. Dez 2011)

Hm da Problem bei den Buttons wäre dann das ich diese immer neu zeichnen müsste .

Ich versuche es nochmal ganz trivial zu schildern ^^

Also es soll ein TextAdventure werden was auf folgenden Spielprinzip basiert:

Beispiel:

Was möchtest du tun : Raum wechseln oder jemand befragen ?

--> antwort einlesen

Ok du möchtest den Raum wechseln .Wohin möchtest du gehen ?

1.Raum a
2.Raum b

--> einlesen

Ok was möchtest du tun ? Raum wechseln oder jemand befragen ?


-----------------------------------------------------------------

Dies soll irgendwie mit einem JTextField und JTextArea realisiert werden.

auf der reinen Konsole wäre es kein problem das dort auf die Eingabe gewartet wird.

Wie kann ich dies aber nun mit einem Listener ( vielleicht gibt es noch einen anderen der das kann ??)
machen ?


----------



## pro2 (14. Dez 2011)

Öhm müsste sowas triviales nicht gehen?
Du erstellst dir einen String, nennen wir ihn mal lastText. Den initialisiert du erst einmal mit "". Dann prüfst du am Anfang ob der nicht "" entspricht, falls ja ob der etwa wechseln entspricht und falls das ja, schaust du nach dem aktuellen Text in dem TextField. (z.B. Raum a) Dabei wieder nach dem Funktionsaufruf für Raum a z.B. den String leeren und das Textfeld leeren. 
Falls der String halt "" ist, einfach das Textfeld einlesen.


----------



## psychoblade (14. Dez 2011)

Ansich ein gute Idee wobei ich denke das es an folgendem scheitert .

wenn ich getText() aufrufe muss der String ja noch nicht geändert sein  ok warte ist doof formuliert.

ähm nach deiner idee müsste ich ja dann ne schleife machen die erst dann endet wenn der String nicht mehr "" ist oder ?

irgendwie muss ich ja das programm solange anhalten bis der string geändert wurde. 

falls du es nicht verstehst was ich meine ,könntest du vielleicht deine idee kurz im pseudocode wiedegeben?^^

danke erstmal trotzdem für deine hilfe 


edit : stelle mir das in meiner fantasie so vor :

if ( actionperformed().geändert()){
textfield.setText("Du hast folgendes getan");

}

in der art und weise geht es bestimmt nicht aber ich hoffe du weißt wo mein problem liegt^^


----------



## pro2 (15. Dez 2011)

```
//Irgendwo in der Klasse
String lastText = "";

//Im Actionlistener

if lastText != ""
    if lastText == "wechseln"
        if textField.getText() == "raum a"
            //dein Code
            lastText == "";
if lastText == ""
    if textField.getText() == "wechseln"
        lastText == "wechseln"
```

So war das ungefähr gemeint


----------



## fastjack (15. Dez 2011)

Die Programmlogik würde ich mit so einer Art StateMachine implementieren, ansonsten hast Du sehr schnell einen gigantischen Brummer...


----------



## psychoblade (15. Dez 2011)

hallo fastjack ,

ist mir bewusst das die Pogrammlogik irgendwann recht groß werden würde aber so groß soll das eigtl noch nicht werden^^

Könntest du mir aber vielleicht erklären wie man die StateMachine implementiert ? Raff die entsprechenende Klasse einfach nicht 

@pro2 : Ich glaube das müsste funktionieren . Probiere es mal aus und melde mich wieder 

Wird natürlich je nach anzahl der auswahlmöglichkeiten echt verdammt groß 


Danke erstmal an eure Ideen  Weitere sind erwünscht^^


mfg


----------



## Mofi (19. Dez 2011)

Ob meine Version jetzt sinnvoller ist weiß ich nicht. Aber ich hab das so gemacht (Ja ich mach auch grad ein TextAdventure  )

```
class EingabeListener implements ActionListener{
		public void actionPerformed(ActionEvent ae){
			String tmp = eingabefeld.getText();
			String text = controller.ueberpruefeEingabe(tmp);
			
			if(text != null){
				textflaeche.append(text + "\n");
				textflaeche.setCaretPosition(textflaeche.getDocument().getLength()); 

			}
			eingabefeld.setText("");
			eingabefeld.requestFocus();
		}
	}
```


```
eingabefeld
```
 ist ein JTextField und 
	
	
	
	





```
textflaeche
```
 ist eine JTextArea.

```
controller
```
 ist einfach eine Klasse die zwischen meiner Gui und dem Rest vermittelt.

Die Eingabe wird dann dort weiter geprüft und dementsprechend werden in einer anderen Klasse Variablen gesetzt. Je nachdem wie diese gesetzt sind "entscheidet" der Controller wie die weitere Eingabe gehandhabt wird bzw welche Methoden aufgerufen werden.

Was ich damit sagen wollte: Lagere doch die ganzen if's aus und setzte irgendwo Variablen, dass bestimmte Aktionen grad stattfinden (Raumwechsel, Kampf, was-auch-immer) und variiere dementsprechend was passiert.

Ich hoff ich hab das halbwegs verständlich erklärt


----------



## JanHH (19. Dez 2011)

Naja wenn jemand "wechseln" eingibt befindet sich der Teil Deiner anwendung, der das Textfield auswertet, im Zustand "wechseln". Wird sich also gemerkt. Entsprechend wird die nächste Eingabe im "Wechseln"-Kontext ausgewertet, alternativ zum "Befragen"-Kontext.

```
int state=keiner;

if(state=keiner)
   if(eingabe="wechseln")
      state=wechseln;
   else if(eingabe="befragen")
      state=befragen;
else if(state=wechseln)
   if(eingabe="kaminzimmer")
      geheKaminzimmer()
   usw usf.
else if(state=befragen)
   if(eingabe="person a")
     personAbefragen();
   uswusf.
```
in pseudo-code.

Aber wäre nicht ein simpler Parser, der auch mit etwas komplexeren Eingaben als nur einem Wort was anfangen kann, die bessere Lösung?


----------

