Entwurf einer einfachen Spielarchitektur
-
Hallo zusammen,
ich habe vor ein paar Monaten ein Spiel angefangen zu entwickeln und leider ist der gesamte Aufbau nicht besonders gut geworden.
Deswegen will ich jetzt erstmal ein wenig planen, bevor ich neu anfange und richtig loslege.
Ich habe bisher noch nie UML benutzt, das ist also mein erster Versuch
Implementierungsdetails, also fast alle privaten Teile habe ich erstmal rausgelassen, da es mir zunächst primär um die Schnittstellen geht.
Mir ist es wichtig, dass ich auch Netzwerkfähigkeit mit drin habe.Ich habe das C++ und nicht das Spieleentwicklungsforum gewählt, weil es mir eher um den allgemeinen Aufbau/Entwurf geht, als um besondere Techniken, die bei der Spielentwicklung zum Einsatz kommen.
Ich hab eben nach einer Seite gegooled, bei der ich kostenlos UML machen kann und erstmal Gliffy gefunden, leider nur 30 Tage kostenlos, also, falls wer was besseres hat, wäre ein Link gut
Mir ist auch klar, dass das, was ich da mache kein echtes UML ist, sondern eine Mischung aus C++ und UML, aber das sollte doch eigentlich trotzdem gut Verständlich für euch sein, oder?Also hier könnt ihr meinen ersten Entwurf einsehen:
http://www.gliffy.com/publish/2784511/Wie ihr sehr habe ich erstmal nur 4 Klassen reingetan.
Game ist dabei sozusagen die Hauptklasse, von der alles ausgeht.
Level ist dabei nur ein Interface.
NetworkClient und NetworkServer regeln die lowlevel-Details der Netzwerk verbindung.
Immer, wenn etwas interessantes passiert wird die Game-Klasse benachrichtigt mit den onXYZ-Methoden.Ich werde den Entwurf in nächster Zeit weiterentwickeln und hoffe dabei auf ein wenig Hilfe.
Was haltet ihr vom bisherigen Entwurf?
Habt ihr Verbesserungsvorschläge/Anmerkungen?Danke für eure Hilfe!
-
Arbeite mit Zuständen. Beispiel einer Basisklasse:
class IGameState { public: virtual ~IGameState() {} virtual void initGameState() = 0; virtual void onEnterGameState() = 0; virtual void onLeaveGameState() = 0; };
Ein Level ist ein Zustand, das Menü ist ein Zustand etc. So kann auch jeder Zustand für sich programmiert werden und mit einer entsprechenden Verwaltungsklasse läuft der Übergang der einzelnen Zustände automatisch.
Ich finde das die beste Lösung, da man so im Projekt jede Komponente für sich trennen kann.
initGameState wird aufgerufen wenn geladen werden soll, als Beispiel direkt bei der Erzeugung des Zustandes. Kommt auf den Umfang an.
enter wenn der Zustand aufgerufen wird und leave logischerweise kurz bevor oder nachdem der nächste Zustand eingeleitet wird/wurde. Je nach design.
Aber mir gefällt diese Lösung.
-
Die Idee klingt gut, nur weiß ich noch nich so genau, wie ich es umsetzen soll.
Also wie ich rausfinde, welcher Zustand auf den derzeitigen folgt und wann der Zustand verlassen wird usw..
Ich werd mal drüber nachdenken und das vermutlich auch in meinen Entwurf einarbeiten.
Habt ihr noch weitere Verbesserungsvorschläge/Anmerkungen?
-
Der übliche Weg ist da eine State Machine zu benutzen.
Siehe dazu hier:
http://de.wikipedia.org/wiki/Finite_State_MachineWäre wahrscheinlich das, worauf du auch kommen würdest.
Ein State ist dann z.B "Menü". Ein Button klicken löst eine Transition aus. In welchen nächsten State das ganze geht hängt dann davon ab welcher Button gedrückt wurde und dann gehts z.B in den State "Game" oder "Untermenü".
Transitionen kannst du dann z.B auch automatisch auslösen lassen, wenn eine bestimmte Zeit abgelaufen ist (z.B für Übergänge zwischen 2 States).
-
Dieser Thread wurde von Moderator/in CStoll aus dem Forum C++ (auch C++0x) in das Forum Spiele-/Grafikprogrammierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Danke für die Tipps!
Ich habe mal angefangen, es mit einzuarbeiten, bin aber noch nicht besonders weit gekommen.
Den aktuellsten Stand könnt ihr hier sehen:
http://www.gliffy.com/publish/2784511/
(Das ist der selbe link wie oben)Falls ihr noch weitere Tipps/Anmerkungen/Kritiken/etc. habt, immer her damit
-
Ich hab das ganze jetzt mal angefangen zu implementieren und bin bei dem Punkt angekommen, bei dem ich die GameStates managen muss.
Ich bin mir aber immer unsicher, wie ich das machen sollte...
In der Klasse GameImpl habe ich jetzt ein Attribut
GameState * myGameState;
Und die GameLoop sieht dann so aus:
void GameImpl::gameLoop() { while(myWindow->IsOpened()) { myGameState->update(myWindow->GetFrameTime()/1000.f); myGameState->draw(); handleEvents(); } }
Wie mach ich das jetzt mit den State-Übergängen rein?
Soll die GameState dann in der update methode beim game eine methode aufrufen, die den gamestate ändert, oder soll der rückgabewert von update anzeigen, ob und wenn ja auf was der GameState geändert werden soll, oder wie macht man sowas?
Und nehme ich dann eine enum für die Gamestates?
Also sowas wieenum GameStates { PLAYING, MENU, SUBMENU1, ... };
void MenuState::update(float delta) { //MenuState hält eine Referenz auf das Game-Objekt... if(userJustClickedOnSubMenuButton()) { myGame->setGameState(SUBMENU1); } }
Sieht irgendwie nicht so toll aus...
Aber ich weiß noch nicht so wirklich, wie ichs besser machen kann.P.S.:
Schaut ruhig auch hier nochmal rein:
http://www.gliffy.com/publish/2784511/
Hab wieder einiges geändert.
-
Nur so als Anregung. Unter http://kde-apps.org gibt es etliche Games in C++. Die eigentliche Gamelogik ist von Linux/Windows unabhängig. Da darf man sich ruhig inspirieren lassen.
Wenn es etwas komplizierter sein darf, ist auch http://wl.widelands.org/ ganz interesant.