我制作了一个XNA图像查看器,但它总是会重新绘制场景,即使它没有改变,而且它让我的上网本烧得像地狱一样,所以我希望它能在没有任何变化时暂停绘制。
将帧速率降低到1是保持冷却的一种方法,但会导致输出滞后。
如果没有输入,如何阻止重绘?
这个问题已经解决了,但是发现了另一个问题 - 当游戏的窗口处于焦点时,游戏消耗了大量的CPU,但是当它不是时,它只需要大约1%的CPU。有关如何解决此其他问题的详细信息,请参阅此问题:
How to reduce XNA game CPU usage while nothing worth computing is happening?
答案 0 :(得分:11)
您可以使用Game.SupressDraw方法来实现此目的。从链接的评论:
在Update期间调用此方法,以防止在下次调用Update之前调用Draw。如果显示器因更新而未发生变化,则此方法可用于小型设备以延长电池寿命。例如,如果屏幕是静态的而没有背景动画,则可以在更新期间检查播放器输入以确定播放器是否正在执行任何操作。如果未检测到输入,则此方法允许游戏跳过绘图直到下次更新。
作为示例,以下代码仅调用Draw
函数一次。当我测试这个时,我注意到没有SuppressDraw
调用的CPU使用率很高(70%)。使用SupressDraw
时,CPU使用率急剧下降(低于15%)。您的电话号码可能会有所不同。
public class Game1 : Microsoft.Xna.Framework.Game
{
...
private bool _drawn = false;
protected override void Update(GameTime gameTime)
{
if (_drawn)
SuppressDraw();
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
/* draw stuff here */
spriteBatch.End();
_drawn = true;
}
...
}
请注意,SupressDraw
仅会抑制一次Draw
次呼叫。要阻止对Draw
的更多来电,您必须不断致电SupressDraw
中的Update
。希望这是有道理的。
答案 1 :(得分:0)
如接受的答案所示,您可以使用SuppressDraw来避免绘制未更改的帧。但是,您的Update方法将运行,这就是为什么它仍然使用比预期更多的CPU。为了避免使用尽可能多的CPU,您需要以某种方式避免更新自上一帧以来您知道没有更改的内容。
我认为你会知道这与你知道什么时候压制平局的方式相同,所以你需要做的是重新安排你的Update方法:
private void Update(GameTime gameTime)
{
var frameHasChanges = DetectChanges(); //This method you need to figure out yourself
if (!frameHasChanges)
{
SuppressDraw();
base.Update(gameTime);
return;
}
//Do the rest of normal Update
}
作为最后的说明;我从来没有在任何我做过的游戏中使用它。我觉得你可能会遇到其他一些潜在的性能问题。但是,我使用了许多技术来避免在每个帧上渲染文本等(导致装箱/拆箱)。如果您想了解更多,请在评论中询问。