我正在创建一个 component-based game object system .一些提示:
GameObject
只是一个Components
列表。- 有
游戏子系统
。例如,渲染、物理等。每个GameSubsystem
都包含指向某些Components
的指针。GameSubsystem
是一个非常强大和灵活的抽象:它代表游戏世界的任何部分(或方面)。
需要一种在GameSubsystems
中注册Components
的机制(当创建和组合GameObject
时)。有4种方法:
- 1: Chain of responsibility图案。每个
Component
都提供给每个GameSubsystem
。GameSubsystem
决定要注册哪些Components
(以及如何组织它们)。例如,GameSubsystemRender 可以注册 Renderable Components。
亲。 Components
对它们的使用方式一无所知。低耦合。 A. 我们可以添加新的GameSubsystem
。例如,让我们添加 GameSubsystemTitles,它注册所有 ComponentTitle 并保证每个标题都是唯一的,并提供按标题查询对象的接口(interface)。当然,在这种情况下,不应重写或继承 ComponentTitle。 B. 我们可以重组现有的GameSubsystems
。例如,GameSubsystemAudio、GameSubsystemRender、GameSubsystemParticleEmmiter 可以合并到 GameSubsystemSpatial 中(将所有音频、emmiter、渲染 Components
放在同一层次结构中并使用父级相对转换)。
反对。逐一检查。非常低效。
反对。 子系统
了解组件
。
- 2:每个
子系统
搜索特定类型的组件
。
亲。性能优于方法 1
。
反对。 子系统
仍然了解组件
。
- 3:
Component
在GameSubsystem(s)
中注册自己。我们在编译时知道有一个 GameSubsystemRenderer,所以我们让 ComponentImageRender 调用类似 GameSubsystemRenderer::register(ComponentRenderBase*) 的东西。
Observer图案。Component
订阅“更新”事件(由GameSubsystem(s)
发送)。
亲。表现。没有方法 1
和 方法 2
中的不必要检查。
反对。 Components
与 GameSubsystems
严重耦合。
- 4:Mediator图案。
GameState
(包含GameSubsystems
)可以实现 registerComponent(Component*)。
亲。 Components
和 GameSubystems
彼此一无所知。
反对。在 C++ 中,它看起来像丑陋且缓慢的 typeid-switch。
问题:
哪种方法更好并且主要用于基于组件的设计?什么实践说?关于方法 4
的(数据驱动的)实现有什么建议吗?
谢谢。
最佳答案
投票给第三种方法。
我目前正在研究基于组件的游戏对象系统,我清楚地看到这种方法的一些额外优势:
组件越来越成为自给自足的子实体,因为它仅依赖于一组可用的子系统(我假设这组子系统在您的项目中是固定的)。
数据驱动设计更适用。理想情况下,您可以通过这种方式设计一个系统,其中的组件完全用数据而不是 C++ 定义。
编辑:我在开发 CBGOS 时想到的一个功能。有时,能够设计和构造无子系统 无源组件会很方便。当您想到这一点时,第四种方法是唯一的方法。
关于c++ - 在游戏子系统中注册游戏对象组件? (基于组件的游戏对象设计),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3958455/