我制作了一个XNA图像查看器,但它总是重新绘制场景,即使没有变化,这让我的上网本发烫得厉害,所以我希望在没有变化时暂停绘制。
降低帧率到1是保持其冷却的一种方法,但会导致输出很卡顿。
如何在没有输入时防止重绘?
这个问题已经解决,但另一个问题被发现——当游戏窗口处于焦点状态时,游戏会消耗大量CPU,但当它没有焦点时,只需要约1%的CPU。有关如何解决这个问题的详细信息,请参见此问题:
我制作了一个XNA图像查看器,但它总是重新绘制场景,即使没有变化,这让我的上网本发烫得厉害,所以我希望在没有变化时暂停绘制。
降低帧率到1是保持其冷却的一种方法,但会导致输出很卡顿。
如何在没有输入时防止重绘?
这个问题已经解决,但另一个问题被发现——当游戏窗口处于焦点状态时,游戏会消耗大量CPU,但当它没有焦点时,只需要约1%的CPU。有关如何解决这个问题的详细信息,请参见此问题:
例如,以下代码仅调用在更新期间调用此方法,以防止任何调用绘制方法,直到下一次更新后。如果显示器由于更新而不发生更改,则可以在小型设备上使用此方法以节省电池寿命。例如,如果屏幕是静态的,没有背景动画,可以在更新期间检查玩家输入以确定玩家是否执行任何操作。如果未检测到输入,则该方法允许游戏跳过绘制,直到下一次更新。
Draw
函数一次。在我测试时,我注意到没有SuppressDraw
调用时CPU使用率很高(70%)。当使用SuppressDraw
时,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
的调用,您必须在 Update
中不断调用 SupressDraw
。希望这样说得清楚了。正如被接受的答案所说,您可以使用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
}