Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

21.01.2009, 19:25

Gamestates - Sinnvoll?

Nabend!

Wie schon einmal erwähnt, frage ich vorweg für ein künftiges 2D Spiel. ;)

Nun habe ich einige Fragen zu Gamestates, steckt der Sinn dahinter, für
verschiedene Teilaspekte des Spiels (Pause, Menü, game, Game_Kampf, etc.) je einen Gamestate zu errichten?
In einem anderen Thread hier im
Forum habe ich gelesen, dass das ganze mit Klassen realisiert wird :?:

Wenn ich nun ein Spiel programmiere und der Anfang etwa so lautet:

1. Fenster/Screen öffnen
2. Intro abspielen
3. Menü anzeigen

Dann ist es doch sinnvoll Funktionen dafür zu schreiben, sodass ich das
ganze Initialisierungszeugs in eine Funktion Init() packe, oder? (ist das
möglich?)
In einer anderen Programmiersprache, habe ich mal gesehen, dass das
mit den Gamestates über einer einzigen Variablen läuft, die anschließend
immer überschrieben wird. Beispielsweise wird geprüft, ob ein Kampf
stattfindet und anschließend der Gamestate Variablen Kampf zugewiesen...oder so ähnlich. Aber in C++ läuft es mit Klassen?

Letztlich wollte ich noch wissen, ob Gamestates noch verwendet werden und auch irgendetwas "schlechtes" an sich haben (ala Go To).

Danke für eure Antworten!
MfG Shiver!

„Ideen sind nur Ausgangspunkte. Um zu wissen, was man zeichnen will, muss man zu zeichnen anfangen.“ Pablo Picasso

Ibot Development - Mein Weg zum eigenen 2D RPG

the[V]oid

Alter Hase

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

2

21.01.2009, 19:35

Ich nehme an, das mit den Klassen ist so gemeint, dass du z.B. eine Klasse Menu und eine Klasse Game hast, beide sind von einer abstrakten Klasse State mit [jetzt mal ganz banal] den purevirtual Funktionen move() und draw() abgeleitet, diese werden implementiert in Game und Menu, dann hast du eine Variable á la "State* m_pState", die mal auf ein Game-Objekt, mal auf ein Menu-Objekt verweisen kann, und in deiner Hauptschleife rufst du dann "pState -> move ()" bzw. "pState -> draw ()" auf. Also so in etwa. Klassischer Fall für Polymorphie.
<< an dieser Stelle ist eine Signatur verstorben >>

3

21.01.2009, 20:48

Wenn das Menü z.B. über dem Spielfeld angezeigt werden soll, ist es eventuell sinnvoller, das Menü in die Spiel Klasse zu packen und dort anzuzeigen.
Eine allgemein richtige Vorgehensweise gibt es da aber sicher nicht, hängt halt ganz von dem Projekt ab. Und es gib auch sicherlich meist mehrere saubere Lösungen.
Lieber dumm fragen, als dumm bleiben!

Beneroth

Alter Hase

Beiträge: 969

Wohnort: Schweiz

Beruf: Software Entwickler

  • Private Nachricht senden

4

21.01.2009, 22:05

Benutze States wenn du in mehreren oder sogar allen States gleiche Funktionen von irgendwo her aufrufen musst woi dieses "irgendwo" nicht weiss oder wissen muss welcher state nun genau gemeint ist (einfach der halt der gerade aktiv ist).

Zum Beispiel wird es ja wohl in all deinen Spiel-States zwei Sachen geben die so oder so gemacht werden: Events behandeln, und auf den Bildschirm zeichnen.
Da könntest du auf der Klasse "States" die Funktionen "handleEvents(<wasAuchImmerHierReinkommt>)" und "paint( <wasImmerHierAuchReinkommtZumBeispielPointerZumRenderTarget>)" virtual deklarieren, und jeder Spielstate-Klasse überschreibt die Funktion und zeichnet darin was sie halt zeichnen soll.
So hast du dann im main nur noch deine Hauptschleife und einen States-Pointer auf das aktuelle Objekt über welchen jeweils paint() und handleEvents() aufgerufen wird, sowie ein System dass diesen Pointer ändert falls der State sich ändert (kannst ja bei handleEvents den State-Pointer zurückgeben oder so).

Zitat von »"Shiver"«

In einer anderen Programmiersprache, habe ich mal gesehen, dass das
mit den Gamestates über einer einzigen Variablen läuft, die anschließend
immer überschrieben wird. Beispielsweise wird geprüft, ob ein Kampf
stattfindet und anschließend der Gamestate Variablen Kampf zugewiesen...oder so ähnlich. Aber in C++ läuft es mit Klassen?

Diese Variable wäre in C++ am einfachsten ein Pointer zu einer Instanz einer Klasse, zum aktuell aktiven State.

Zitat von »"Shiver"«

Dann ist es doch sinnvoll Funktionen dafür zu schreiben, sodass ich das
ganze Initialisierungszeugs in eine Funktion Init() packe, oder? (ist das
möglich?)

Eine Klasse ist wie ne Art Schachtel wo es sowohl Funktionen wie auch Variablen drin hat. Jede Klasse hat immer (mindestens) eine Funktion die genau so heisst wie die Klasse selber, so einer Funktion sagt man "Konstruktor", und sie macht genau das was dein Init() macht, die Variablen in der Klasse initialisieren (also ihnen einen Startwert geben).

Zitat von »"Shiver"«

Letztlich wollte ich noch wissen, ob Gamestates noch verwendet werden und auch irgendetwas "schlechtes" an sich haben (ala Go To).

