Endliche Zustandsmaschine in C ++

16

Ich habe viel darüber gelesen , wie man mit FSMs Spielzustände verwaltet, was ein FSM ist und wie man einen Stapel oder eine Reihe von Zuständen verwendet, um einen zu erstellen. Ich habe das alles durchgemacht. Aber ich bin fest entschlossen, eine tatsächliche, gut konzipierte Implementierung eines FSM für diesen Zweck zu schreiben . Insbesondere, wie kann man das Problem des Übergangs zwischen Zuständen sauber lösen, (wie) sollte ein Staat in der Lage sein, Daten aus anderen Zuständen zu verwenden, und so weiter. Hat jemand Tipps zum Entwerfen und Schreiben einer Implementierung in C ++ oder noch besser Codebeispielen?

Electro
quelle
bearbeitete Tags basierend auf dieser Diskussion in meta: meta.gamedev.stackexchange.com/questions/103/…
lathomas64

Antworten:

12

Ich habe einen FSM basierend auf einem Kapitel in "Massively Multiplayer Game Development" von Thor Alexander geschrieben. Darin befindet sich ein Kapitel mit dem Titel "Parallel-State-Maschinen für glaubwürdige Charaktere". Dies ist in Python geschrieben, aber die Konzepte sind leicht in C ++ zu übersetzen. Ich empfehle dringend, dies zu überprüfen, auch wenn es um Charakterstatus und nicht um Spielstatus geht.

Was ich erstellt habe, ist hier: https://github.com/swganh/mmoserver/tree/master/src/ZoneServer/GameSystemManagers/State%20Manager Schauen Sie unter StateManager nach Implementierungsdetails, aber im Grunde haben Sie verschiedene 'Basiszustände', die Sie können verwenden. Von dort aus haben Sie dann die spezifischen Zustände, zu denen Sie als Charakter übergehen, sodass jeder Zustand eine Klasse ist. Sie prüfen dann, ob Sie von einem Zustand in einen anderen wechseln können, und bei "Enter" können Sie Ihren Wechsel vornehmen. Ich fand, dass dies für das Spiel bisher sehr gut funktioniert hat.

Was ich implementiert habe, ist das, was das Buch eine parallele Zustandsmaschine nennt, was wesentlich ist, wenn mehrere fsm zusammenarbeiten. In diesem Fall können Sie in einen Zustand übergehen, der alle anderen Zustände blockiert (z. B. CreatureState_Dead). Ich werde nicht zu viel ins Detail gehen, da ich nicht denke, dass es Ihnen wirklich helfen würde, aber wenn Sie möchten, kann ich es näher erläutern.

Kyle C
quelle
1
Sieht so aus, als wäre der Code
Uhr
8

Das Programmieren von Game AI By Example (http://www.ai-junkie.com/books/toc_pgaibe.html) enthält eine Beispielimplementierung, die ziemlich einfach ist und nur die Grundlagen behandelt. Übergänge werden in einem einzigen Methodenaufruf behandelt (zuerst Enter (), dann Execute () jedes Update, Exit () beim Übergang)> Ich weiß nicht, was Sie darüber hinaus benötigen würden. Ich würde kompliziertere Übergänge als eigene Zustände implementieren, die nur einmal ausgeführt werden und nacheinander zum nächsten Zustand übergehen sollen.

Ich gehe mal davon aus, dass Sie sich mit FSMs für KI befassen. Wenn ja, empfehle ich Ihnen, sich Verhaltensbäume anzuschauen. AIGameDev hat einige großartige Artikel darüber.

michael.bartnett
quelle
1
Dieses Beispiel ist auch auf seiner Website verfügbar: ai-junkie.com/architecture/state_driven/tut_state1.html
Zolomon
5

Wenn C ++ Template Magic und möglicherweise lange Kompilierungszeiten kein Problem für Sie sind und Sie Boost bereits installiert haben, um damit zu arbeiten :

Boost hat jetzt eine effiziente ( in Geschwindigkeit und Größe ) Meta-State-Machine-Bibliothek, die den Vorteil bietet, dass Sie die Übergangstabelle getrennt von den Statusstrukturen festlegen können : Sie haben eine Tabelle, die beschreibt, wann von einem Status in einen anderen Status übergegangen werden muss . Sie müssen es nur lesen, um zu verstehen, was in der Zustandsmaschine vor sich geht.

Der andere Vorteil ist, dass es von mehreren Unternehmen auch in Embedded-Software mit Hochleistungssoftware getestet wurde (Details finden Sie in der Boost-Mailingliste). Da die Implementierung bereits vorhanden ist, ist sie möglicherweise eine gute Wahl, wenn Sie eine allgemeine Implementierung einer Zustandsmaschine benötigen, die mit Just Works (tm) funktioniert.

Es werden auch orthogonale Zustände (parallele Zustände) und andere nützliche UML-basierte Funktionen unterstützt.

Es bietet auch mehrere Möglichkeiten, die Übergangstabelle auszudrücken, eine davon ist experimentell, aber auf der Expressivitätsseite interessant (obwohl sie durch die aktuelle Compilerleistung begrenzt ist - schade!).

Klaim
quelle