2009-02-26 8 views
6

Edycja: To czyni mnie bardziej sensownym teraz, gdy zrobiłem krok od kodu, dzięki za pomoc.Gameloop dla j2me "turowej" gry

Po prostu znalazłem przepełnienie stosu na drugi dzień dzięki przerażeniu kodu i wygląda świetnie. Postaraj się zapytać społeczność o problem, który próbuję obecnie rozwiązać.

Zajmuję się tworzeniem roguelike sortof gry przy użyciu j2me dla telefonów midp 2.0. Projekt wciąż znajduje się na podstawowym etapie rozwoju, ponieważ wiem, jak to zadziała. Część, w której obecnie utknąłem, ma związek z wątkami.

Gra ma niestandardową klasę HaxCanvas, która rozszerza GameCanvas i Implements runnable. Uruchamia wywołania metod repaint(), a następnie śpi przez 50 ms, co daje szybkość 20 klatek na sekundę. To pozwala mi pisać resztę gry bez konieczności umieszczania odświeżania wszędzie i powinno ułatwiać później wykonywanie animacji i efektów. (przynajmniej teoretycznie).

Przepływ rozgrywki kontrolowany jest przez klasę GameManager, która przepuszcza wszystkie NPC na mapie, wykonując swoje skręty, aż do momentu, w którym przyjdzie kolej na gracza. W tym momencie muszę uzyskać dane wejściowe, aby umożliwić graczowi poruszanie się i/lub atakowanie rzeczy. Pierwotnie dzwoniłem pod numer gameManager.runUntilHeroTurn() w metodzie keyPressed mojego HaxCanvas. Jednak po przeczytaniu wątków systemowych j2me zdałem sobie sprawę, że umieszczenie metody z możliwością uruchomienia przez jakiś czas w wywołaniu zwrotnym jest złym pomysłem. Jednak muszę używać keyPressed do ręcznego wprowadzania danych, ponieważ potrzebuję dostępu do klawiszy numerycznych, a getKeyStates() nie obsługuje tego.

Sofar moje próby umieszczenia mojego gameloop w jego wątku spowodowały katastrofę. Dziwny "nieprzechwycony wyjątek ArrayIndexOutOfBoundsException" bez śladu stosu pojawia się po kilku uruchomieniach gry.

więc przypuszczam moje pytanie jest takie:

Przez „turowa” grę w J2ME, co jest najlepszym sposobem wdrożenia pętlę gry, pozwalając na wejście handeling tylko wtedy, gdy jest to kolej gracza?

+0

Przy okazji, dobre pytanie. +1 – Fostah

Odpowiedz

3

Unikał wątków dla logiki gry jako gwintowanie J2ME, w zależności od producenta oczywiście, nie robi wielkiej pracy dzielenie ograniczonych zasobów. Często zobaczysz pauzy, podczas gdy wątek wykonuje intensywne przetwarzanie. Zalecałbym tylko wątki do ładowania lub funkcje łączności sieciowej, ponieważ w tym przypadku po prostu przekazujesz użytkownikowi podstawową informację zwrotną "Ładowanie ...".

W tym celu nie miałbym podpętli do aktualizacji każdej sztucznej inteligencji w jednej ramce.Chciałbym zrobić coś jak następujące w funkcji run:

public void run() { 
    while(true) { 
     // Update the Game 
     if(gameManager.isUsersTurn()) { 
      // Collect User Input 
      // Process User Input 
      // Update User's State 
     } 
     else { 
      // Update the active NPC based on their current state 
      gameManager.updateCurrentNPC(); 
     } 

     // Do your drawing 
    } 
} 

chcesz uniknąć wszystko aktualizowane w jednej ramce jako 1) aktualizacji może być powolny, w wyniku braku natychmiastowej wizualnej informacji zwrotnej dla użytkownika 2) można animuj każdego pojedynczego NPC, gdy wykonują swoje działanie. Dzięki tej konfiguracji możesz mieć stany NPC, NPC_DECIDE_MOVE i NPC_ANIMATING, które pozwolą ci dalej kontrolować, co robi NPC. NPC_ANIMATING zasadniczo postawiłby grę w stanie oczekiwania na animację, unikając dalszego przetwarzania aż do zakończenia animacji. Następnie może przejść do następnej rundy NPC.

Ponadto, po prostu mam gameManager.update() i gameManager.paint (g) (farba byłaby wywoływana z farby), która zajmowałaby się wszystkim i utrzymywała cienką metodę run.

Wreszcie, czy zaglądasz do flushGraphics()? Za pomocą GameCanvas zazwyczaj tworzysz obiekt graficzny, rysujesz wszystko do tego, a następnie wywołujesz flushGraphics(), a następnie czekasz. Metoda, o której wspomniałeś, jest sposobem rozwiązania tego problemu dla klasy Canvas. Pomyślałem, że wspomnę o tym i opublikuję link: Game Canvas Basics

5

Chociaż w szczególności nie należy j2me przechwytywać danych wprowadzanych przez użytkownika, ogólną strategią jest umieszczanie w kolejce danych wejściowych do czasu przetworzenia danych wejściowych.

input ---> queue <---> Manager(loop) 

W ten sposób można nawet zapisywać dane wejściowe dla celów debugowania.

Nie potrzebujesz nowego wątku. Za każdym naciśnięciem klawisza użytkownik zapisuje je w buforze, a następnie przetwarza zawartość bufora, gdy jest to konieczne. Jeśli bufor odtwarzacza nie ma wejścia, menedżer powinien pominąć całą grę, tworzyć animacje, a następnie zacząć od początku (ponieważ gra nie jest grą akcji).