Gamestates beschreibt eine Art (ist also sowas wie ein Plan) wie man mithilfe von Klassen und Pointern sehr einfach (damit ist gemeint übersichtlich und später leicht änderbar) und effizient so verschiedene "Spiel-Zustände" verwalten kann.
goto ist ein keyword von c++ das etwas macht. Gamestates (ein Plan) und und goto (ein keyword) können nicht verglichen werden.

Gamestates (bzw. der richtige name ist Zustands-Entwurfsmuster, oder State-Pattern in englisch) sind in der Regel etwas sehr schönes und wird vermutlich fast überall benutzt, allerdings muss man sie mal begriffen haben damit man sie verwenden kann.

Ich rate dir erstmal in c++ richtig zu lernen was pointer und klassen und so sind und was man damit machen kann, erst wenn du klassen und pointer richtig verstanden hast wirst du selber auch ein Gamestates-System bauen und verstehen können.

5

22.01.2009, 12:40

Moin!

Ok, ich glaube ich habe meine Antworten. Hast aber schon Recht Beneroth, ich muss wirklich erst noch Pointer und Klassen und einige
andere Sachen lernen. Daher werde ich das mit den Gamestates wohl
erst hinterher so richtig begreifen, aber dann kann ich ja wieder hier reinschauen. :)
Das mit dem GoTo habe ich nur reingebracht, weil ich mal irgendwo gelesen habe, dass man GoTo nicht benutzen sollte.

Danke für eure Antworten!
MfG Shiver!

„Ideen sind nur Ausgangspunkte. Um zu wissen, was man zeichnen will, muss man zu zeichnen anfangen.“ Pablo Picasso

Ibot Development - Mein Weg zum eigenen 2D RPG

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

6

22.01.2009, 12:42

Zitat von »"Shiver"«


Das mit dem GoTo habe ich nur reingebracht, weil ich mal irgendwo gelesen habe, dass man GoTo nicht benutzen sollte.


sry für den OT, aber ich hab öfter schon microsoft code gesehen die aus faulheit goto benutzt haben, fand ich ganz witzig. war irgend nen dx sdk sample.

7

22.01.2009, 13:43

Zitat von »"Jonathan_Klein"«

Wenn das Menü z.B. über dem Spielfeld angezeigt werden soll, ist es eventuell sinnvoller, das Menü in die Spiel Klasse zu packen und dort anzuzeigen.
Eine allgemein richtige Vorgehensweise gibt es da aber sicher nicht, hängt halt ganz von dem Projekt ab. Und es gib auch sicherlich meist mehrere saubere Lösungen.


ich hab das alles mal als gamestate-stack implementiert, da gab es dann aktive und passive gamestates, aktive zeichnen, passive können aber immer noch was machen (netzwerk etc), durch gutes design kann man sogar die netzwerkschicht in einen (immer) passiven gamestate hauen, und kann so relativ einfach client und server tauschen (in meinem fall jdnfalls)

aber eine sache macht mir bei gamestates immer kopfschmerzen...
wie könnte man am besten die übergänge der states realisieren, ohne die states ansich fest zu verlinken? ich hab das immer über ne art "register"-funktion realisiert, wo dann die namen der states statt der klassen selber registriert wurden, was schonmal etwas entkoppelt, aber das find ich noch nich optimal... hat da jmnd bessere ideen? so ne art vernetzung, die von einer zentralen stelle im code stattfindet, schwebt mir da vor :)

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

8

22.01.2009, 13:53

Nur woher soll die Verwaltung wissen, in welchen Gamestate du willst, wenn du dich in einem befindest und der Gamestate ansich nicht sagen kann "ich will da und da hin". Sehe spontan nur die 3 Möglichkeiten: -
-direktes setzen Verwaltung->NewState(NeuerZustand()); (was du ja nicht willst)
-setzen per Name Verwaltung->NewState("NeuerZustand"); (was du ja schon angemerkt hast)
-setzen per "links" Verwaltung->NewState(1); ("gehe zum ersten link". Setzt voraus, dass die Verwaltung weiß, was der erste link ist und der Programmierer muss es auch wissen. Also viel zu viel implizites Wissen :cry: )
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

9

22.01.2009, 14:08

aber genau das is das problem, was mich daran stört, das implizite wissen...
also Verwaltung->NewState("NeuerZustand"); verlangt auch implizites wissen, nämlich den namen, der "irgendwo" anders im programm eingegeben wurde. zumal da schnell rechtschreibfehler reinkommen (ok, kleines manko, sieht man ja beim debuggen, aber trotzdem).
wenn ich so drüber nachdenk, finde ich ne art verwaltung am besten, die das entweder per Enums oder per funktionen regelt, welcher gamestate aktiviert werden soll, da man dann nix falsch machen kann :) allerdings widerpricht das dem grundsatz der kapselung von informationen...
hm...mal quer gedacht: (inversion of control) wenn jeder gamestate seinen inneren zustand exponiert, dann kann die verwaltung den zustand checken und dann entscheiden, welcher gamestate zu folgen hat...das klingt für mich am optimalsten, da es dann einen zentralen ablaufplan für das spiel gibt, und trotzdem die states unabhängig voneinander sind...so könnte man es sogar soweit treiben, einzelne levels in gamestates zu bringen. die reihenfolge der level entscheidet sich dann in der verwaltung oder dem "plan" des spiels
aber wie der zustand eines gamestates propagiert werden soll, weiß ich nicht...
klingt trotzdem nach ner guten alternative zu den normalen varianten, oder?

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

10

22.01.2009, 14:26

Dann müsste man das Wissen der States in die Verwaltung portieren und dafür müsste das Interface von den States sehr aufgebläht sein oder man greift wieder auf "Serialisierungen" für den Wissenstransfer zurück, was wieder implizites Wissen voraussetzt. Ich glaube das wäre nur eine Verlagerung des "Designfehlers" :?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Werbeanzeige