Spielzustand-Automaten
Aus Spieleprogrammierer-Wiki
(Unterschied zwischen Versionen)
[gesichtete Version] | [gesichtete Version] |
K (→Stapelverarbeitung von Zuständen) |
(→Grundidee und Architektur) |
||
Zeile 10: | Zeile 10: | ||
[[Datei:uml_states.png|miniatur|UML-Klassendiagramm eines Spielzustand-Automaten]] | [[Datei:uml_states.png|miniatur|UML-Klassendiagramm eines Spielzustand-Automaten]] | ||
− | Die Grundidee der Spielzustand-Automaten lässt sich in zwei Klassen teilen: Den Zustands-Manager <tt>StateManager</tt> und | + | Die Grundidee der Spielzustand-Automaten lässt sich in zwei Klassen teilen: Den Zustands-Manager <tt>StateManager</tt> und eine Schnittstelle <tt>State</tt>. Jedes Spiel definiert eine Menge an Zuständen in Form von Klassen, die die Schnittstelle <tt>State</tt> implementieren. Der <tt>StateManager</tt> kennt und besitzt alle Zustände und identifiziert diese über eine ID. Im Folgenden wird auf beide Klassen näher eingegangen. |
=== State === | === State === | ||
− | <tt>State</tt> definiert | + | <tt>State</tt> definiert eine Schnittstelle für Spielzustände, die vom <tt>StateManager</tt> verwaltet werden. Für jeden konkreten Spielzustand wird eine Klasse benötigt, die die <tt>State</tt>-Schnittstelle implementiert. Die Schnittstelle enthält eine Reihe von Methoden, die beim Eintritt bestimmter Ereignisse aufgerufen werden: |
* <tt>'''OnEnter'''</tt>: Der <tt>StateManager</tt> ruft diese Methode auf, wenn von einem anderen Zustand zu diesem Zustand gewechselt wird. Dadurch können z.B. Variablen zurückgesetzt, Eingangsanimationen gestartet oder ein Musikstück abgespielt werden. | * <tt>'''OnEnter'''</tt>: Der <tt>StateManager</tt> ruft diese Methode auf, wenn von einem anderen Zustand zu diesem Zustand gewechselt wird. Dadurch können z.B. Variablen zurückgesetzt, Eingangsanimationen gestartet oder ein Musikstück abgespielt werden. | ||
Zeile 20: | Zeile 20: | ||
* <tt>'''OnUpdate'''</tt>: In dieser Funktion wird die Logik des Zustands berechnet. Im Falle des Zustands ''Spiel'' werden üblicherweise KI, Animationen und Physik aktualisiert. | * <tt>'''OnUpdate'''</tt>: In dieser Funktion wird die Logik des Zustands berechnet. Im Falle des Zustands ''Spiel'' werden üblicherweise KI, Animationen und Physik aktualisiert. | ||
* <tt>'''OnRender'''</tt>: Hier findet das gesamte Zeichnen für den aktuellen Zustand statt. | * <tt>'''OnRender'''</tt>: Hier findet das gesamte Zeichnen für den aktuellen Zustand statt. | ||
− | |||
=== StateManager === | === StateManager === | ||
Zeile 26: | Zeile 25: | ||
Der <tt>StateManager</tt> verwaltet alle für das Spiel möglichen Zustände. Dazu werden ihm alle Zustände durch <tt>AddState</tt> bekannt gemacht. Für den <tt>StateManager</tt> ist immer genau ein Zustand aktuell. Dieser lässt sich mit der Methode <tt>SetState</tt> festlegen. | Der <tt>StateManager</tt> verwaltet alle für das Spiel möglichen Zustände. Dazu werden ihm alle Zustände durch <tt>AddState</tt> bekannt gemacht. Für den <tt>StateManager</tt> ist immer genau ein Zustand aktuell. Dieser lässt sich mit der Methode <tt>SetState</tt> festlegen. | ||
− | Prinzipiell verwendet man bei Spielen getrennte Logik für Update- und Render-Funktionalität. Daher unterscheidet der <tt>StateManager</tt> auch zwischen diesen beiden Vorgängen, indem | + | Prinzipiell verwendet man bei Spielen getrennte Logik für Update- und Render-Funktionalität. Daher unterscheidet der <tt>StateManager</tt> auch zwischen diesen beiden Vorgängen, indem er getrennte Methoden besitzt. Diese rufen vom aktuellen Zustand <tt>OnUpdate</tt> bzw. <tt>OnRender</tt> auf. |
=== Stapelverarbeitung von Zuständen === | === Stapelverarbeitung von Zuständen === | ||
− | Neben dem simplen Setzen von Zuständen ist die Abfolge von Zustandswechsel ein interessantes Thema. | + | Neben dem simplen Setzen von Zuständen ist die Abfolge von Zustandswechsel ein interessantes Thema. Es bietet sich hier die Benutzung eines Stapels (''Stack'') an. Der <tt>StateManager</tt> besitzt einen Stapel, der eine Menge an Zuständen referenziert. Dabei gilt das [http://de.wikipedia.org/wiki/Last_In_–_First_Out LIFO-Prinzip] (''Last In – First Out''). Mit Hilfe der Methoden <tt>PushState</tt> lässt sich ein neuer Zustand auf den Stapel packen, der auch gleichzeitig der Aktive ist. Das Gegenstück lautet <tt>PopState</tt> und nimmt den zuletzt eingefügten Zustand vom Stapel. Durch dieses Prinzip gestalten sich Zustandsübergänge durch eine Kombination aus <tt>PushState</tt> und <tt>PopState</tt>. Hier ein einfaches Beispiel: |
Ein Spiel besitzt zwei Zustände: ''Hauptmenü'' und ''Spiel''. Der <tt>StateManager</tt> hat vorerst einen leeren Stapel. Beim Starten des Programmes wird der Zustand ''Hauptmenü'' mit <tt>PushState</tt> als erster Zustand gesetzt. Nun entscheidet sich der Spieler, ein neues Spiel zu starten. Im Programm wird mit <tt>PushState</tt> der Zustand ''Spiel'' auf den Stapel gepackt. Dadurch ist ''Spiel'' der aktuelle Zustand. Nachdem der Spieler sein Spiel gespielt und verloren hat, möchte er das Spiel erneut mit einem anderen Schwierigkeitsgrad spielen und beendet das Spiel, um in das Hauptmenü zu gelangen. Dazu wird <tt>PopState</tt> aufgerufen, wodurch der Zustand ''Spiel'' vom Stapel genommen wird und ''Hauptmenü'' wieder der aktuelle Zustand ist. | Ein Spiel besitzt zwei Zustände: ''Hauptmenü'' und ''Spiel''. Der <tt>StateManager</tt> hat vorerst einen leeren Stapel. Beim Starten des Programmes wird der Zustand ''Hauptmenü'' mit <tt>PushState</tt> als erster Zustand gesetzt. Nun entscheidet sich der Spieler, ein neues Spiel zu starten. Im Programm wird mit <tt>PushState</tt> der Zustand ''Spiel'' auf den Stapel gepackt. Dadurch ist ''Spiel'' der aktuelle Zustand. Nachdem der Spieler sein Spiel gespielt und verloren hat, möchte er das Spiel erneut mit einem anderen Schwierigkeitsgrad spielen und beendet das Spiel, um in das Hauptmenü zu gelangen. Dazu wird <tt>PopState</tt> aufgerufen, wodurch der Zustand ''Spiel'' vom Stapel genommen wird und ''Hauptmenü'' wieder der aktuelle Zustand ist. |
Version vom 7. November 2011, 17:18 Uhr
Klicke hier, um diese Version anzusehen.