2

我在网上阅读的大多数关于实体组件系统的材料似乎都表明它被用来避免使用继承。但是我想知道的是,在ECS旁边继续使用继承是否可行?

假设我在引擎中有特定数量的实体,它们将具有基本相同的功能。例如,能够移动的实体。那么创建一个MovableEntity添加必要组件的对象是否可行?

public class MovableEntity extends Entity {
    public MovableEntity(int x, int y) {
        addComponent(new PositionComponent(x, y));
        addComponent(new VelocityComponent());
        ...
    }
}
4

3 回答 3

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当想要克隆 a 时,从可移动的对象中克隆出 a MoveableEntity)。

所以至少对于实体来说,我真的认为你最好不要扩展它们。我可以看到更多组件类型继承的用例,尽管我仍然建议不要这样做,因为 ECS 在访问组件方面非常灵活,不需要通过组件基类型的多态性。如果您想在另一个组件中重用一个组件的数据字段,您可以只使用组合。

继承向 ECS 添加了一种竞争类型的模型,它不会那么漂亮,除非您这样做是为了更容易地使用一组特定的组件构建特定类型的实体,这又可以通过一个没有引入全新实体类型的简单函数。

于 2017-12-21T04:40:01.687 回答
1

如果您不需要在实体中动态添加/删除组件,则可以使用继承来定义实体(在具有多重继承的语言中)。考虑以下来自Evolve Your Hierarchy的 ECS 示例:

在此处输入图像描述

您的组件将对应于类:

  • 班级职位
  • 阶级运动
  • ...

并且您的实体将对应于类:

  • 类外星人:位置,运动,渲染,...
  • 类球员:位置,运动,物理,...
  • ...
于 2016-05-08T01:59:00.327 回答
0

虽然不是标准的,但我发现这种做法非常有用。想象一个战士有HP、攻击和防御的游戏。您可以编写一个接受枚举和值的 stat 组件。另一种方法是拥有一个包含其他实体的组件,并使每个 stat 本身成为具有值和类型组件的实体。我尝试了这两种方法,但我不喜欢早期的结果。(后者运行良好,但确实很复杂,但它确实严格遵守 ECS 设计)

最后我把每一个都做成了一个继承自 Component 的 StatComponent。这意味着我可以执行所有统计数据通用的操作,这非常方便。诀窍是让每一点 OOP 都陷入泡沫中。只要它是自包含的,我就看不到任何重大问题。

于 2016-08-24T05:09:30.527 回答