Erstellen Sie eine Entität aus einer Vorlage in einer komponentenbasierten Engine


7

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?


2
Sieht aus wie die Notwendigkeit für das Prototyp- Design-Muster ...
The Light Spark

Antworten:


2

Geben Sie Ihrer ObjectFactoryKlasse eine make_copyFunktion, 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, Systemverfügen Sie über eine Basisklasse mit einer rein virtuellen AddComponentFunktion, die einen Zeiger auf die Komponente akzeptiert. Lassen Sie alle Ihre Systeme von dieser SystemBasisklasse ableiten . Lassen Sie dann den ObjectFactorySpeicher eine Liste von Zeigern auf diese Systeme speichern, und wenn er eine neue Komponente erstellt, übergibt er diese an das jeweilige System.


Vielen Dank für die Antwort, dies hat mich auf den richtigen Weg gebracht. Ein Problem dabei ist jedoch, dass in meiner Implementierung die Komponenten in den Systemen gespeichert sind. Wenn ich eine Kopie jeder Komponente erstelle, die eine Entität haben sollte, müsste ich diese irgendwie an das entsprechende System übergeben.
Davidv

@ user2715488, fügte das der Antwort hinzu.
Der

@ user2715488 Mich würde interessieren, wie Sie das Problem gelöst haben. Ich habe auch zwei Vorschläge für Sie.
Danijar

1

Wie kommunizieren Sie derzeit zwischen Systemen? Wenn Sie eine Art Messaging- oder Event-Manager haben, können Sie einen habencreate_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 ComponentCollectionsKlasse 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 RenderSystemWeltposition 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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.