我写我自己的游戏,其处理大量的游戏实体(计数≈1000)的巨量。 每个实体都必须在屏幕上绘制。一开始我不确定C#会给我一个好的帧率。但是,当我应用一些基本的扑杀时,我被更高的帧率震惊。管理对象
所以,现在,当我将AI逻辑添加到实体时,每个对象的更新时间都需要一定的时间。我有对象的列表,我循环它们并调用obj.Update(dt)。看起来这种方式不是最好的。更新“巨大”的实体可能需要很多ms,所以其他人需要等待这个人完成自己的更新。
所以我的问题是:当管理大量的动态对象时哪种方式更好?
我写我自己的游戏,其处理大量的游戏实体(计数≈1000)的巨量。 每个实体都必须在屏幕上绘制。一开始我不确定C#会给我一个好的帧率。但是,当我应用一些基本的扑杀时,我被更高的帧率震惊。管理对象
所以,现在,当我将AI逻辑添加到实体时,每个对象的更新时间都需要一定的时间。我有对象的列表,我循环它们并调用obj.Update(dt)。看起来这种方式不是最好的。更新“巨大”的实体可能需要很多ms,所以其他人需要等待这个人完成自己的更新。
所以我的问题是:当管理大量的动态对象时哪种方式更好?
您遇到的问题是您正在循环调用Update
方法的对象。如果有什么东西没有更新呢?如果有什么东西需要每帧更新?
更好地将事件添加到您的主回路和你的对象订阅它:
public void FrameListener(float _ticks);
public class Game
{
public Event FrameListener OnFrame;
}
现在,每当有什么需要更新,它只是同意这样的事件(获得增量滴答计数传递到它)。当一个对象闲置时,它可以自行退订。使用这种方法,只是对象是需要更新都得到更新。另外,你可以为订阅过程添加一个计数器(意味着你可以抛弃事件对象而倾向于使用AddListener()
类型的方法),告诉系统只调用委托给每个'n'帧。在一个游戏中,例如你可能要建造生产(定居者,文明等),这些东西在每一帧都更新他们的产品是没有意义的。即使每5秒钟就够了。当您可以准确定义对象需要更新的频率时,这会减少很多开销。
静态对象只是从来没有灌输的委托,所以不会引起任何开销。
首先,1000个物体并不是真的巨大的。在60 fps时,即60 kHz,即16μs - 每个对象在大多数硬件上至少需要32,000个时钟周期。有些物体必须承担高成本。
假设您无法降低每个对象的成本,您可以为更新对象分配一个总时间预算,并在该时间结束时停止循环,但在下一帧保持循环不变,包装如果你在到达最后时还剩下更多的时间,那么你可以从头开始。简而言之,围绕一个环形缓冲区运行,每当你的时间用完时停止渲染一帧。
谢谢,当我选择C#时,我试图找到一些关于其性能的信息。很多人都说游戏开发不适合。所以我认为1000是真的很大..%-O – joe
@joe:C#通常有相当不错的表现,这些天。它仍然与精心设计的C++不相上下,但差异对于你的场景来说不应该是重要的。特别是,重GC会损害性能,所以我会对你的对象更新代码中的每个'new'采取非常黄疸的看法。同样,如果你还没有这样做,把你所有的小班变成结构。 –
我觉得你的问题是不相关的游戏开发,而是综合性能的原则。
你可能有机会去探索倍数优化性能的方法。以下是列表,但并非详尽:
甲提示更具体的游戏开发者(来自游戏开发者的新手)我承认): *尝试在子集中而不是单个集合中分割对象...有时更有效的方法是使用对象图形,而不是对象列表。您可以更新图形的单个节点而不是整个对象 *如果可能的话,排除未显示对象的更新
谢谢你提供有用的提示!不幸的是,我不能标记多个正确的答案;( – joe
没有pb :)我很高兴,如果它有帮助 –
是多线程/并行处理一个选项吗? – TDaver
http://gamedev.stackexchange.com/是游戏开发专用网站的完美内容。 –
如果可以,请考虑并行执行更新。 – jason