2013-03-20 7 views
6

Próbuję opracować podstawową grę tekstową, ponieważ uczę się języka Java. Chciałbym móc liczyć rundy w grze jako sposób zarządzania tempem określonych zdarzeń. Na przykład szatnie można ograniczyć do jednej na rundę (sekundę, w kodzie testowym). Małe stworzenie może zaatakować lub zmienić pokoje na wyższym poziomie, podczas gdy większe może być bardziej uciążliwe. Dobry do tej pory? Wspaniały.Czas obsługi w grze tekstowej (Java)

Więc ugotowałem to i natychmiast zdałem sobie sprawę, że uderzę w blok za każdym razem, gdy pętla while czeka, aż gracz wprowadzi polecenie. Kod:

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() 

Tak, tu jest moje pytanie:

Czy istnieje sposób mogę stosować oddzielną metodę do czasu log/zaokrągla współbieżne do pętli podczas prezentacji gracza z wiersza polecenia?

Jeśli nie, czy jest inny sposób, aby uczynić to nie problem, którego jeszcze nie widzę/praktykowałem?

Odpowiedz

4

Spójrz na Concurrency tutorial. Dzięki wątkom możesz czekać na wprowadzanie danych przez użytkownika bez zatrzymywania innych procesów (i sprawiania, aby te inne procesy były wykonywane jednocześnie - nie równolegle, ale z podziałem czasu).

+0

Przypuszczam, że tutorial Oracle byłby rozsądniejszym miejscem do rozpoczęcia.Wcześniejsze głosowanie, kiedy mam reputację. – eenblam

1

Nazywa się "pętlą gry", która pozwala na płynną grę bez względu na dane wejściowe użytkownika.

Najprostsze rozwiązanie - utwórz 2 wątki, frist będzie czekać na dane wejściowe użytkownika i wstawi je do ConcurrentLinkedQueue z pojemnością 1. Drugi wątek uruchomi pętlę gry i pobierze dane z kolejki, aby je przetworzyć, jeśli kolejka nie jest pusta .

Możesz użyć dowolnej struktury danych, którą chcesz wymieniać dane między 2 wątkami, może to być nawet zmienna zmienna łańcuchowa. Jedyne wymagania, które należy przeczytać, to prawo do zapisu do tej zmiennej powinno być w jakiś sposób zsynchronizowane.

+0

Niesamowite, dziękuję za zwięzłe wyjaśnienie. Prawdopodobnie będę musiał spędzić trochę czasu w dokumentach, ale to brzmi całkiem wykonalne. – eenblam

1

Przebieg tekstu w czasie rzeczywistym? Brzmi interesująco. Nie sugerowałbym próbowania współbieżności dla tego konkretnego problemu, istnieją łatwiejsze sposoby.

Zwykle nie mieszałbyś blokowania wejścia z czasem w sekundach. Jeśli nie masz serca na ten projekt, proponuję albo.

1) Nie blokuj przy wprowadzaniu danych przez użytkownika. Napisz swój własny kod obsługi wprowadzania, sprawdzając naciśnięcia klawiszy każdej klatki. Następnie możesz obliczyć różnicę czasu między iteracjami. Na przykład. potwór przesuwa się o 1 blok sekundę, więc jeśli iteracja pętli prądowej zajęła 100 ms, przesuwa się o 0,1 bloku. (Przechowuj te wartości wewnętrznie, nawet jeśli rysujesz na siatce tekstu:

2) Przyrost czasu gry w "tickach" na podstawie danych wprowadzanych przez użytkownika. Byłby to styl NetHack/Roguelike. Potwory mogą przesuwać tyle bloków na tick, a nie na sekundę.

+0

Pomyślałem o metodzie kleszcza, ale nie widzę tego przeniesienia do gry wieloosobowej, co byłoby fajnym projektem na przyszłość. Doceniam również alternatywne podejście w opcji 1, ponieważ byłby to sam w sobie projekt oświecający. Prawdopodobnie użyję wątków tylko po to, aby je poznać (pierwotny cel), a następnie zaimplementować tę obsługę wprowadzania danych w tym wątku. – eenblam

1

Tak, jest sposób. Będziesz musiał umieścić kod "Round Counting" we własnym wątku, aby nie został zablokowany przez użytkownika oczekującego na dane wejściowe. Pomocny w tym może być pakiet java.util.concurrency.

Spójrz na Java Doc metoda scheduleAtFixedRate() wykona operację w stałych odstępach czasu. Kod "round counting" zostanie przeniesiony do klasy, która implementuje interfejs runnable. A to byłoby wykonywane w ustalonym przedziale czasu. Jest to jednak dość zaawansowane.

Powiązane problemy