游戏循环性能和组件方法

问题描述:

我有一个组织游戏循环的想法。我对性能有些怀疑。可能有更好的做事方式。如果你有一组游戏组件,他们都被要求在每个游戏循环迭代中做一些事情。例如:游戏循环性能和组件方法

GameData data; // shared 
app.registerComponent("AI", ComponentAI(data)); 
app.registerComponent("Logic", ComponentGameLogic(data)); 
app.registerComponent("2d", Component2d(data)); 
app.registerComponent("Menu", ComponentMenu(data))->setActive(false); 
//... 
while (ok) 
{ 
//... 
app.runAllComponents(); 
//... 
} 

优点:

  1. 良好基于组件的应用,没有依赖关系,良好的模块化
  2. 我们可以激活/去激活,注册/注销部件动态
  3. 一些组件可以是透明地移除或替换,并且系统仍然可以工作,因为什么也没有发生(改变2d到3d)(团队合作:每个程序员创建他/她自己的组件,并且不需要其他组件编译代码)

疑惑:

  1. 在游戏圈与虚拟调用组件:: run()的
  2. 我想组件:: run()的返回bool值,并检查该值内环。如果返回false,则必须禁用组件。所以内部循环变得更加昂贵。

那么,这个解决方案有多好?你在真实项目中使用过它吗?

一些C++程序员对虚拟函数的开销有太多担忧。与功能相比,虚拟调用的开销通常可以忽略不计。布尔检查也不是很昂贵。

在最简单的维护代码中执行任何结果。只有在需要时才进行优化。如果你确实需要优化,那么消除虚拟呼叫可能不会成为你需要的优化。

+0

您的优先级是正确的。但实际上,虚拟通话非常缓慢。当我编写粒子系统时,每个粒子的虚拟调用比每个粒子系统的调用太慢。 – 2010-04-21 11:21:59

+2

对,重要的可能是您的程序每秒需要调用多少个虚函数。 100000?没问题。但是,1000万可能是CPU总时间中的一小部分。 另一个问题是每个函数调用完成多少工作。只要大多数虚拟通话都做了不重要的工作,就没有问题了。 – Qwertie 2010-04-23 19:29:05

在大多数“真实”的游戏中,对组件之间的相互依赖性有相当严格的要求,而排序很重要。

这可能会也可能不会影响到你,但是在用户交互过程之前(或之后),根据你的场景等,物理生效通常很重要。在这种情况下,你可能需要一些额外的处理来进行排序正确。另外,由于您最有可能拥有某种形式的场景图或空间分区,因此您需要确保您的“组件”可以利用该功能。这可能意味着,根据你目前的描述,你会多次走你的树。不过,这也可以通过设计决定来解决。话虽如此,一些组件可能只对空间分区的某些部分感兴趣,并且再次想要适当地设计。

+0

这不完全是我的问题的答案,但非常有用。谢谢。 – 2010-04-21 11:24:12

+0

@topright:你的问题听起来更像是“这个设计是可以接受的”......我试图给你一些要考虑你当前的设计,如上所述。 – 2010-04-21 17:43:45

+0

我投了你的答案。 – 2010-04-23 19:14:14

我在模块化合成音频文件生成器中使用了类似的方法。

我似乎记得注意到,编程100个不同的模块后,出现了在性能产生影响的新的编码模块时。

总体上,虽然,我觉得这是一个不错的办法。

也许我是oldschool,但我真的没有看到通用组件的价值,因为我没有看到它们在运行时被换出。

struct GameObject 
{ 
    Ai* ai; 
    Transform* transform; 
    Renderable* renderable; 
    Collision* collision; 
    Health* health; 
}; 

这适用于从玩家到敌人到天空盒和触发器的所有事情;只需将给定对象中不需要的“组件”留空即可。你想把所有的AI都放到一个列表中?然后在施工时就这样做。有了多态性,你可以在其中锁定各种不同的行为(例如,玩家的“AI”正在翻译控制器输入),除此之外,不需要为所有内容创建通用基类。无论如何,它会做什么?

您的“更新所有内容”将不得不明确地调出每个列表,但这不会改变您必须执行的输入量,而只是将其移动。您不需要混淆地设置需要全局操作的集合,而是明确地列举操作完成时需要操作的集合。

恕我直言,这不是虚拟电话很慢。这是一个游戏实体的“组件”不是同质的。他们都做很大不同的事情,所以对待他们是不同的。事实上,它们之间没有重叠,所以我再次问,如果不用任何有意义的方式使用指向该基类的指针而不将其转换为其他类型,基类的意义何在?

+0

1.我受到Jeff Plummer“计算机游戏的灵活和可扩展的体系结构”的启发。他描述了数据驱动的体系结构,这些体系结构包含不了解彼此的组件,并通过数据存储和消息队列进行通信。 – 2010-04-23 20:05:01

+0

2.我也相信使用这些组件是一种灵活的方法。它允许你动态地控制游戏子系统应该工作。您可以在任何抽象级别上使用这些组件。游戏对象可以是一个组件。粒子系统可以是一个组件。整个渲染系统和AI可以是组件。菜单或游戏状态可以。等等 – 2010-04-23 20:08:02

+0

一如既往,我投你的答案。 – 2010-04-23 20:10:24