这是我对这个问题的回答,但是我回答了一个更具体的主题。
这个答案使我比本文更好地理解了实体系统。
我读了 有关实体系统的文章(是的),它告诉我以下内容:
实体只是一个id和一组组件(文章说,将实体存储在组件中不是一种好方法,但没有提供替代方法)。
组件是数据片段,它们指示可以对特定实体执行的操作。
系统是“方法”,它们对实体上的数据进行操作。
在许多情况下,这似乎确实可行,但是有关组件仅仅是数据类的部分让我感到困扰。例如,如何在实体系统中实现Vector2D类(位置)?
Vector2D类保存数据:x和y坐标,但是它也具有方法,这对于其有用性至关重要,并且可以将类与仅包含两个元素的数组区分开。实施例的方法有:add()
,rotate(point, r, angle)
,substract()
,normalize()
,和所有其他的标准,有用的和绝对需要的方法该位置(其是对的Vector2D类的实例)应该有。
如果该组件只是一个数据持有者,它将无法使用这些方法!
一种可能弹出的解决方案是在系统内部实现它们,但这似乎非常违反直觉。这些方法是我现在要执行的事情,要使它们完整并可以使用。我不想等待MovementSystem
读取一些昂贵的消息,这些消息指示它对实体的位置进行计算!
并且,该文章非常清楚地指出,只有系统才应该具有任何功能,而对此的唯一解释是“避免OOP”。首先,我不明白为什么我应该避免在实体和组件中使用方法。内存开销实际上是相同的,并且当与系统耦合时,它们应该非常容易实现并以有趣的方式组合。例如,系统只能向知道实现本身的实体/组件提供基本逻辑。如果您问我-这基本上是从ES和OOP那里获得的好处,根据本文的作者所说,这是无法完成的,但是对我来说,这似乎是一种好习惯。
这样想吧;游戏中有许多不同类型的可绘制对象。普通的旧图像,动画(update()
,getCurrentFrame()
等),这些原始类型的组合以及所有这些都可以简单地为draw()
渲染系统提供一种方法,然后该方法无需关心实体的sprite是如何实现的,关于界面(绘制)和位置。然后,我只需要一个动画系统,该系统将调用与渲染无关的特定于动画的方法。
还有另一件事……关于存储组件,真的有数组的替代方法吗?除了实体类中的数组,我看不到要存储组件的其他地方。
也许这是一个更好的方法:将组件存储为实体的简单属性。例如,位置组件将粘贴到entity.position
。
的唯一其他方法是有某种奇怪的查找表的内部系统中,引用不同的实体。但是,这似乎非常低效的,更复杂的比在实体只需存储组件来开发。