Statusänderungen in Entitäten oder Komponenten

9

Ich habe einige Probleme damit, herauszufinden, wie ich mit der staatlichen Verwaltung in meinen Einheiten umgehen soll.

Ich habe keine Probleme mit der Verwaltung des Spielstatus, wie Pause und Menüs, da diese nicht als Entitätskomponentensystem behandelt werden. nur mit Zustand in Entitäten / Komponenten.

Als Beispiel für Orcs Must Die habe ich meine MainCharacter- und Trap-Entitäten, deren Komponenten nur PositionComponent, RenderComponent, PhysicsComponent sind.

Bei jedem Update ruft die Entität das Update ihrer Komponenten auf. Ich habe auch einen generischen EventManager mit Listenern für verschiedene Ereignistypen.

Jetzt muss ich in der Lage sein, die Fallen zu platzieren: Wählen Sie zuerst die Falle und die Position der Falle aus und platzieren Sie dann die Falle.

Wenn Sie eine Falle platzieren, sollte sie vor dem MainCharacter erscheinen, auf andere Weise gerendert werden und ihm folgen. Wenn es platziert ist, sollte es nur auf Kollisionen reagieren und auf normale Weise gerendert werden.

Wie wird dies normalerweise in komponentenbasierten Systemen gehandhabt?

(Dieses Beispiel ist spezifisch, kann jedoch dazu beitragen, den allgemeinen Umgang mit Entitätszuständen herauszufinden.)

GriffinHeart
quelle
1
Können Sie die Komponenten von Entitäten basierend auf Eingabeereignissen hinzufügen und entfernen? Vielleicht können Sie die Komponenten der Falle ändern, wenn sich die Zustände ändern. Wenn Sie beispielsweise den Trap platzieren, enthält er FollowComponent und RenderEffectComponnent. Wenn es platziert wird, entfernen Sie beide Komponenten und fügen CollisionComponent hinzu. (Bearbeiten: deutlicher ausgedrückt von Martin Sojka)
Asakeron
Ja, ich kann, jede Eingabe wird von einem "HumanView" in Spielereignisse übersetzt, die zum größten Teil zuerst von meiner GameLogic-Klasse verarbeitet werden. Diese prüft beispielsweise, ob der MainCharacter über genügend Geld verfügt, um eine Falle zu platzieren passiert, nachdem ich versucht habe, das herauszufinden.
GriffinHeart

Antworten:

6

Eine interessante Anwendung eines Komponentensystems besteht darin, dass Sie die Komponenten einer Entität zur Laufzeit ändern können, wenn Sie sie so konzipiert haben, dass sie solche verarbeiten können. Der Zustand einer Entität wird somit zur Summe sowohl der ihr zugewiesenen Komponenten als auch der Werte, die diese enthalten.

In Ihrem Beispiel können Sie zuerst die Falle mit a BuildControllerComponent(die die Reaktion auf Spielersteuerungen in der Erstellungsphase regelt), a PositionComponentund a erstellen RenderComponent. Das letzte hat ein Datenfeld, das die verwendeten Pixel-Shader steuert, und eines davon verleiht der zu erstellenden Falle ein "gespenstisches" Aussehen. Sie werden feststellen, dass noch keine Physikkomponenten zugewiesen sind.

Beim Platzieren der Falle werden die Komponenten ausgetauscht. Das BuildControllerComponentwird nicht mehr benötigt, daher wird es entfernt. Die RenderComponentShader des werden durch Ihre normale Standardansicht der Falle ersetzt. Schließlich wird PhysicsComponentder Entität alles hinzugefügt, was für die Funktion der Falle erforderlich ist.

Bei einem vererbungsbasierten Ansatz entspricht dies einem Konstruktor für eine ActiveTrapEntityKlasse, der eine BuildTimeTrapEntityKlasse als Argumente verwendet. Der zweite wird zum Rendern der Falle während des Erstellens verwendet, der erste wird für die Falle verwendet, nachdem sie vorhanden ist .

