Ich habe kürzlich beschlossen, meine Spielarchitektur zu überarbeiten, um tiefe Klassenhierarchien zu beseitigen und sie durch konfigurierbare Komponenten zu ersetzen. Die erste Hierarchie, die ich ersetze, ist die Elementhierarchie, und ich möchte einige Ratschläge, um zu wissen, ob ich auf dem richtigen Weg bin.
Zuvor hatte ich eine Hierarchie, die ungefähr so aussah:
Item -> Equipment -> Weapon
-> Armor
-> Accessory
-> SyntehsisItem
-> BattleUseItem -> HealingItem
-> ThrowingItem -> ThrowsAsAttackItem
Unnötig zu erwähnen, dass es langsam chaotisch wurde und dies keine einfache Lösung für Gegenstände war, bei denen es sich um mehrere Typen handeln musste (dh einige Geräte werden für die Objektsynthese verwendet, andere Geräte können geworfen werden usw.).
Ich habe dann versucht, die Funktionalität umzugestalten und in die Basiselementklasse einzufügen. Aber dann bemerkte ich, dass der Artikel viele unbenutzte / überflüssige Daten enthielt. Jetzt versuche ich, eine Komponente wie Architektur zu erstellen, zumindest für meine Gegenstände, bevor ich dies für meine anderen Spielklassen versuche.
Folgendes denke ich derzeit für das Komponenten-Setup:
Ich habe eine Basisgegenstandsklasse mit Steckplätzen für verschiedene Komponenten (z. B. einen Ausrüstungskomponentensteckplatz, einen Heilungskomponentensteckplatz usw. sowie eine Karte für beliebige Komponenten).
class Item
{
//Basic item properties (name, ID, etc.) excluded
EquipmentComponent* equipmentComponent;
HealingComponent* healingComponent;
SynthesisComponent* synthesisComponent;
ThrowComponent* throwComponent;
boost::unordered_map<std::string, std::pair<bool, ItemComponent*> > AdditionalComponents;
}
Alle Elementkomponenten würden von einer Basis-ItemComponent-Klasse erben, und jeder Komponententyp ist dafür verantwortlich, der Engine mitzuteilen, wie diese Funktionalität implementiert werden soll. Das heißt, die Heilungskomponente teilt der Kampfmechanik mit, wie der Gegenstand als Heilgegenstand verbraucht werden soll, während die Wurfkomponente der Kampfmaschine mitteilt, wie der Gegenstand als Wurfgegenstand behandelt werden soll.
Die Karte wird zum Speichern beliebiger Komponenten verwendet, die keine Kernelementkomponenten sind. Ich kopple es mit einem Bool, um anzugeben, ob der Item Container die ItemComponent verwalten soll oder ob sie von einer externen Quelle verwaltet wird.
Meine Idee hier war, dass ich die Kernkomponenten, die von meiner Spiel-Engine verwendet werden, im Voraus definiere und meine Gegenstandsfabrik die Komponenten zuweist, die der Gegenstand tatsächlich hat, andernfalls sind sie null. Die Karte würde beliebige Komponenten enthalten, die im Allgemeinen von Skriptdateien hinzugefügt / verwendet werden.
Meine Frage ist, ist das ein gutes Design? Wenn nicht, wie kann es verbessert werden? Ich überlegte, alle Komponenten in der Karte zu gruppieren, aber die Verwendung der Zeichenfolgenindizierung schien für die Kernelementkomponenten nicht erforderlich zu sein