Grundsätzlich habe ich in jedem einzelnen Spiel, das ich bisher gemacht habe, immer eine Variable wie "current_state", die "game", "titlecreen", "gameoverscreen" usw. sein kann.
Und dann habe ich auf meiner Update-Funktion eine riesige:
if current_state == "game"
game stuf
...
else if current_state == "titlescreen"
...
Ich bin jedoch nicht der Meinung, dass dies eine professionelle / saubere Art ist, mit Zuständen umzugehen. Irgendwelche Ideen, wie man das besser machen kann? Oder ist das der Standardweg?
lua
architecture
love2d
David Gomes
quelle
quelle
Antworten:
Da es sich um Bildschirme handelt, ist es meiner Meinung nach am besten, diese gesamte Logik in verschiedene Bildschirme zu unterteilen. Was ich normalerweise mache:
Definieren Sie eine Schnittstelle namens screen und lassen Sie sie von mehreren Bildschirmen implementieren. Wie LoadingScreen, MainMenuScreen, GameScreen, GameOverScreen, HighScoreScreen usw. In Ihrem Spiel fügen Sie eine Variable ein, die den aktuellen Bildschirm enthält. In jeder Schleife rufen Sie screen.update () auf und rendern den aktuellen Bildschirm. Dies erspart Ihnen viel "wenn dieser Status dies tut", da Ihr Status durch den aktuellen Bildschirm definiert wird.
Dies wird Ihre Logik sehr schön trennen.
Beispielcode:
Oder abhängig von Ihrem Spiel-Setup haben Sie möglicherweise eine Endlosschleife als Ihr Spiel.
quelle
Wenn Sie Middleclass bereits verwenden, gibt es eine ausgezeichnete State-Machine-Bibliothek namens Statefull . Es ist einfach zu bedienen und basiert auf denselben Ideen, die Matsemann vorgeschlagen hat.
quelle
Wenn Ihre
current_state
Variable eine Zeichenfolge ist, ist dies in Lua wirklich einfach:quelle
Was ich mache, ist ungefähr wie folgt:
Ich habe eine gerichtete azyklische Graphdatenstruktur , die im Wesentlichen nur eine Reihe von Knoten ist, die aufeinander zeigen. Jeder Knoten repräsentiert ein Spielsystem. zB die Benutzeroberfläche, die Welt, die Eingabe, das Rendering. Und jeder Knoten zeigt auf andere Knoten, die davor oder danach kommen. Sobald alle Knoten vorhanden sind, können Sie sie leicht zu einer einfachen Liste zusammenfassen. Das Einrichten dieser DAG ist das erste, was ich beim Start des Spiels mache. Jedes Mal, wenn ich ein neues System hinzufügen möchte, z. B. KI, kann ich einfach sagen, dass ich diesen Code schreibe und dann meinem Spiel sage, wovon es abhängt und was davon abhängen sollte.
Danach kommt meine Hauptspielschleife und führt einfach jedes System der Reihe nach aus. Zuerst werden Eingaben verarbeitet, dann Weltaktualisierungen, dann andere Dinge ... Die Benutzeroberfläche ist fast zu Ende, und das Rendern ist das letzte. Wenn das Spiel zum ersten Mal gestartet wird, gibt es keine Welt, Physik oder KI, daher werden diese Schritte im Wesentlichen übersprungen und nur der Titelbildschirm wird angezeigt. Wenn Sie das Spiel richtig starten, sendet die Benutzeroberfläche eine Nachricht an das Weltsystem, um es einzuschalten, und es kümmert sich nur um sich selbst. Das Verwalten des Spielstatus bedeutet lediglich das Ein- und Ausschalten der verschiedenen Systeme. Jedes System verfügt über einen eigenen Satz von Statusinformationen, die mehr oder weniger unabhängig von allen anderen verarbeitet werden (das ist nicht vollständigTatsächlich handeln viele Systeme mit demselben Datensatz - das UI-System erfasst beispielsweise Daten aus der Welt, um beispielsweise Informationen anzuzeigen. Das KI-System muss auch Nachrichten betrachten und an Entitäten in der Welt senden.
quelle
So organisiere ich meine Staaten in Lua + Love2d. Es vermeidet die langen if / then-Anweisungen.
Zuerst erstelle ich eine Basisklasse, die die Methoden update (dt) und render () enthält. Sie können ihm auch Methoden zur Ereignisbehandlung geben, z. B. onKeyDown (Schlüssel). Ich nenne diese Klasse Stage, aber jedes Objekt, das die Methoden implementiert, funktioniert. Dann erstelle ich für jeden Spielstatus eine Instanz dieser Klasse und implementiere die erforderlichen Methoden. Ich erstelle dann eine Schlüssel- / Wertetabelle mit dem Namen des Staates und der Instanz des Staates. Verfolgen Sie dann den aktuellen Status im globalen Bereich, damit die Status ihn ändern können, wenn eine bestimmte Bedingung erfüllt ist.
quelle
Nun, obwohl es nicht schön ist, ist es in Ordnung, Zustände so zu behandeln, IMO. Sie können es viel sauberer machen, indem Sie Funktionen für jeden Zustand verwenden, wie zum Beispiel:
oder etwas anderes stört Sie bei diesem Ansatz (ich meine, außer dass die Update-Methode sehr lang ist)?
quelle