7

我正在创建一个基于组件的游戏对象系统。一些技巧:

  1. GameObject只是一个列表Components
  2. GameSubsystems。例如,渲染、物理等。每个都GameSubsystem包含指向某些Components. GameSubsystem是一个非常强大和灵活的抽象:它代表游戏世界的任何部分(或方面)。

需要一种注册机制ComponentsGameSubsystems何时GameObject创建和组合)。有4种方法


  • 1:责任链模式。每一个Component都提供给每一个GameSubsystemGameSubsystem决定Components注册哪个(以及如何组织它们)。例如,GameSubsystemRender 可以注册 Renderable Components。

亲。Components对它们的使用方式一无所知。低耦合。A.我们可以添加新的GameSubsystem. 例如,让我们添加注册所有 ComponentTitle 并保证每个标题都是唯一的 GameSubsystemTitles,并提供按标题查询对象的接口。当然,在这种情况下不应重写或继承 ComponentTitle。B.我们可以重组现有的GameSubsystems. 例如,GameSubsystemAudio、GameSubsystemRender、GameSubsystemParticleEmmiter 可以合并到 GameSubsystemSpatial 中(将所有音频、发射器、渲染Components放在同一层次结构中并使用父相对变换)。

反对。每次检查。非常低效。

反对。Subsystems知道Components


  • 2:每个Subsystem搜索Components的特定类型。

亲。性能优于Approach 1.

反对。Subsystems还是知道的Components


  • 3:ComponentGameSubsystem(s). 我们在编译时知道有一个 GameSubsystemRenderer,所以让我们 ComponentImageRender 将调用类似 GameSubsystemRenderer::register(ComponentRenderBase*) 的东西。
    观察者模式。Component订阅“更新”事件(由 发送GameSubsystem(s))。

亲。表现。没有不必要的检查,如Approach 1Approach 2

反对。ComponentsGameSubsystems.


  • 4:中介模式。GameState(包含GameSubsystems)可以实现 registerComponent(Component*)。

亲。Components并且GameSubystems对彼此一无所知。

反对。在 C++ 中,它看起来像丑陋而缓慢的 typeid-switch。


问题: 哪种方法更好并且主要用于基于组件的设计?实践说什么?关于(数据驱动)实施的任何建议Approach 4

谢谢你。

4

2 回答 2

2

投票支持第三种方法。

我目前正在研究基于组件的游戏对象系统,我清楚地看到了这种方法的一些额外优势:

  • 组件是越来越自给自足的子实体,因为它仅依赖于一组可用的子系统(我假设这组子系统在您的项目中是固定的)。

  • 数据驱动的设计更适用。理想情况下,您可以设计一个系统,其中组件完全用数据定义,而不是 C++。


编辑:我在研究 CGBOS 时想到的一个功能。有时,拥有设计和构建无子系统无源元件的能力会很方便。当您想到这一点时,第四种方法是唯一的方法。

于 2010-10-18T11:40:24.140 回答
1

我的方法是在每个子系统中实现代理模式。由于每个子系统只对每个实体可能包含的全部组件的子集感兴趣,代理存储指向系统只关心的组件的指针,例如,运动系统只关心位置和速度,所以它需要一个代理来存储两个指针,指向这些组件。如果实体缺少其中一个或多个,则子系统将忽略它。如果两个组件都存在,则创建代理节点并将其添加到内部集合中。代理存储实体的唯一标识符值也很有用,以便在必要时可以在恒定时间内从每个子系统添加/删除代理。

这样,如果需要从引擎中删除实体,则可以将包含实体 id 的单个消息发送到每个子系统。然后可以独立地从每个子系统集合中删除代理。

于 2014-06-26T06:54:58.493 回答