您可以使用以下公式在任何给定时刻获取当前帧速率:
framerate = (1 / gameTime.ElapsedGameTime.TotalSeconds);
下面介绍的其他两种方法都为您提供了修改后的帧速率,旨在更平滑,并且返回值的波动更少
这个方法是通过在对数尺度上加权所有以前的帧时间来工作的。我不喜欢使用平均值来获得游戏性能指标的想法,因为丢帧没有很好地表示(或者如果你有一个很高的平均值)并且非常低/非常高的帧率具有非常不同的准确度水平如果它们的平均运行速度相同。
为了解决这个问题,我创建了一个 SmartFramerate 类(我知道这个名字很糟糕)
class SmartFramerate
{
double currentFrametimes;
double weight;
int numerator;
public double framerate
{
get
{
return (numerator / currentFrametimes);
}
}
public SmartFramerate(int oldFrameWeight)
{
numerator = oldFrameWeight;
weight = (double)oldFrameWeight / ((double)oldFrameWeight - 1d);
}
public void Update(double timeSinceLastFrame)
{
currentFrametimes = currentFrametimes / weight;
currentFrametimes += timeSinceLastFrame;
}
}
您在创建变量时设置权重:
(权重越高对瞬时帧率越准确,权重越低越平滑。我发现3-5是一个很好的平衡)
SmartFramerate smartFPS = new SmartFramerate(5);
在每帧运行的任何地方调用 Update 方法:
smartFPS.Update(gameTime.ElapsedGameTime.TotalSeconds);
当前帧率可以这样访问:
smartFPS.framerate
或像这样打印:
debuginfo.Update("\n\nᴥ" + smartFPS.framerate.ToString("0000"), true);
(我将其放入自定义打印类中,因此如果语法看起来很时髦,我深表歉意)
但是,如果您想简单地平均一定数量的帧,那么这个类是我想出的最有效的方法。
class SmoothFramerate
{
int samples;
int currentFrame;
double[] frametimes;
double currentFrametimes;
public double framerate
{
get
{
return (samples / currentFrametimes);
}
}
public SmoothFramerate(int Samples)
{
samples = Samples;
currentFrame = 0;
frametimes = new double[samples];
}
public void Update(double timeSinceLastFrame)
{
currentFrame++;
if (currentFrame >= frametimes.Length) { currentFrame = 0; }
currentFrametimes -= frametimes[currentFrame];
frametimes[currentFrame] = timeSinceLastFrame;
currentFrametimes += frametimes[currentFrame];
}
}
要使用它,只需在您希望使用它的地方初始化一个 SmoothFramerate 变量,传递您想要平均的帧数:
SmoothFramerate smoothFPS = new SmoothFramerate(1000);
更新、访问和打印当前帧速率,与使用上面的 SmartFramerate 类完全一样。
感谢阅读,希望对大家有所帮助。