2011-01-26 111 views
1

我写我自己的游戏,其处理大量的游戏实体(计数≈1000)的巨量。 每个实体都必须在屏幕上绘制。一开始我不确定C#会给我一个好的帧率。但是,当我应用一些基本的扑杀时,我被更高的帧率震惊。管理对象

所以,现在,当我将AI逻辑添加到实体时,每个对象的更新时间都需要一定的时间。我有对象的列表,我循环它们并调用obj.Update(dt)。看起来这种方式不是最好的。更新“巨大”的实体可能需要很多ms,所以其他人需要等待这个人完成自己的更新。

所以我的问题是:当管理大量的动态对象时哪种方式更好?

+4

是多线程/并行处理一个选项吗? – TDaver

+7

http://gamedev.stackexchange.com/是游戏开发专用网站的完美内容。 –

+1

如果可以,请考虑并行执行更新。 – jason

回答

3

您遇到的问题是您正在循环调用Update方法的对象。如果有什么东西没有更新呢?如果有什么东西需要每帧更新?

更好地将事件添加到您的主回路和你的对象订阅它:

public void FrameListener(float _ticks); 


public class Game 
{ 
    public Event FrameListener OnFrame; 
} 

现在,每当有什么需要更新,它只是同意这样的事件(获得增量滴答计数传递到它)。当一个对象闲置时,它可以自行退订。使用这种方法,只是对象是需要更新都得到更新。另外,你可以为订阅过程添加一个计数器(意味着你可以抛弃事件对象而倾向于使用AddListener()类型的方法),告诉系统只调用委托给每个'n'帧。在一个游戏中,例如你可能要建造生产(定居者,文明等),这些东西在每一帧都更新他们的产品是没有意义的。即使每5秒钟就够了。当您可以准确定义对象需要更新的频率时,这会减少很多开销。

静态对象只是从来没有灌输的委托,所以不会引起任何开销。

3

首先,1000个物体并不是真的巨大的。在60 fps时,即60 kHz,即16μs - 每个对象在大多数硬件上至少需要32,000个时钟周期。有些物体必须承担高成本。

假设您无法降低每个对象的成本,您可以为更新对象分配一个总时间预算,并在该时间结束时停止循环,但在下一帧保持循环不变,包装如果你在到达最后时还剩下更多的时间,那么你可以从头开始。简而言之,围绕一个环形缓冲区运行,每当你的时间用完时停止渲染一帧。

+0

谢谢,当我选择C#时,我试图找到一些关于其性能的信息。很多人都说游戏开发不适合。所以我认为1000是真的很大..%-O – joe

+0

@joe:C#通常有相当不错的表现,这些天。它仍然与精心设计的C++不相上下,但差异对于你的场景来说不应该是重要的。特别是,重GC会损害性能,所以我会对你的对象更新代码中的每个'new'采取非常黄疸的看法。同样,如果你还没有这样做,把你所有的小班变成结构。 –

1

我觉得你的问题是不相关的游戏开发,而是综合性能的原则。

你可能有机会去探索倍数优化性能的方法。以下是列表,但并非详尽:

  • 多线程/并行:可以实现很好的改进,但会增加应用程序的复杂性。如果你使用c#4,你可以看看新的并行库
  • ,这取决于你的VS的版本和版本,你可以激活代码分析(或者如果VS中不可用,使用FXcop)。该工具可以提供良好的建议
  • 使用分析工具来发现你的代码的瓶颈
  • 使用的工具来分析你的代码的复杂性,尤其是圈复杂度
  • google了一下一般性能提示(字符串生成器VS字符串连接等)
  • 谷歌多一点为硬编码性能尖端(改变的方法的参数的顺序,减少使用可变值,降低调用图等)

甲提示更具体的游戏开发者(来自游戏开发者的新手)我承认): *尝试在子集中而不是单个集合中分割对象...有时更有效的方法是使用对象图形,而不是对象列表。您可以更新图形的单个节点而不是整个对象 *如果可能的话,排除未显示对象的更新

+0

谢谢你提供有用的提示!不幸的是,我不能标记多个正确的答案;( – joe

+0

没有pb :)我很高兴,如果它有帮助 –