Spiel registrieren Objektkomponenten in Spiel Subsystemen? (Component-based Spiel Object Design)

StackOverflow https://stackoverflow.com/questions/3958455

Frage

Ich erstelle ein komponentenbasiertes Spiel Objektsystem . Einige Tipps:

  1. GameObject ist einfach eine Liste von Components.
  2. Es gibt GameSubsystems. Zum Beispiel, Rendering, Physik usw. Jeder GameSubsystem enthält Zeiger auf einige Components. GameSubsystem ist eine sehr leistungsfähige und flexible Abstraktion. es stellt jede Scheibe (oder Aspekt) der Spielwelt

Es ist notwendig, in einem Mechanismus Components in GameSubsystems der Registrierung (wenn GameObject erstellt und zusammengesetzt). Es gibt 4 nähert sich :


  • 1: Verantwortungskette Muster. Jeder Component wird jeden GameSubsystem angeboten. GameSubsystem eine Entscheidung trifft, die registrieren Components (und wie sie zu organisieren). Zum Beispiel GameSubsystemRender können Render Komponenten registrieren.

Pro. Components weiß nichts darüber, wie sie verwendet werden. Low-Kupplung. A. können wir neue GameSubsystem hinzufügen. Zum Beispiel, lassen Sie uns GameSubsystemTitles hinzufügen, die alle ComponentTitle und Garantien registriert, dass jeder Titel ist einzigartig und bietet Schnittstelle zu Objekten nach Titel Quering. Natürlich ComponentTitle sollte in diesem Fall nicht rewrited oder vererbt werden. B. Wir können bestehende GameSubsystems reorganisieren. Zum Beispiel GameSubsystemAudio, GameSubsystemRender kann GameSubsystemParticleEmmiter in GameSubsystemSpatial zusammengeführt werden (um alle Audio zu platzieren, emmiter, machen Components in der gleichen Hierarchie und Verwendung Eltern-relativen Transformationen).

con. Jeder zu jedem Scheck. Sehr innefficient.

con. Subsystems wissen über Components.


  • 2. Jede Subsystem sucht nach Components bestimmten Arten

Pro. Eine bessere Leistung als in Approach 1.

con. weiß Subsystems noch über Components.


  • 3: Component registriert sich in GameSubsystem(s). Wir wissen, dass zum Zeitpunkt der Kompilierung, dass es eine GameSubsystemRenderer ist, so lass uns ComponentImageRender wird so etwas wie GameSubsystemRenderer nennen :: Register (ComponentRenderBase *).
    Observer Muster. Component abonniert "update" Veranstaltung (von GameSubsystem(s) gesendet).

Pro. Performance. Keine unnötigen Kontrollen wie in Approach 1 und Approach 2.

con. Components sind schlecht gekoppelt mit GameSubsystems.


  • 4: Mediator Muster. GameState (die GameSubsystems enthält) kann implementieren registerComponent (Component *).

Pro. Components und GameSubystems wissen nichts voneinander.

con. In C ++ würde es aussehen, wie hässlich und langsam typeid-Schalter.


Fragen: Welcher Ansatz ist besser und vor allem in komponentenbasierten Design verwendet? Was Praxis sagt? Irgendwelche Vorschläge über (data-driven) Umsetzung von Approach 4?

Danke.

War es hilfreich?

Lösung

Vote for the third approach.

I am currently working on component-based game object system and i clearly see some of additional advantages of this approach:

  • The Component is more and more self-sufficing subentity as it depends only on a set of available subsystems (i presume this set is fixed in your project).

  • Data-driven design is more applicable. Ideally, this way you may design a system where components are completely defined in the terms of data but not C++.


EDIT: One feature i thought about while working on CBGOS. Sometimes it is convenient to have ability to design and construct subsystemless passive components. When this is on your mind the fourth approach is the only way.

Andere Tipps

My approach was to implement the proxy pattern within each subsystem. As each subsystem is only interested in a subset of the total components each entity may contain, The proxy stores pointers to only the components the system cares about, eg, a motion system only cares about position and velocity, so it needs a proxy which stores two pointers, to those components. If the entity is missing one or more of those, then the subsystem will ignore it. If both components are present, then a proxy node is created and added to an internal collection. It is also useful for the proxy to store the unique identifier value for the entity, so that proxies may be added/removed in constant time from each subsystem, should it be necessary.

In such a way, should an entity be required to be removed from the engine, a single message containing the id of the entity can be sent to every subsystem. The proxy can then be removed from each subsystem collection independently.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top