Недавно я решил обновить свою игровую архитектуру, чтобы избавиться от глубоких иерархий классов и заменить их настраиваемыми компонентами. Первая иерархия, которую я заменяю, - это иерархия Предметов, и я хотел бы получить несколько советов, чтобы узнать, нахожусь ли я на правильном пути.
Раньше у меня была иерархия, которая выглядела примерно так:
Item -> Equipment -> Weapon
-> Armor
-> Accessory
-> SyntehsisItem
-> BattleUseItem -> HealingItem
-> ThrowingItem -> ThrowsAsAttackItem
Само собой разумеется, что это начало становиться грязным, и это было непростое решение для предметов, которые должны быть нескольких типов (т.е. какое-то оборудование используется для синтеза предметов, какое-то оборудование может быть брошено и т. Д.)
Затем я попытался провести рефакторинг и поместить функциональность в базовый класс элементов. Но тогда я заметил, что у Предмета было много неиспользованных / лишних данных. Теперь я пытаюсь создать такой компонент, как архитектура, по крайней мере, для своих предметов, прежде чем пытаться сделать это для других моих игровых классов.
Вот что я сейчас думаю о настройке компонента:
У меня есть базовый класс предметов, в котором есть слоты для различных компонентов (то есть слот для компонента оборудования, слот для компонента лечения и т. Д., А также карта для произвольных компонентов), поэтому что-то вроде этого:
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;
}
Все компоненты элемента наследуются от базового класса ItemComponent, и каждый тип компонента отвечает за указание движку, как реализовать эту функциональность. т.е. HealingComponent сообщает механике сражения, как использовать предмет как лечебный предмет, в то время как ThrowComponent сообщает движку, как обращаться с предметом как бросаемым предметом.
Карта используется для хранения произвольных компонентов, которые не являются компонентами основного элемента. Я соединяю его с логическим значением, чтобы указать, должен ли Контейнер элементов управлять ItemComponent или управляется внешним источником.
Моя идея состояла в том, чтобы я заранее определил основные компоненты, используемые моим игровым движком, и моя фабрика предметов будет назначать компоненты, которые на самом деле есть у элемента, иначе они будут нулевыми. Карта будет содержать произвольные компоненты, которые обычно добавляются / используются в файлах сценариев.
Мой вопрос, это хороший дизайн? Если нет, как это можно улучшить? Я подумал о группировании всех компонентов на карте, но использование строковой индексации казалось ненужным для основных компонентов