Martin Sojka
quelle
Das ist klug.
Cypher
1
Dies ist eine gute Strategie zum Anwenden des Status einer Entität. Es geht nicht um die Frage, wie der Status jeder Entität verfolgt werden kann. Woher wissen Sie, in welchem ​​Zustand sich das Unternehmen derzeit befindet?
MichaelHouse
@MartinSojka Dies kommt dem nahe, woran ich gedacht habe, nachdem ich die Frage gestellt habe. Ich habe überlegt, einen BuildTrapProcess (etwas, das bei GameLogic aktualisiert wird) hinzuzufügen, der den Laufzeitaspekt beim Ändern von Komponenten verwaltet, um die Statusänderungen zu erreichen, die zum Erstellen eines Traps erforderlich sind. Wenn die Schaltfläche zum Erstellen einer Falle gedrückt wird, erstellt die Spiellogik den Prozess und startet ihn. Irgendwelche Gedanken zu diesem Ansatz?
GriffinHeart
@ Byte56: Im Allgemeinen können Sie die zugehörigen Komponenten und ihre Werte abfragen. In der Praxis müssen Sie häufig nur die relevante Teilmenge des gesamten Status kennen, z. B. "Hat diese Entität BuildControllerComponent?" oder "Wie ist die Position dieses Unternehmens PositionComponent, wenn es welche hat?" - diejenigen, die Sie tun, indem Sie die Komponentenliste auf diejenigen überprüfen, an denen Sie interessiert sind, und optional (einige) ihrer Werte abfragen.
Martin Sojka
1
@GriffinHeart: Ich würde einfach alles implementieren, was benötigt wird, um die Falle in dem System zu "bauen", das mit der Verwaltung von BuildControllerComponents verbunden ist. Es muss bereits die Blickwinkeländerungen des Spielercharakters (oder der Kamera) sowie Ereignisse beim Drücken von Tasten und Mäusen verarbeiten.
Martin Sojka
5

Ich mag die Idee nicht, dass Entitäten Updates für ihre Komponenten aufrufen (Systeme sollten die Arbeit erledigen), und das wird zu Problemen führen, wenn Komponenten sich nicht gegenseitig bewusst sind.

Sie können eine zusätzliche Komponente namens "Status" hinzufügen. Auf Ihre Render- und Kollisionssysteme wird zugegriffen. Die Statuskomponente ist nur ein Flag, für das mehrere Status verfügbar sind. Für die Situation, die Sie beschreiben, wären die Zustände Playund Build. Wenn das Render-System erkennt, dass der Status Buildvorliegt, wird das Objekt durchscheinend gezeichnet. Wenn das Kollisionssystem den BuildStatus sieht , verarbeitet es keine Kollisionen mit dem Spieler.

Aber wirklich, wenn Sie keine Systeme haben und sich auf Komponenten verlassen, um die ganze Arbeit zu erledigen, werden Sie auf viele Probleme stoßen. Komponenten sollten nichts voneinander wissen und keine Verarbeitung durchführen.

MichaelHouse
quelle
Was Sie sagen, ist widersprüchlich. Zuerst sollten sie sich dessen nicht bewusst sein (was ich zustimme), dann haben Sie eine Komponente, auf die andere zugreifen. Könntest Du das erläutern? Ich halte Komponenten vom Ereignissystem entkoppelt.
GriffinHeart
Ich sage beides. Ich sage, sie sollten sich dessen nicht bewusst sein und versuchen, meine Antwort darauf abzustimmen, wie ich denke, dass Sie mit Komponenten umgehen. Wenn Sie sagen "Entität ruft Update für ihre Komponenten auf", glaube ich, dass Sie keine systemverarbeitenden Entitäten haben. Ich habe die verwirrende Sprache entfernt und nur Systeme sagen lassen. Ich habe Komponenten gesagt, weil ich verstanden habe, dass Sie auf diese Weise aktualisiert haben.
MichaelHouse
Ich mag die Idee eines StateComponent, das von mehreren Systemen genutzt werden kann.
Cypher
1
Es ist höflich, Gründe für Abstimmungen zu liefern. Vielen Dank.
MichaelHouse
2
In einem anderen Sinne basiert Ihr Einwand gegen den Ansatz des Fragestellers auf der Annahme, dass jedes komponentenbasierte Design Komponenten aus separaten Systemen aktualisieren muss (wie ein Entitätssystemdesign). Dies ist eine Möglichkeit, aber sicherlich nicht die einzige, und es gibt keinen Grund, einen solchen Ansatz für ein Spiel abzuraten, bei dem keine Cache-optimierenden Komponentenaktualisierungsschleifen erforderlich sind.
Sean Middleditch