我正在创建一个component-based game object system。一些提示:
GameObject
只是Components
。GameSubsystems
。例如,渲染,物理等。每个GameSubsystem
都包含指向某些Components
的指针。 GameSubsystem
是一个非常强大而灵活的抽象:它代表了游戏世界的任何片段(或方面)。需要在Components
中注册GameSubsystems
的机制(创建和编写GameObject
时)。有 4种方法:
Component
都会提供GameSubsystem
。 GameSubsystem
做出Components
注册(以及如何组织它们)的决定。例如,GameSubsystemRender可以注册可渲染组件。亲。 Components
对如何使用它们一无所知。低耦合。 A. 我们可以添加新的GameSubsystem
。例如,让我们添加注册所有ComponentTitle的GameSubsystemTitles,并保证每个标题都是唯一的,并提供按标题查询对象的接口。当然,在这种情况下,ComponentTitle不应该被重写或继承。 B. 我们可以重新组织现有的GameSubsystems
。例如,GameSubsystemAudio,GameSubsystemRender,GameSubsystemParticleEmmiter可以合并到GameSubsystemSpatial中(将所有音频,emmiter,render Components
放在同一层次结构中并使用父相对变换)。
CON。每一次检查。效率很低。
CON。 Subsystems
了解Components
。
Subsystem
搜索特定类型的Components
。亲。比Approach 1
更好的表现。
CON。 Subsystems
仍然了解Components
。
Component
在GameSubsystem(s)
中注册。我们在编译时知道有一个GameSubsystemRenderer,所以让我们的ComponentImageRender会调用类似GameSubsystemRenderer :: register(ComponentRenderBase *)的东西。Component
订阅了“更新”事件(由GameSubsystem(s)
发送)。亲。性能。没有不必要的检查,如Approach 1
和Approach 2
。
CON。 Components
与GameSubsystems
非常吻合。
GameState
(包含GameSubsystems
)可以实现registerComponent(Component *)。亲。 Components
和GameSubystems
对彼此一无所知。
CON。在C ++中,它看起来像丑陋和慢速的typeid-switch。
问题:
哪种方法更好,主要用于基于组件的设计?实践说什么?关于Approach 4
的实施(数据驱动)的任何建议?
谢谢。
答案 0 :(得分:2)
投票支持第三种方法。
我目前正致力于基于组件的游戏对象系统,我清楚地看到了这种方法的一些额外优势:
组件越来越自给自足,因为它只依赖于一组可用的子系统(我认为这个组合在你的项目中是固定的)。
数据驱动设计更适用。理想情况下,您可以通过这种方式设计一个系统,其中组件完全按照数据而非C ++定义。
编辑:我在研究CBGOS时考虑过的一个特性。有时可以方便地设计和构建无子系统无源组件。当你想到这一点时,第四种方法是唯一的方法。
答案 1 :(得分:1)
我的方法是在每个子系统中实现代理模式。由于每个子系统仅对每个实体可能包含的总组件的子集感兴趣,因此代理仅存储指向系统所关心的组件的指针,例如,运动系统仅关注位置和速度,因此它需要存储的代理两个指针,到那些组件。如果实体缺少其中的一个或多个,则子系统将忽略它。如果两个组件都存在,则创建代理节点并将其添加到内部集合。代理还可以存储实体的唯一标识符值,以便在必要时可以在每个子系统的固定时间内添加/删除代理。
以这种方式,如果要求从引擎中删除实体,则可以将包含实体ID的单个消息发送到每个子系统。然后可以独立地从每个子系统集合中删除代理。