对于基于组件的体系结构,适当的粒度级别是多少?


26

我正在开发具有基于组件的体系结构的游戏。一个Entity拥有一组Component实例,每个实例都有一组Slot用于存储,发送和接收值的实例。工厂功能,例如Player具有所需组件和插槽连接的生产实体。

我正在尝试确定组件的最佳粒度。例如,现在PositionVelocityAcceleration都是串联的独立组件。Velocity并且Acceleration可以轻松地重写为统一的Delta组件或PositionVelocity并且Acceleration可以与诸如FrictionGravity组成整体Physics组件。

一个组件应该承担最小的责任(以大量的互连为代价),还是应该将相关组件组合为整体组件(以灵活性为代价)?我倾向于前者,但我可以使用第二种意见。



您要使用自己的物理引擎还是集成现有的物理引擎?

@Den:我正在写一些物理代码,但无论如何它不是引擎。只是平凡的2D运动学。
乔恩·普迪

Answers:


14

完全的粒度(不导致代码浪费或类似blob的状态(这是偏爱组件体系结构的原因))与可用性之间存在界线。

显然,事物可能具有Position,但不一定是动态的(所以为什么有Velocityand Acceleration?)。但是,带有a的东西Velocity将成为移动的对象,因此将其Acceleration分组也很有意义。

您是否有需要va的情况,但又不想对其进行物理模拟?同样,Gravity如果它们不是物理对象,是否有一点意义?

tl; dr将什么有意义。


1
听起来很公平。我的系统有非常小的集中化:如果EntityPosition一些组件,使该Position参加物理,则Entity事实上的身体。我认为我可以做的只是添加一些用于逻辑分组的组件,并将所有基本组件归于单一职责。因此增加,也就是说,一个Movable一个Entity将具有与添加相同的效果PositionVelocityAcceleration
乔恩·珀迪

6

为了避免从一开始就对我建议的每个变量进行微观管理,请选择责任划分,并在情况以逻辑方式呈现时进行重构。您可以在纸上开始第一个设计。在某些时候,这些总的责任分工将成为您实体的基础。

因此,举一个仓促的例子,您有Game。游戏分为环境+状态。环境分为StaticWorld + MovingStuff。状态分为AIControlled + PlayerControlled。损害的总体概念分为TakesDamage + GivesDamage。

等等。

很像“构建游戏,而不是引擎!”的常见建议。对于新手,我建议“构建游戏,而不是复杂的组件系统!” 因为只有亲身体验正在运行的游戏,您才能知道以后的作品中是否需要精心设计的组件系统。


我不是新开发人员。如果我基于概念有分量,而不是行为(即自上而下与自下而上),会不会我的建筑更脆,并且更详细点吗?我可以从小型组件中实现我想要的任何行为,但是我无法始终从预组合组件中获得所需的行为。更不用说即使在一场比赛的背景下,我也无法预测我想要实现的所有目标。
乔恩·普迪

自下而上的缺点是组件之间的通信成为一个问题,人们往往从他们所建模的规模开始,过于微观。我主要是试图从超微型转向“ xyz是一个组件”,“旋转是一个组件”,“ rgb是一个组件”级别,以适应没有经验的人。
Patrick Hughes

很公平。我只是想确保我正确理解了您。使用我拥有的插槽系统,组件通信变得简单而高效,因此我真的看不到“超微型”秤有任何缺点。我不打算将其重构为一个独立的引擎,但是如果这样做,那么我总是可以引入抽象,例如我在对《共产鸭》的评论中提到的组件组。
乔恩·普迪

4

我的猜测是将具有大量交互作用的组件组合在一起。在您的情况下,我会将位置保持在单个组件中,并将速度和加速度保持在物理组件中。

但这很大程度上取决于您的游戏功能(除非您在构建框架时没有考虑特定的游戏)。


2
通过大量交互将组件组合在一起的问题是,有时不需要其他部分。
共产党鸭子

4

我意识到这是一个老问题,但也许有人会觉得这个答案有用。

我相信这Systems将更好地帮助您了解如何构造组件。系统存在于体系结构中,除了简单的getter / setter和helper函数外,组件不包含自己的逻辑。系统在满足组件要求的实体上运行。这就是为什么最好分离组成部分数据,因为在没有其他数据的情况下处理该数据是有意义的。

例如,您可能有一个MovementSystemPosition根据来更新其实体Velocity。这可能适用于游戏中的简单实体。但是,对于“ 玩家”和“ 敌人”,您可能需要在Acceleration中进行处理的移动AcceleratedMovementSystem。但是对于障碍物,您可能想要Friction。该地形可能也有摩擦,但不会有一个速度分量。但是呢Gravity?只需添加播放器,敌人和障碍物,然后创建一个GravitySystem即可对其进行处理。

底线是,更多的去耦你的Components是,更多的可扩展Entities使用的时候会Systems

编辑:使最后的声明更加清晰。

编辑:好的,我一直在自己的系统上工作,并实现了这一目标。拆分“位置”和“速度”的一个示例是,操纵“速度”会使“位置”随移动系统而变化。结果,“ InputMovementSystem”不需要“ Position”就可以使播放器从用户Input移开,因为MovingSystem将拾取“ Velocity”的更改以应用于Position。当然,将它们放在一起仍然可以正常工作,但这就是为什么不需要这样做的一个示例。


我最近读了一篇博客文章,内容如下:

“如果您的数据可以与2个不同的组件分组,那么最好使用该数据创建第三个组件。”

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.