陈述实体或组件的变化


9

我在确定如何处理实体中的状态管理时遇到了一些麻烦。

我对游戏状态管理没有任何麻烦,例如暂停和菜单,因为它们没有作为实体组件系统处理;只是带有实体/组件中的状态。

以“兽人必须死”为例,我有MainCharacter和Trap实体,它们只有诸如PositionComponent,RenderComponent和PhysicsComponent之类的组件。

在每次更新时,实体都会调用其组件的更新。我也有一个通用的EventManager,带有用于不同事件类型的侦听器。

现在,我需要能够放置陷阱:首先选择陷阱和陷阱位置,然后放置陷阱。

放置陷阱时,它应该出现在MainCharacter的前面,以不同的方式呈现并跟随它。放置后,它应仅响应碰撞并以常规方式进行渲染。

通常在基于组件的系统中如何处理?

(此示例是特定的,但可以帮助您确定处理实体状态的一般方法。)


1
您可以基于输入事件添加和删除实体的组件吗?也许您可以在状态更改时更改陷阱的组件。例如,放置陷阱时,它将具有FollowComponent和RenderEffectComponnent。放置后,同时删除两个Components并添加CollisionComponent。(编辑:马丁·
索伊卡

是的,我可以,每个输入都从“ HumanView”转换为游戏事件,其中大多数首先由我的GameLogic类进行处理,例如,它将检查MainCharacter是否有足够的钱来放置陷阱,如何处理发生之后,这就是我要计算的。
GriffinHeart

Answers:


6

组件系统的一个有趣应用是,如果您设计了能够处理实体的组件,则可以在运行时更改其组件。因此,实体的状态成为为其分配了哪些组件以及这些组件拥有哪些值的总和。

对于您的示例,您可以首先使用BuildControllerComponent(在构建阶段控制对播放器控件的反应),a PositionComponent和a 创建陷阱RenderComponent。最后一个具有一个数据字段,该数据字段控制使用的像素着色器,其中一个为要构建的陷阱提供“幽灵般”的外观。您会注意到尚未分配任何物理组件。

放置陷阱后,组件将被更换。在BuildControllerComponent不需要了,所以它被移除。该RenderComponent的着色器会被替换成陷阱你的正常标准视图。最后,PhysicsComponent将陷阱起作用所需的所有其他条件也添加到了实体中。

在基于继承的方法中,这等效于为一个ActiveTrapEntity类构造一个以BuildTimeTrapEntity类作为其参数的构造函数,第二个用于在构造陷阱时渲染陷阱,第一个在陷阱到位后用于陷阱。


这很聪明。
Cypher 2012年

1
这是应用实体状态的好策略。它没有解决如何跟踪每个实体的状态的问题。您如何知道该实体当前处于哪个状态?
MichaelHouse

@MartinSojka这跟我问完问题后的想法差不多。我正在考虑添加一个BuildTrapProcess(在GameLogic上已进行了一些更新),它将管理更改组件的运行时方面,以实现构建陷阱所需的状态更改。当按下用于建立陷阱的按钮时,游戏逻辑将创建流程并启动它。对这种方法有什么想法?
GriffinHeart

@ Byte56:通常,您可以查询关联的组件及其值。实际上,您通常只需要知道整个状态的相关子集,例如“此实体有BuildControllerComponent吗?” 或“该实体在其中记录的位置(PositionComponent如果有)吗?” -通过检查组件列表中您感兴趣的组件并有选择地查询(某些)它们的值来进行的操作。
马丁·索卡

1
@GriffinHeart:我只需要实现在与管理BuildControllerComponents 相关的系统中“构建”陷阱所需的一切。它已经需要处理玩家角色(或相机)的视点变化以及按键和鼠标按下事件。
马丁·索伊卡

5

我不喜欢实体在其组件上调用更新的想法(系统应该在进行工作),这会导致保持组件之间彼此不知情的问题。

您可以添加一个名为“状态”的附加组件。渲染和碰撞系统将访问它。状态组件只是一个具有多个可用状态的标志。对于这种情况,您描述的状态是PlayBuild。当渲染系统看到状态为时,Build它将绘制透明的对象。当碰撞系统看到Build状态时,将不会处理与玩家的碰撞。

但是,实际上,如果您没有系统,并且依靠组件来完成所有工作,那么您将遇到很多问题。组件不应该彼此了解,也不应进行处理。


您在说的是矛盾的,首先他们应该不知道(我同意),然后再跟随其他人访问的组件。你能澄清一下吗?我将组件与事件系统分离。
GriffinHeart

我都说。我是说他们应该不知道,并尝试根据我认为您处理组件的方式来定制我的回答。当您说“实体将调用其组件的更新”时,使我相信您没有系统处理实体。我删除了令人困惑的语言,只是说它是系统。我之所以说组件是因为我了解这就是您正在更新的方式。
MichaelHouse

我喜欢一个StateComponent可以被多个系统使用的想法。
Cypher 2012年

1
礼貌地提供拒绝投票的理由。谢谢。
MichaelHouse

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.