我今天刚刚注意到,当我编译并运行一个新的XNA 4.0游戏时,其中一个CPU线程以100%的速度运行,帧速率降至54 FPS。
奇怪的是,它有时会以60 FPS的速度运行,但之后只会下降到54 FPS。
之前我没有注意到这种行为,所以我不知道这是否正常。我卸载了我的防病毒软件并重新安装了XNA Game Studio,XNA Redistributable和.NET Framework 4。
如果我将IsFixedTimeStep设置为false,则游戏以60 FPS运行,CPU使用率最低(1-2%)。但据我所知,这需要我使用ElapsedGameTime进行速度计算,但我不知道该怎么做,因为我对XNA很新。但有人说将其设置为false可以减少动画的抖动。
我已经检查了this forum thread,但没有人找到一个好的解决方案。
有没有人遇到过这个问题?
修改 我做了更多的研究,我实现了一个FPS计数器(直到现在,我用Fraps测量它),我的计数器显示游戏运行速度为60 FPS(IsFixedTimeStep = true),所以这解决了FPS问题,但是高CPU用法依旧。这可能发生在每个人身上吗?
答案 0 :(得分:19)
根据this discussion on XBox Live Indie Games forum,显然在某些处理器(和OS-s)上,当默认值 Game.IsFixedTimeStep
100%的CPU时间>已使用。
一个通用解决方案(也适用于我的方法)是将以下内容放在Game
构造函数中:
IsFixedTimeStep = false;
true
属性,Update()
时确保您的框架(Draw()
,Game.TargetElapsedTime
,...)以固定时间间隔调用< / strong>在Game.IsFixedTimeStep = false
中指定。默认为每秒60次调用。
当Vector3 velocity;
Vector3 position;
时,对前一帧的调用将在前一帧完成时发生。这在下面的时间图中说明:
需要修改所有固定时间计算(动作,时间等)以适应可变时间步长。值得庆幸的是,这很简单。
假设你有
position += velocity;
对于某个对象,您正在使用
更新位置60 * velocity.Length()
默认情况下,这意味着您的对象的速度 position += velocity * 60 * gameTime.ElapsedGameTime.TotalSeconds;
每秒单位。你每秒加速60次。
当您将该句子翻译成代码时,您会得到简单修改:
{{1}}
简单来说:您根据已经过了多长时间来扩展您添加的值。
通过在您执行移动(或计时等)的地方进行这些修改,您将确保您的游戏在固定的时间步长时恢复运作。
答案 1 :(得分:-1)
高CPU使用率(一个核心100%)是游戏的 无问题 。换句话说,它是预期的。你在编写游戏时使用CPU的方式要求你这样做。
打开代码环境并编写一个简单的程序
void main(){
while(1) puts( "aaah" ) ;
}
打开CPU监视器,看看是否使用了100%的核心。
现在你的游戏正在这样做:
void main(){
while(1){
update() ;
draw() ;
while( getTimeElapsedThisFrame() < 1.0/60.0 ) ; // busy wait, until 16ms have passed
}
}
所以基本上你打电话给update()
和draw()
,这占据了你计算一个帧的大部分时间(你 占据了你的大部分时间游戏里面有很多东西)。
现在因为O/S sleep resolution is not exact(如果你打电话给sleep( 1ms )
,它实际上可能会在你的应用再次唤醒之前睡眠 20ms ),会发生的事情是游戏永远不会打电话O / S系统功能Sleep
。 Sleep
功能会让您的游戏“过度睡眠”,游戏会显得迟钝而且速度慢。
良好的CPU使用率不值得拥有无响应的游戏应用程序。因此标准是“忙等待”并在占用CPU时缩短时间。