gpt4 book ai didi

oop - 基于组件的游戏引擎中的通信

转载 作者:行者123 更新时间:2023-12-03 11:51:03 25 4
gpt4 key购买 nike

对于我正在制作的 2D 游戏(对于 Android),我使用的是基于组件的系统,其中 GameObject 包含多个 GameComponent 对象。 GameComponents 可以是诸如输入组件、渲染组件、子弹发射组件等。目前,GameComponents 拥有对拥有它们的对象的引用并可以对其进行修改,但 GameObject 本身只有一个组件列表,它并不关心组件是什么,只要在对象更新时可以更新它们即可。

有时一个组件有一些 GameObject 需要知道的信息。例如,对于碰撞检测,游戏对象向碰撞检测子系统注册自己,以便在它与另一个对象碰撞时得到通知。碰撞检测子系统需要知道对象的边界框。我将 x 和 y 直接存储在对象中(因为它被多个组件使用),但宽度和高度只有保存对象位图的渲染组件才知道。我想在 GameObject 中有一个方法 getBoundingBox 或 getWidth 来获取该信息。或者一般来说,我想将一些信息从组件发送到对象。但是,在我当前的设计中,GameObject 不知道它在列表中有哪些特定组件。

我可以想到几种方法来解决这个问题:

  • 我可以让 GameObject 拥有一些重要组件的特定字段,而不是拥有一个完全通用的组件列表。例如,它可以有一个名为renderingComponent的成员变量;每当我需要获取对象的宽度时,我只使用 renderingComponent.getWidth() .这个解决方案仍然允许通用组件列表,但它对其中一些组件的处理方式不同,而且我担心我最终会得到几个异常字段,因为需要查询更多组件。有些对象甚至没有渲染组件。
  • 将所需信息作为 GameObject 的成员,但允许组件对其进行更新。因此,对象的宽度和高度默认为 0 或 -1,但渲染组件可以在其更新循环中将它们设置为正确的值。这感觉像是一种 hack,为了方便起见,我最终可能会将许多东西推送到 GameObject 类,即使并非所有对象都需要它们。
  • 让组件实现一个接口(interface),该接口(interface)指示它们可以查询的信息类型。例如,渲染组件将实现 HasSize 接口(interface),该接口(interface)包括 getWidth 和 getHeight 等方法。当 GameObject 需要宽度时,它会遍历其组件,检查它们是否实现了 HasSize 接口(interface)(在 Java 中使用 instanceof 关键字,在 C# 中使用 is)。这似乎是一种更通用的解决方案,一个缺点是搜索组件可能需要一些时间(但是,大多数对象只有 3 或 4 个组件)。

  • 这个问题不是关于特定问题的。它经常出现在我的设计中,我想知道处理它的最佳方法是什么。因为这是一个游戏,所以性能有点重要,但每个对象的组件数量通常很少(最多为 8 个)。

    短版

    在基于组件的游戏系统中,在保持设计通用性的同时将信息从组件传递到对象的最佳方式是什么?

    最佳答案

    我们每周在 GameDev.net(游戏对象通常被称为“实体”)上每周获得三到四次关于这个问题的变体,到目前为止,还没有就最佳方法达成共识。几种不同的方法已被证明是可行的,所以我不会太担心。

    但是,通常问题与组件之间的通信有关。人们很少担心从组件向实体获取信息——如果实体知道它需要什么信息,那么它大概知道它需要访问什么类型的组件以及它需要在该组件上调用哪个属性或方法来获取数据。如果您需要 react 而不是主动,则注册回调或使用组件设置观察者模式,以让实体知道组件中的某些内容何时发生更改,并读取该点的值。

    完全通用的组件在很大程度上是无用的:它们需要提供某种已知的接口(interface),否则它们存在的意义不大。否则,您也可以只拥有一个大的无类型值关联数组并完成它。在 Java、Python、C# 和其他比 C++ 稍高级的语言中,您可以使用反射为您提供一种更通用的方式来使用特定子类,而无需将类型和接口(interface)信息编码到组件本身中。

    至于沟通:

    有些人假设实体将始终包含一组已知的组件类型(其中每个实例都是几个可能的子类之一),因此可以直接获取对另一个组件的引用并通过其公共(public)接口(interface)进行读/写。

    有些人正在使用发布/订阅、信号/槽等,在组件之间创建任意连接。这似乎更灵活一些,但最终您仍然需要了解这些隐式依赖关系的知识。 (如果这在编译时就知道了,为什么不直接使用以前的方法呢?)

    或者,您可以将所有共享数据放在实体本身中,并将其用作每个组件都可以读取和写入的共享通信区域(与 AI 中的 blackboard system 密切相关)。这通常需要一些鲁棒性,以应对某些您期望它们不存在的属性。它也不适合并行性,尽管我怀疑这对小型嵌入式系统来说是一个巨大的问题......?

    最后,有些人的系统根本不存在实体。组件存在于它们的子系统中,实体的唯一概念是某些组件中的 ID 值 - 如果渲染组件(在渲染系统内)和播放器组件(在播放器系统内)具有相同的 ID,那么您可以假设前者处理后者的绘图。但是没有任何单个对象可以聚合这些组件中的任何一个。

    关于oop - 基于组件的游戏引擎中的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3180077/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com