2009-02-26 4 views
6

Edit: Das macht viel mehr Sinn für mich jetzt, dass ich einen Schritt vom Code entfernt habe, danke für die Hilfe.Gameloop für j2me "Turn-based" Spiel

Gerade gefunden Stapelüberlauf den anderen Tag durch Coding Horror und es sieht fantastisch aus. Stellen Sie sich vor, dass ich die Community nach einem Problem frage, das ich gerade versuche herauszufinden.

Ich entwickle ein Roguelike sortof Spiel mit j2me für Midp 2.0 Handys. Das Projekt befindet sich immer noch in den Grundphasen der Entwicklung, während ich herausfinde, wie es funktionieren wird. Der Teil, an dem ich gerade festhalte, hat mit Threading zu tun.

Das Spiel hat eine benutzerdefinierte HaxCanvas Klasse, die GameCanvas und implementiert runnable erweitert. Die Methode run ruft repaint() auf und ruht dann für 50 ms, was zu einer Bildrate von 20 FPS führt. Dies ermöglicht mir, den Rest des Spiels zu schreiben, ohne dass ich Repaint überall anbringen muss, und sollte später Animationen und Effekte einfacher machen. (zumindest in der Theorie).

Der Spielfluss wird von einer GameManager-Klasse kontrolliert, die alle NPCs auf der Karte durchläuft, bis sie an der Reihe ist. An diesem Punkt muss ich eine Eingabe erhalten, damit der Spieler sich bewegen und/oder Dinge angreifen kann. Ich rief ursprünglich gameManager.runUntilHeroTurn() in der keyPressed Methode meiner HaxCanvas. Nach dem Lesen von j2me-System-Threads wurde mir jedoch klar, dass es eine schlechte Idee ist, eine Methode mit dem Potenzial für eine Weile in einem Callback einzusetzen. Allerdings muss ich keyPressed verwenden, um Eingabe-Handeling zu tun, da ich Zugang zu den Zifferntasten benötige, und getKeyStates() unterstützt dies nicht.

Soar meine Versuche, meine Gameloop in einen eigenen Thread zu setzen, haben zu einem Desaster geführt. Eine seltsame "nicht abgefangene ArrayIndexOutOfBoundsException" ohne Stack-Trace erscheint, nachdem das Spiel mehrere Runden gelaufen ist. So

Ich nehme meine Frage ist:

Für ein Spiel, in J2ME „basiert drehen“, was ist der beste Weg, um das Spiel Schleife zu implementieren, für die Eingabe erlaubt nur handeling, wenn es die Umdrehung des Spielers?

+0

Übrigens, gute Frage. +1 – Fostah

Antwort

3

Ich würde Threading für die Spiellogik vermeiden, da J2ME Threading, je nach Hersteller natürlich, keine gute Arbeit macht, die begrenzten Ressourcen zu teilen. Sie werden oft Pausen sehen, während ein Thread eine schwere Verarbeitung durchführt. Ich würde nur Threads für Lade- oder Netzwerkkonnektivitäts-Funktionen empfehlen, da Sie in diesem Fall dem Benutzer lediglich das grundlegende Feedback "Loading ..." geben.

Um dies zu behandeln, hätte ich keine Sub-Loops, um jede der AI in einem Frame zu aktualisieren.Ich würde so etwas wie folgt in der Run-Funktion tun:

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 
    } 
} 

Sie wollen zu vermeiden, alles in einem Rahmen als 1 aktualisiert haben) die Aktualisierung langsam sein könnte, für den Benutzer nicht in unmittelbarem visuellen Feedback resultierende 2) Sie können animiere nicht jeden einzelnen NPC, wenn er seine Aktion ausführt. Mit dieser Konfiguration könntest du die NPC-Zustände NPC_DECIDE_MOVE und NPC_ANIMATING haben, mit denen du weiter kontrollieren kannst, was der NPC tut. NPC_ANIMATING würde das Spiel im Grunde in einen Wartezustand versetzen, in dem die Animation stattfinden würde, wobei jede weitere Verarbeitung vermieden wird, bis die Animation abgeschlossen ist. Dann könnte es zum nächsten NPC weitergehen.

Außerdem hätte ich nur einen gameManager.update() und gameManager.paint (g) (Farbe würde von paint aufgerufen werden), die alles handhaben und die Laufmethode dünn halten würde.

Schließlich, haben Sie in flushGraphics() untersucht? Mit dem GameCanvas erstellen Sie normalerweise ein Graphics-Objekt, zeichnen alles darauf und rufen dann flushGraphics() auf, dann warten Sie. Die Methode, die Sie erwähnen, ist die Art, sie für die Canvas-Klasse anzugehen. Nur gedacht, ich würde dies erwähnen und einen Link posten: Game Canvas Basics

5

Obwohl nicht speziell j2me Sie Benutzereingaben erfassen sollten, besteht die allgemeine Strategie darin, die Eingabe bis zu ihrer Zeit in die Warteschlange zu stellen, um die Eingabe zu verarbeiten.

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

Auf diese Weise können Sie sogar Skripteingabe für Debug-Zwecke.

Sie brauchen also keinen neuen Thread. Jedes Mal, wenn der Benutzer die Taste drückt, speichert er sie in einem Puffer und verarbeitet dann bei Bedarf den Inhalt des Puffers. Wenn der Player-Puffer keine Eingabe hat, sollte der Manager das gesamte Gameplay überspringen, Animationen machen und dann neu beginnen (da das Spiel kein Action-Spiel ist).