Ich plane ein Abenteuerspiel und kann nicht herausfinden, wie das Verhalten eines Levels in Abhängigkeit vom Fortschritt der Geschichte richtig umgesetzt werden kann.
In meinem Einzelspielerspiel gibt es eine riesige Welt, in der der Spieler an verschiedenen Punkten des Spiels mit Menschen in einer Stadt interagieren muss. Abhängig vom Fortschreiten der Geschichte werden dem Spieler jedoch verschiedene Dinge präsentiert, z. Die Türen wurden nur zu bestimmten Tageszeiten nach Beendigung einer bestimmten Routine geöffnet. Verschiedene Cut-Screen- / Trigger-Ereignisse treten erst auf, nachdem ein bestimmter Meilenstein erreicht wurde.
Ich dachte naiv daran, eine switch {} -Anweisung zu verwenden, um zu entscheiden, was der NPC sagen soll oder wo er zu finden ist, und Questziele erst dann interaktiv zu machen, wenn der Zustand einer globalen game_state-Variablen überprüft wurde. Mir wurde jedoch klar, dass ich schnell auf viele verschiedene Spielzustände und Schaltzustände stoßen würde, um das Verhalten eines Objekts zu ändern. Diese switch-Anweisung wäre auch sehr schwer zu debuggen, und ich denke, es könnte auch schwierig sein, sie in einem Level-Editor zu verwenden.
Also dachte ich, anstatt ein einzelnes Objekt mit mehreren Zuständen zu haben, sollte ich vielleicht mehrere Instanzen desselben Objekts mit einem einzelnen Zustand haben. Auf diese Weise kann ich, wenn ich so etwas wie einen Level-Editor verwende, eine Instanz des NPC an allen verschiedenen Orten platzieren, an denen er jemals erscheinen könnte, und auch eine Instanz für jeden Gesprächszustand, den er hat. Aber das bedeutet, dass es eine Menge inaktiver, unsichtbarer Spielobjekte geben wird, die im Level schweben, was für das Gedächtnis problematisch oder in einem Level-Editor einfach schwer zu erkennen sein kann, ich weiß es nicht.
Oder erstellen Sie einfach für jeden Spielstatus ein identisches, aber separates Level. Dies ist die sauberste und fehlerfreieste Art, Dinge zu tun, aber es fühlt sich nach massiver manueller Arbeit an, um sicherzustellen, dass jede Version des Levels wirklich identisch ist.
Alle meine Methoden fühlen sich so ineffizient an. Gibt es eine bessere oder standardisierte Methode, um ein Verhalten auf einer Ebene zu implementieren, das vom Fortschritt der Story abhängt?
PS: Ich habe noch keinen Level-Editor - ich denke darüber nach, etwas wie JME SDK zu verwenden oder mein eigenes zu erstellen.
quelle
Die Auswahl, die ich in Betracht ziehen würde, besteht entweder darin, die einzelnen Objekte auf unterschiedliche Spielzustände reagieren zu lassen oder in unterschiedlichen Spielzuständen unterschiedliche Ebenen zu bedienen. Die Wahl zwischen diesen beiden Optionen hängt davon ab, was genau ich im Spiel tun möchte (was sind die verschiedenen Zustände? Wie wird das Spiel zwischen den Zuständen wechseln? Usw.).
So oder so würde ich es jedoch nicht tun, indem ich die Zustände fest in den Spielcode einkodiere. Anstelle einer massiven switch-Anweisung in NPC-Objekten würde ich anstelle des NPC-Verhaltens, das aus einer Datendatei in ein assoziatives Array geladen wird, dieses assoziative Array verwenden, um ein anderes Verhalten für die zugehörigen Zustände auszuführen.
quelle
Wie wäre es mit einem Beobachtermuster, um nach Meilensteinänderungen zu suchen? Wenn eine Änderung eintritt, würde dies eine Klasse erkennen und beispielsweise eine Änderung vornehmen, die an einem NPC vorgenommen werden muss.
Anstelle des genannten State Design Pattern würde ich ein Strategie-Pattern verwenden.
Wenn ein NPC n Möglichkeiten hat, mit dem Charakter und den m Positionen, an denen er sich befinden könnte, zu interagieren, müssen Sie maximal (m * n) +1 Klassen entwerfen. Wenn Sie das Strategiemuster verwenden, erhalten Sie n + m + 1 Klassen, aber diese Strategien können auch von anderen NPCs verwendet werden.
Es könnte also eine Klasse geben, die die Meilensteine handhabt, und Klassen, die diese Klasse beobachten und entweder mit NPCs oder Feinden umgehen, oder was auch immer geändert werden sollte. Wenn die Beobachter auf den neuesten Stand gebracht werden, entscheiden sie, ob sie etwas an den Instanzen ändern müssen, die sie regieren. Die NPC-Klasse zum Beispiel würde im Konstruktor den NPC-Manager informieren, wann er aktualisiert werden muss und was aktualisiert werden muss ...
quelle
Alle angegebenen Ansätze sind gültig. Das hängt von der Situation ab, in der Sie sich gerade befinden. Viele Abenteuer oder MMOs verwenden eine Kombination aus diesen.
Wenn sich beispielsweise durch ein zentrales Ereignis ein großer Teil des Levels ändert (z. B. ein Schuldner Ihre Wohnung aufräumt und jeder darin festgenommen wird), ist es in der Regel einfacher, den gesamten Raum durch einen zweiten Raum zu ersetzen, der nur ähnlich aussieht.
OTOH, wenn Charaktere auf der Karte herumlaufen und verschiedene Dinge an verschiedenen Orten tun, haben Sie oft einen einzigen Akteur, der sich durch verschiedene Verhaltensobjekte dreht (z. B. geradeaus gehen / keine Konversationen vs. hier stehen / Konversation über Mitch's Tod) "versteckt", wenn ihr Zweck erfüllt wurde.
Das heißt, normalerweise sollten Duplikate eines Objekts, das Sie manuell erstellen, keine Probleme verursachen. Wie viele Objekte können Sie erstellen? Wenn Sie mehr Objekte erstellen können, als Ihr Spiel durchlaufen kann, überprüfen Sie deren "versteckte" Eigenschaft und überspringen Sie, Ihre Engine ist zu langsam. Darum würde ich mir also keine Sorgen machen. Viele Online-Spiele machen das tatsächlich. Bestimmte Charaktere oder Gegenstände sind immer vorhanden, werden aber nicht Charakteren angezeigt, die nicht die entsprechende Mission haben.
Sie können die Ansätze sogar kombinieren: Haben Sie zwei Türen in Ihrem Wohnhaus. Man führt in die Wohnung "vor dem Inkasso", man in die Wohnung danach. Wenn Sie den Korridor betreten, wird nur der angezeigt, der für Ihren Verlauf in der Geschichte gilt. Auf diese Weise können Sie nur einen allgemeinen Mechanismus für "Element ist zum aktuellen Zeitpunkt in der Story sichtbar" und eine Tür mit einem einzelnen Ziel einrichten. Alternativ können Sie auch kompliziertere Türen herstellen, bei denen das Verhalten vertauscht werden kann, und eine davon lautet "Zur vollen Wohnung gehen", die andere "Zur leeren Wohnung gehen". Dies mag unsinnig erscheinen, wenn sich wirklich nur das Ziel der Tür ändert, aber wenn sich auch ihr Aussehen ändert (z. B. ein großes Schloss vor der Tür, das Sie zuerst knacken müssen).
quelle