2013-03-20 12 views
6

Ich versuche, ein einfaches textbasiertes Spiel zu entwickeln, während ich Java lerne. Ich möchte Runden im Spiel zählen können, um bestimmte Ereignisse zu steuern. Zum Beispiel könnte die Umkleidekabine auf einmal pro Runde (eine Sekunde, im Testcode) begrenzt werden. Eine kleine Kreatur könnte Räume mit einer höheren Rate angreifen oder verändern, während eine größere Kreatur umständlicher sein könnte. Gut soweit? Groß.Bearbeitungszeit in einem textbasierten Spiel (Java)

Also kochte ich das auf und erkannte sofort, dass ich jedes Mal einen Block schlagen würde, wenn die while-Schleife darauf wartete, dass der Spieler einen Befehl eingab. Code:

private void startPlaying() { 
    //declare clock/round variables. 
    int lastRound = 0; 
    int currentRound = 0; 
    long lastTime = System.currentTimeMillis(); 
    long currentTime; 

    while (player.getIsPlaying()){ 
     //Clocking 
     currentTime = System.currentTimeMillis(); 
     if ((lastTime + 1000) < currentTime) { 
      lastTime = currentTime; 
      lastRound = currentRound; 
      currentRound++; 
      System.out.println("Current round:\t" + currentRound + "\tCurrent time:\t" + currentTime); //EDIT:NOTE: This is just a test line to observe the loop. 
     }//end if (Clocking) 

     Command command = new Command(); 
     String[] commandString = command.setAll(); //Array gets parsed elsewhere. 
     player.doCommand(commandString); 
     //Class Player extends Pawn extends Actor; Pawn has most command methods. 
    } 
    finishPlaying(); 
}//END STARTPLAYING() 

So, hier ist meine Frage:

Gibt es eine Möglichkeit ich eine separate Methode verwenden, um Zeit log/rundet gleichzeitig auf die while-Schleife den Spieler mit einer Eingabeaufforderung zu präsentieren?

Wenn nicht, gibt es eine andere Möglichkeit, dies zu einem Nicht-Problem zu machen, das ich gerade noch nicht sehe/praktiziere?

Antwort

4

Werfen Sie einen Blick auf Concurrency tutorial. Mit Threads können Sie auf Benutzereingaben warten, ohne andere Prozesse anzuhalten (und diese anderen Prozesse gleichzeitig ausführen lassen - nicht parallel, sondern Time-Sharing).

+0

Ich nehme an, Oracle Tutorial wäre ein sinnvoller Ausgangspunkt gewesen.Up-Voting sobald ich den Ruf habe. – eenblam

1

Es wird "Spielschleife" genannt, die dem Spiel erlaubt, unabhängig von der Eingabe des Benutzers glatt zu laufen. Die einfachste Lösung - 2 Threads erstellen, wartet auf Benutzereingaben und fügt sie in ConcurrentLinkedQueue mit der Kapazität 1 ein. Der zweite Thread führt Ihre Spielschleife aus und nimmt Benutzereingaben aus der Warteschlange, um sie zu verarbeiten, wenn die Warteschlange nicht leer ist .

Sie können jede Datenstruktur verwenden, die Sie Daten zwischen 2 Threads austauschen möchten, kann es sogar volatile String-Variable sein. Die einzigen Anforderungen Lese Schreibzugriff auf diese Variable sollte irgendwie synchronisiert werden.

+0

Super, danke für die knappe Erklärung. Ich werde wahrscheinlich ein wenig Zeit in der Dokumentation verbringen müssen, aber das klingt durchaus machbar. – eenblam

1

Ein Echtzeit-Text-Abenteuer? Hört sich interessant an. Ich würde nicht vorschlagen, Parallelität für dieses spezielle Problem zu versuchen, es gibt einfachere Wege.

Normalerweise würden Sie keine Blockierung bei der Eingabe mit der Zeit in Sekunden mischen. Es sei denn, Sie haben Ihr Herz auf dieses Design, würde ich entweder vorschlagen.

1) Blockieren Sie die Benutzereingabe nicht. Schreiben Sie Ihren eigenen Eingabehandhabungscode, indem Sie nach jedem Tastendruck für jeden Rahmen suchen. Dann können Sie einfach den Zeitunterschied zwischen den Iterationen berechnen. Z.B. ein Monster bewegt sich 1 Blocksekunde, wenn also die aktuelle Schleifeniteration 100 ms dauert, bewegt es sich um 0,1 Blöcke. (Speichern Sie diese Werte intern als float s, auch wenn Sie ein Textgitter zeichnen.

2) Erhöhen Sie die Spielzeit in "Ticks" basierend auf Benutzereingaben. Dies wäre NetHack/Roguelike-Stil. Monster können so viele Blöcke pro Tick anstatt pro Sekunde bewegen.

+0

Dachte über die Tick-Methode, aber ich kann nicht sehen, dass die Übertragung auf eine Multiplayer-Implementierung, die ein schönes Projekt für die Zukunft wäre. Ich schätze auch den alternativen Ansatz in Option 1, da dies ein aufschlussreiches Projekt an sich wäre. Ich werde wahrscheinlich sowieso Threads verwenden, nur um sie zu lernen (das ursprüngliche Ziel) und dann diese Eingabehandhabung in diesem Thread zu implementieren. – eenblam

1

Ja, es gibt einen Weg. Sie müssten den "Round Counting" -Code in einen eigenen Thread einfügen, damit er nicht vom Benutzer blockiert wird, der auf die Dateneingabe wartet. Das java.util.concurrency Paket kann dabei helfen.

Betrachten Sie Java Doc die Methode scheduleAtFixedRate() wird eine Runnable in festen Intervallen ausführen. Der Code "Rundenzählung" würde in eine Klasse verschoben, die die Schnittstelle runnable implementiert. Und dies würde zum festgelegten Zeitintervall ausgeführt werden. Dies ist jedoch ziemlich fortgeschritten.