Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确计算XNA中的FPS?_Xna_Frame Rate - Fatal编程技术网

如何正确计算XNA中的FPS?

如何正确计算XNA中的FPS?,xna,frame-rate,Xna,Frame Rate,我编写了一个组件来显示当前FPS。 其中最重要的部分是: public override void Update(GameTime gameTime) { elapseTime += (float)gameTime.ElapsedRealTime.TotalSeconds; frameCounter++; if (elapseTime > 1) { FPS = frameCounter

我编写了一个组件来显示当前FPS。
其中最重要的部分是:

    public override void Update(GameTime gameTime)
    {
        elapseTime += (float)gameTime.ElapsedRealTime.TotalSeconds;
        frameCounter++;

        if (elapseTime > 1)
        {
            FPS = frameCounter;
            frameCounter = 0;
            elapseTime = 0;
        }
        base.Update(gameTime);
    }


    public override void Draw(GameTime gameTime)
    {
        spriteBatch.Begin();

        spriteBatch.DrawString(font, "FPS " + ((int)FPS).ToString(), position, color, 0, origin, scale, SpriteEffects.None, 0);

        spriteBatch.End();

        base.Draw(gameTime);
    }
在大多数情况下,它工作正常,但最近我遇到了一个问题。
当我把下面的代码放到游戏的更新方法中时,奇怪的事情开始发生了

       if (threadPath == null || threadPath.ThreadState != ThreadState.Running)
        {
            ThreadStart ts = new ThreadStart(current.PathFinder.FindPaths);
            threadPath = new Thread(ts);
            threadPath.Priority = ThreadPriority.Highest;
            threadPath.Start();
        }
这段代码的主要思想是始终在不同的线程中运行寻路算法

奇怪的事情,我的意思是,有时FPS衰减,这是显而易见的,但显示的FPS变化频率超过每秒一次。如果我理解这段代码,FPS的更改频率不能超过每秒一次

有人能解释一下发生了什么事吗

编辑26.03.2010
我还发布了绘制方法的代码

编辑2010年3月31日Venesectrix问题的答案
1) 您是使用固定时间步长还是可变时间步长运行?
IsFixedTimeStep和SynchronizeWithVerticalRetrace设置为true。
2) 发生这种情况时,您是否正在移动XNA窗口?

3) XNA窗口有焦点吗?

4) 它有多引人注目(例如,更新得如此之快以至于你无法阅读它,或者仅仅更新了一秒钟以上)?
我能够阅读更新,FPS每秒更新约3次。
5) 所有这些只有在线程代码在其中时才会发生?

是的

肖恩·哈格里夫斯(Shawn Hargreaves)在这方面有一篇很棒的帖子。我在他的代码和你的代码之间看到的第一个区别是,你每次都将你的elapseTime重置为0,这会损失一些时间,而Shawn只是从他的elapseTime中减去1秒。此外,Shawn使用ElapsedGameTime而不是ElapsedRealTime。他在Draw函数中更新帧计数器,而不是更新函数

至于他为什么使用ElapsedRealTime,他在帖子后的评论中解释道:

>当然是1/gameTime.ElapsedRealTime.TotalSeconds

>因此将给出当前的帧率

那会告诉你这是多久 自上次调用更新以来,但是 这和你的计划不一样 帧率

a) 如果游戏正在丢弃帧, 将更频繁地调用更新 为了赶上。你想浪费时间吗 正在绘制的实际绘制数 不仅仅是这些额外的 追赶逻辑框架

b) 一次更新的时间可以是 波动幅度很大,所以你的数字 滚开,那太不稳定了 易于阅读


我会试试他的部件,看看是否适合你。这篇文章很老了,我想你必须把LoadGraphicsContent改成LoadContent,把UnloadGraphicsContent改成UnloadContent,正如另一条评论指出的那样。

作为旁白。。。您应该避免设置线程优先级。通过将最高线程优先级分配给应该是后台线程的线程,您可能会耗尽主线程的cpu时间,因为调度程序会将优先级分配给threadPath

您是否正在积极检查IsRunningSlowly是否正在更改?即使将IsFixedTimeStep设置为true,如果您的程序无法完成预期的更新,它将更频繁地调用它

我以前缓解这种情况的一种方法是直接调用ResetElapsedTime(),而不是自己跟踪它


但我不确定这是否对你有用。我确实注意到,当我调试上一期时,它不会调用额外的更新,这可能是调试时的一个“功能”。

以下是我如何使用此方法进行调试的:

  • 平均超过n帧
  • 您可以将其与选择的任何初始化方法一起使用
  • 它应该易于阅读和理解
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用Microsoft.Xna.Framework;
使用Microsoft.Xna.Framework.Audio;
使用Microsoft.Xna.Framework.Content;
使用Microsoft.Xna.Framework.GamerServices;
使用Microsoft.Xna.Framework.Graphics;
使用Microsoft.Xna.Framework.Input;
使用Microsoft.Xna.Framework.Media;
名称空间_60fps
{
公共类游戏1:Microsoft.Xna.Framework.Game
{
图形管理器图形;
SpriteBatch SpriteBatch;
SpriteFont输出字体;
浮球Fps=0f;
private const int NumberSamples=50;//基于此样本数更新fps计时器
int[]Samples=新int[NumberSamples];
int CurrentSample=0;
int TicksAggregate=0;
int SecondSinceStart=0;
公共游戏1()
{
graphics=新的GraphicsDeviceManager(此);
Content.RootDirectory=“Content”;
}
受保护的覆盖无效初始化()
{
base.Initialize();
graphics.SynchronizeWithVerticalRetrace=假;
int DesiredFrameRate=60;
targetReleasedTime=新的时间跨度(TimeSpan.TicksPerSecond/DesiredFrameRate);
}
受保护的覆盖void LoadContent()
{
spriteBatch=新spriteBatch(图形设备);
OutputFont=Content.Load(“MessageFont”);
}
受保护的覆盖无效UnloadContent()
{/*无事可做*/}
受保护覆盖无效更新(游戏时间游戏时间)
{
if(GamePad.GetState(PlayerIndex.One).Buttons.Back==ButtonState.Pressed | | Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape))
这是Exit();
更新(游戏时间);
}
私有浮点和(int[]样本)
{
float RetVal=0f;
for(int i=0;i时间跨度滴答声秒)
{
TicksAggregate-=(int)TimeSpan.TicksPerSecond;
SecondSinceStart+=1;
}
if(CurrentSample==NumberSamples)//我们已经过了