如何使用基于组件的架构设计有效的游戏对象交互方案?


14

这是一个设计问题。我敢肯定,这可以进一步推广,但是我很难过。我想知道游戏对象交互的设计-这是我的示例(二维拼图平台)。

假设玩家正在尝试逐步升级。有许多可以指向不同方向的灯。这是这些灯光对象如何相互作用的示例。

  • 一盏灯投射出一个平台,使玩家可以越过空隙
  • 一盏灯会降低其触摸的任何物体的摩擦系数,另一盏灯会增加它的摩擦系数。
  • 一盏灯使所有灯的效果无效,这将使平台在该灯打开时消失,并使摩擦修饰符无效。
  • 等等...

使用组件体系结构时解决此问题的最佳方法是什么?每个主要对象的组件似乎都是显而易见的,而且是一种清晰的方法来定义其对环境的影响。一个用来“解决”交互作用的类(好像这样很快就会变得一团糟)?使用装饰器模式为在给定时间进行交互的对象创建组合对象?一个适合这种情况的数据结构?

另外,将音频连接到这些交互吗?似乎将音频连接到系统就像连接其他属性一样,例如可见性或播放器移动/碰撞。

显然,随着添加更多组件,如果有一个健壮的系统可以进行少量修改就可以处理新组件,那将是很好的选择,但是我不熟悉如何进行此设计。

其他信息:我使用的引擎是一个名为IceCream的XNA引擎。



2
但是,这里有一个实际的问题,与Joe给出的链接中的“问题”相反。
dash-tom-bang 2010年

2
没有看到这个骗子,问题在于如何使用组件系统在代码中设计特定游戏的要求(@Christopher:提及哪一个会有所帮助,您使用Unity还是Torque?专有?)
LearnCocos2D

2
我喜欢您的游戏思路=)
Nailer

Answers:


5

在面向对象的系统中,什么是最好的X方式的唯一真正答案是,您应该以想到的最直接的方式来启动和运行某项,然后在运行时更改它。更容易表达。在编写任何代码之前,要考虑选择正确的模式,这是使自己从一开始就得到错误答案的好方法。让所有关于模式和组件的想法融为一体,然后按照以下步骤从您现在的位置开始(假设您已经实现了一个轻量级的组件):

  1. 将代码添加到项目平台的light组件中。(使此工作。)
  2. 将该组件复制到一个新组件中,删除平台内容并添加代码以减少适当对象的摩擦。(使此工作正常,确认#1仍然有效。)
  3. 将该组件复制到一个新组件中,删除“新”代码并添加内容以禁用其他组件的效果。(使此工作正常,然后验证#1和#2仍然有效。)

此时,您(可能)将有大量重复的代码。将通用代码提取到函数或其他类(可能是基类)中或任何合适的地方。仅仅因为您从“ light component”开始,并不意味着LightComponent是合适的基础。可能是组成轻型组件的任何代码本身都不是真正的“组件”,也许最好用一组函数甚至一个单独的类(最好是聚合到您的新组件中)来表示(作为成员变量) )。


我将其标记为答案,因为它确实回答了“我应该如何设计...”。谢谢,这绝对使我走上了正确的道路。
Christopher Horenstein'9

2

一般而言,当类型A的对象与类型B的对象交互时,您希望产生某种效果C。这被称为“双重调度”,并且很难在类似C的语言中优雅地完成。

有效但难于维护的方法只是一堆switch和if语句,这取决于对象的类型。您可能会写脏东西,但可以完成工作。

访问者模式是一种更可靠的解决方案,它隐藏讨厌型开关,但也可以是clumbersome成立。

通常,代码中任何类型的类型转换都是一种气味,但是在这里,您试图概括多态性(通常将基于一种类型的功能转换为基于两种类型的功能)。多态性是OOP的基础,因此不是气味。


2

让我看看。这只是我在写作时脑海中浮现的东西,如果我缺少某些东西,对不起。

使所有光节点都在您的家伙周围的合理距离内。

对于每个光源,您都会渲染一个表示其对帧缓冲区对象的作用区域的多边形。因此,光锥将在FBO中创建一种像素类型的锥。以适当的优先级渲染每个节点类型。您可以将信息编码到每个像素中,例如绿色通道可能是摩擦,红色是重力,蓝色和alpha是其他东西。

巧妙的色彩融合技术可以创造出有趣的效果。每个关卡都可以有自己的混合规则。您还可以添加片段阴影来获得迷幻的动态效果,例如脉动重力等。

最后,只要检查您的Mandude触摸了哪些像素,并在靠近预计算区域的边缘时重新计算位图即可。

在2分钟内进行了粗略的说明,这说明了我的想法:

插图

编辑:实际上,这意味着您唯一需要的就是一个发出某种颜色的光分量。与什么颜色有关的规则完全可以在其他地方完成。您可以将大量数据编码为pr像素的32位。或者,您可以有多个FBO,它们包含互不影响的不同属性。您可能有一个重力/摩擦FBO和一个1bit碰撞FBO。如果选择此选项,则当然必须标记灯光应渲染到哪个FBO。


谢谢您的意见。我非常欣赏视觉效果,这确实让我思考了技工如何在后台工作。
克里斯托弗·霍伦斯坦

嘿,没问题。我知道它无法回答您的确切问题,但是有些问题需要专门的解决方案。祝好运!
Nailer

0

观察者模式是最好的解决方案之一。消息将仅发送到真正对其感兴趣的对象(组件)。因此,接收者必须订阅此消息/事件类型。

有许多信号/插槽实现。例如,在C ++中有一个 sigslot库

有关更多信息,请阅读有关Qt信号和插槽的信息

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.