当窗口具有焦点时 XNA 滞后
我正在使用 XNA 3.1 为 xna game studion 进行开发,我注意到一些游戏存在一个问题,尽管系统有足够的资源来处理它们,但它们仍然滞后,并且处理器使用率莫名其妙地过多。当游戏窗口处于焦点状态时,进程 #1(在任务管理器中)的使用率达到 100%,并且游戏显示出轻微滞后的迹象(当音效按顺序重复时非常明显)。当游戏失去窗口焦点时,它继续实时绘制和更新,但进程使用率减少,滞后消失。
我用各种游戏对此进行了测试,结果保持不变,证明它与我的代码或代码效率无关。
这是 Xna 3.1 独有的问题吗?有解决办法吗?或者我是否只需切换到 4.0 并希望我的游戏不要使用任何不向后兼容的东西?
I'm developing for xna game studion using XNA 3.1, and I've noticed a problem with some games, where they lag despite the system having plenty of resources to handle them, along with an inexplicable excess of processor usage. When the window from the game is in focus, process #1 (in task manager) goes to 100% usage, and the game shows signs of minor lag (largely notable when sound effects are repeated in sequence). When the game loses window focus, it continues to draw and update at real time, but the process usage decreases, and the lag disappears.
I have tested this with various games, and the results remain the same, proving that it has nothing to do with my code or code efficiency.
Is this a problem isolated to Xna 3.1, and is there fix for it? Or do I just have to switch to 4.0 and hope my games don't use anything that isn't backwards compatible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
该问题可能是由于垃圾收集器而发生的。每次垃圾收集器运行时,帧速率可能会下降一两秒,但在 Windows 上这应该不是问题。
将此行添加到您的代码中并查看生成了多少堆内存。每当该值下降时,就会运行垃圾收集器。
SpriteBatch.DrawInt64 是一个 SpriteBatch 扩展,不会在 int、long 等上生成垃圾。您也可以只使用 SpriteBatch.DrawString(..., (GC.GetTotalMemory(false) / 1000).ToString(), ... )
SpriteBatchExtensions .cs:http://pastebin.com/z9aB7zFH
The problem may occur because of garbage collector. Everytime garbage collector runs, the frame rate may drop for a second or two, though on Windows it shouldnt be a problem.
Add this line to your code and see how much heap memory is generated. Every time the value goes down, garbage collector is ran.
SpriteBatch.DrawInt64 is a SpriteBatch extension which doesnt generate garbage on int, long etc. You can alternatively just use SpriteBatch.DrawString(..., (GC.GetTotalMemory(false) / 1000).ToString(), ... )
SpriteBatchExtensions.cs : http://pastebin.com/z9aB7zFH
根据我的经验,XNA 在对焦时每秒运行高达 60 帧,在失焦时每秒运行约 20 帧。但是,如果您设置了
IsFixedTimeStep = false;
,当进程处于焦点状态时,游戏将尽可能快地运行。在我的机器上,我的游戏运行速度约为 500-700 fps。这也与发生的Update()
调用的数量有关。所以我的游戏每秒更新500-700次。我敢打赌,您已经禁用了固定时间步长,并且大量的 Update 和 Draw 调用正在消耗您 100% 的核心资源,并且会扰乱您的音乐。我建议删除
IsFixedTimeStep = false;
行(如果存在)。如果您的代码中不存在该行,则这不是问题,尽管我敢打赌您的 Update 或 Draw 所做的工作比应有的要多。刚刚在我自己的游戏中注意到这一点,我的更新循环中有一个 Console.WriteLine 语句(用于调试),这会导致很多滞后。
XNA, from my experience, runs up to 60 frames per second while in focus, and at about 20 frames per second when out of focus. IF however, you have set
IsFixedTimeStep = false;
the game will run as fast as it possibly can when the process is in focus. With my game, on my machine, it runs at about 500-700 fps. This is also tied in to the number ofUpdate()
calls that occur. So my game is also updating 500-700 times per second.My bet is that you have disabled the fixed timestep, and the massive number of Update and Draw calls are consuming 100% of your core and it is messing with your music. I would recommend removing the line
IsFixedTimeStep = false;
if it's there. If that line does not exist in your code, this is not the problem, although I would bet that your Update or Draw is doing more work than it should be.Just noticed this in my own game, I have a Console.WriteLine statement (for debugging) in my update loop, this causes lots of lag.
XNA 添加了窗口未聚焦时的睡眠!
我不久前解决了这个问题,重写 Game 类并更改 Game 类理解其形式是否活动的方式。
据我所知,没有办法在不使用代码修改 Game 类行为的情况下禁用此行为。
特别是,我前段时间发现的方法是一个真正的黑客\怪癖!
非常不干净的解决方案,但我找到的唯一方法。
XNA add a sleep when the window is not in focus!
I solved this problem some time ago overriding Game class and changing the way the Game class understand its form is active or not.
There is not way, as much as i know, to disable this behaviour without modifying Game class behaviour with code.
In particular, the way i found some time ago is a real hack\quirk!
Very unclean solution, but the only way i found.