我在网上阅读的关于实体组件系统的大多数材料似乎表明它用于转向使用继承。但我想知道的是,继续将继承与ECS一起使用是否可行?
假设我在引擎中具有特定数量的实体,这些实体将具有大部分相同的功能。例如,能够移动的实体。那么创建一个添加必要组件的MovableEntity
对象是否可行?
public class MovableEntity extends Entity {
public MovableEntity(int x, int y) {
addComponent(new PositionComponent(x, y));
addComponent(new VelocityComponent());
...
}
}
答案 0 :(得分:2)
我希望你不要介意我的直言不讳,但是按照你这样做的方式,我认为这是一个坏主意。
首先,您是否只是为了更容易地构建新组件类型而定义它们?如果是这样,您可以使用:
Entity movable_entity(int x, int y)
{
Entity new_entity = ...;
new_entity.addComponent(new PositionComponent(x, y));
new_entity.addComponent(new VelocityComponent());
...
return new_entity;
}
这可能看起来像风格差异,但它不涉及继承时表现出更松散的耦合。
其次,如果您要将MovableEntity
实际添加到Entity
所没有的新状态,那么这会使您的实体不再统一大小,我们就无法再有效地表示所有实体在内存中连续进行直接的随机访问,并且它们也可能变得容易进行对象切片(例如:当希望克隆Entity
时)从可移动的实体中克隆MoveableEntity
。 / p>
至少对于实体来说,我真的认为你最好不要扩展它们。我可以看到更多用于继承组件类型的用例,但我仍然建议不要使用它,因为ECS在访问组件方面非常灵活,不需要通过组件基类型进行多态化。如果要重用另一个组件的数据字段,则可以使用组合。
继承为ECS添加了一种竞争类型的模型,它不会如此漂亮,除非您只是这样做以便更容易构建具有特定组件的特定类型的实体,这些组件也可以无需引入全新的实体类型即可通过简单的功能完成。
答案 1 :(得分:1)
如果您不需要动态地向/从实体添加/删除组件,则可以使用继承来定义实体(具有多重继承的语言)。请考虑Evolve Your Hierarchy中的以下示例ECS:
您的组件将与类对应:
并且您的实体将对应于类:
答案 2 :(得分:0)
虽然不标准,但我发现这种做法非常有用。想象一下,一个战士拥有HP,攻击和防御的游戏。你可以写一个带有枚举和值的stat组件。另一种方法是拥有一个包含其他实体的组件,并使每个stat实体本身具有值和类型组件。我尝试了这两个,我不喜欢早期的结果。 (后者工作正常,但确实令人费解,但它确实严格遵守ECS设计)
最后,我为每个人创建了一个继承自Component的StatComponent。这意味着我可以执行非常方便的所有统计数据的操作。诀窍是让每一个OOP都粘在一个泡泡中。只要它是自包含的,我就不会发现任何重大问题。