Für mein Projekt möchte ich komponentenbasierte Entitäten in C ++ verwenden. Meine aktuelle Implementierung gliedert sich in folgende Teile:
- Systeme - Enthalten eine Karte der Komponenten bestimmter Klassen und bearbeiten diese. Zum Beispiel hat PhysicsSystem einen Vektor von PhysicsComponents.
- Komponenten - Eine Komponente enthält einige öffentliche Variablen und möglicherweise einen Konstruktor, um sie zu initialisieren.
- Entitäten - Eine Entität ist für mich nur eine ID. Es wird jedoch nirgendwo gespeichert, sondern nur seine Komponenten werden in Systemen in der Karte gespeichert (wobei der Schlüssel die EntityId und der Wert der Zeiger auf die Komponente ist).
Mein Problem ist das Erstellen von Instanzen verschiedener Objekte in meinem Spiel. Ich möchte Objekte in XML definieren (kann ein beliebiges Textdateiformat sein). Aus Leistungsgründen sollte diese Datei beim Ausführen des Programms nur einmal analysiert werden.
Das heißt, ich sollte eine Vorlage daraus in meiner ObjectFactory erstellen und sie einem Namen zuordnen. Dann würde ich einfach anrufen factory.CreateObject("Player")
, um dem Spiel eine neue Entität hinzuzufügen.
Ich bin mir nicht sicher, wie ich dies ohne zu viel Overhead-Code implementieren soll. Ein weiteres Problem ist, dass ich nicht möchte, dass meine Fabrik etwas über die Systeme selbst weiß. Da meine Komponenten jedoch in den Systemen und nicht in einem Entity-Objekt gespeichert sind, muss ich ein Messaging-System verwenden, um neue Komponenten an das entsprechende System zu übergeben.
Meine Frage ist , wie würde ich das Objekt-Spawning mit Vorlage für jeden Objekttyp implementieren? Und wie beschreiben einige Engines ihre Objekte mit Konfigurationsdateien?
Antworten:
Geben Sie Ihrer
ObjectFactory
Klasse einemake_copy
Funktion, die eine Entität aufnimmt und einen vollständigen separaten Klon dieser Entität erstellen kann. Erstellen Sie neue Komponenten, die mit den Komponenten der ursprünglichen Entität identisch sind, und fügen Sie diese neue Komponente der neuen Entität hinzu. Sie können diese "ursprüngliche" Entität einmal aus der Datei laden und in einer Karte oder etwas mit einem Namen als Schlüssel speichern (wie "Player"). Diese Entität fungiert nun als Vorlage.Später, wenn Sie einen Moment aus dieser Vorlage machen möchten, können Sie anrufen
factory.CreateObject("Player");
, die die Karte mit nachschlagen"Player"
und dann eine Kopie der Vorlagenentität erstellen und an Sie und tada zurücksenden!BEARBEITEN:
Um das Problem "Übergabe der Komponente an Systeme" zu lösen,
System
verfügen Sie über eine Basisklasse mit einer rein virtuellenAddComponent
Funktion, die einen Zeiger auf die Komponente akzeptiert. Lassen Sie alle Ihre Systeme von dieserSystem
Basisklasse ableiten . Lassen Sie dann denObjectFactory
Speicher eine Liste von Zeigern auf diese Systeme speichern, und wenn er eine neue Komponente erstellt, übergibt er diese an das jeweilige System.quelle
Wie kommunizieren Sie derzeit zwischen Systemen? Wenn Sie eine Art Messaging- oder Event-Manager haben, können Sie einen haben
create_entity
Nachricht, die zusammen mit dem analysierten XML-Baum an alle Systeme gesendet wird. Systems sucht nach Tags, die ihre Komponenten beschreiben, und erstellt sie, wenn sie gefunden werden.Sie können die Komponentenarrays auch für Systeme freigeben. Sie können beispielsweise eine
ComponentCollections
Klasse erstellen und einen Verweis an die Konstruktoren Ihrer Systeme übergeben. Es kann verwandt sein und muss nicht über Ihre Komponententypen Bescheid wissen. Auf diese Weise kann ein System vollständige Entitäten erstellen. Möglicherweise möchten Sie, dass ein dediziertes System Entitäten lädt und erstellt, damit die anderen Systeme von möglichst wenigen Komponenten abhängen.Dies ist auch nützlich, wenn Sie auf die
RenderSystem
Weltposition von Objekten zugreifen möchten, die von der aktualisiert wirdPhysicsSystem
.Übrigens, wenn Sie eine Cache-Lokalität wünschen, müssen die Komponenten nacheinander im Speicher gespeichert werden, dh in einem Array oder Vektor anstatt in einer Karte. Sie können jedoch eine Zuordnung von der Entitäts-ID zum Vektorindex für den wahlfreien Zugriff haben.
quelle