实体组件系统对解耦/信息隐藏不是很可怕吗?
标题故意是双曲线的,可能只是我对模式的经验不足,但这是我的理由: 实现实体的“通常”或可以说是直接的方法是通过将它们实现为对象并将其子类化为常规行为。这导致了经典的问题“是或EvilTree的子类”。如果我们允许多重继承,就会出现钻石问题。我们可以代替拉的组合功能,并进一步向上层次导致神类,或者我们可以故意留出的行为在我们和类(使他们在极端情况下接口),以便可以实现本身-这会导致如果有一个代码复制。TreeEnemyTreeEnemyTreeEntityEvilTreeSomewhatEvilTree 实体组件系统试图通过将解决这一问题Tree和Enemy对象到不同的组件-比如Position,Health和AI-和执行系统,例如AISystem,根据AI决定改变一个Entitiy的位置。到目前为止,EvilTree还算不错,但是如果可以启动电源并造成损害该怎么办?首先,我们需要一个CollisionSystem和一个DamageSystem(我们可能已经有了这些)。CollisionSystem与进行通信的需求DamageSystem:每次两件事冲突时,CollisionSystem都会向发送一条消息,DamageSystem以便减少健康状况。损坏也会受到通电的影响,因此我们需要将其存储在某个地方。我们是否创建一个PowerupComponent附加到实体的新商品?但是然后DamageSystem需要知道一些它宁愿一无所知的东西-毕竟,有些东西会造成无法获得能量的伤害(例如Spike)。我们是否允许PowerupSystem修改StatComponent与该答案类似的用于损伤计算的?但是现在两个系统访问相同的数据。随着我们的游戏变得越来越复杂,它将变成无形的依赖图,其中组件在许多系统之间共享。在这一点上,我们可以使用全局静态变量并摆脱所有样板。 有解决此问题的有效方法吗?我曾经有过一个想法,就是让组件具有某些功能,例如,给StatComponent attack()它默认情况下只返回一个整数,但是可以在上电时进行组合: attack = getAttack compose powerupBy(20) compose powerdownBy(40) 这不能解决attack必须保存在多个系统访问的组件中的问题,但是如果我有足够的语言来支持它,至少我可以正确键入这些函数: // In StatComponent type Strength = PrePowerup | PostPowerup type Damage = Int type PrePowerup = Int type PostPowerup = Int attack: Strength = getAttack //default value, can be changed by systems getAttack: PrePowerup // these functions …