Поэтому разработка игр с использованием объектно-ориентированной парадигмы в C ++ обычно включает идею GameObjects и их компонентов.
Теперь, прежде всего, GameObject будет список компонентов, как показано ниже:
class GameObject {
list<Component*> m_components;
Component* getComponent(component){}
}
Сейчас, конечно, есть много других способов реализовать игровой объект лучше и эффективнее, но это не имеет значения, потому что я сосредоточусь на компонентах. То, как gameobjects состоит из компонентов, является классическим примером композиции через архитектуру на основе компонентов, поскольку каждый компонент представляет поведение для GameObject.
Сами компоненты могут состоять из нескольких «функций» или поведений, которые могут понадобиться. Например, у нас может быть компонент, который зависит от множества других классов с поведением, таких как clickables, drag and drop и другие классы.
Принимая во внимание, что каждый подкомпонент имеет все необходимое для работы, они не зависят от вызова конструктора родительского класса, и что конкретные классы реализуют виртуальный метод из одного из родительских классов для выполнения действий в результате поведения происходит. Я считаю, что использование виртуального наследования в этом случае кажется лучшим решением, чем использование другого уровня композиции. Я бы закончил со следующим:
class Component {}
class clickable : virtual Component {
virtual onClick();
}
class draggable : virtual Component {
virtual onDrop();
}
Каждый класс делает то, что ему нужно, не вмешиваясь в базовый класс. Каждый добавил бы функциональность, которая может быть унаследована. все конкретные классы, которые нужно сделать, это переопределить предоставленный виртуальный. Это не могут быть просто интерфейсы, потому что каждый класс должен делать свое дело. Конкретный класс будет выглядеть так:
Класс ConcreteComponent: общедоступный компонент, общедоступный, общедоступный Dragable {}
Проблемы, которые требуют решения:
1- static_casting отключен, поэтому я бы полагался на dynamic_cast, и из-за их дорогостоящей природы я буду вынужден вызывать их только во время создания экземпляра компонента и добавлять указатели в качестве переменных-членов, если требуется какой-либо кросс-поведенческий материал , Я действительно ограничен этим? Будет ли прямое присоединение к базовому компоненту хотя бы смягчить часть проблемы, разрешая статическое приведение к любому конкретному объекту, даже если у них есть родительские классы, которые являются виртуальными базовыми классами?
2. Скорость, насколько хуже будет опора на виртуальные классы, чем прямая реализация наследования.
3 — есть ли реальная реализация, основанная на жизнеспособной композиции, для решения этой проблемы? не является ли сильная зависимость от композиции плохим запахом кода, особенно когда он используется на разных уровнях?
Задача ещё не решена.
Других решений пока нет …