[英]XNA/MonoGame: Getting the Frames Per Second
我試圖獲得我游戲的當前FPS,但是我只能找到每秒更新FPS變量的方法。 例如https://github.com/CartBlanche/MonoGame-Samples/blob/master/Draw2D/FPSCounterComponent.cs和http://www.david-amador.com/2009/11/how-to-do-a-xna -fps計數器/
有沒有辦法持續更新FPS標簽?
這是我剛才寫的FPS計數器課程。 您應該能夠將其放入代碼中並按原樣使用它。
public class FrameCounter
{
public FrameCounter()
{
}
public long TotalFrames { get; private set; }
public float TotalSeconds { get; private set; }
public float AverageFramesPerSecond { get; private set; }
public float CurrentFramesPerSecond { get; private set; }
public const int MAXIMUM_SAMPLES = 100;
private Queue<float> _sampleBuffer = new Queue<float>();
public override bool Update(float deltaTime)
{
CurrentFramesPerSecond = 1.0f / deltaTime;
_sampleBuffer.Enqueue(CurrentFramesPerSecond);
if (_sampleBuffer.Count > MAXIMUM_SAMPLES)
{
_sampleBuffer.Dequeue();
AverageFramesPerSecond = _sampleBuffer.Average(i => i);
}
else
{
AverageFramesPerSecond = CurrentFramesPerSecond;
}
TotalFrames++;
TotalSeconds += deltaTime;
return true;
}
}
您需要做的就是在主Game類中創建一個成員變量。
private FrameCounter _frameCounter = new FrameCounter();
並在Game的Draw方法中調用Update方法並繪制標簽,但是你喜歡..
protected override void Draw(GameTime gameTime)
{
var deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
_frameCounter.Update(deltaTime);
var fps = string.Format("FPS: {0}", _frameCounter.AverageFramesPerSecond);
_spriteBatch.DrawString(_spriteFont, fps, new Vector2(1, 1), Color.Black);
// other draw code here
}
請享用! :)
您可以使用以下公式在任何給定時刻獲取當前幀速率:
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類一樣更新,訪問和打印當前幀速率。
感謝閱讀,我希望這可以幫助別人。
使用double來測量fps:
double frameRate = 0.0;
修改方法Update
如下:
public override void Update(GameTime gameTime)
{
if(gameTime.ElapsedGameTime.TotalSeconds > 0.0)
{
frameRate = (double)frameCounter / gameTime.ElapsedGameTime.TotalSeconds;
}
frameCounter = 0;
}
我沒有測試代碼,但你應該明白這個想法。
您可能嘗試在每次繪制操作中更新FPS。 這將是非常不穩定的價值,因為有時您需要更多,有時更少。 為了使價值更穩定 - 從許多價值中取平均值。
計算FPS的最簡單方法可能是計算圖紙。 而且具有定時器功能的每秒可以說這個值,計算新的fps和清除計數器。 使此計時器更長(例如2秒),或者只是取最后10個fps值並顯示平均值。
在一些游戲中,我看到他們也計算了重繪場景所需的最長時間。 這也可能是一個有趣的價值。 為此,您可以測量繪制函數需要多長時間:在開始時記錄時間,在結束時,差異將是時間。
請注意,如果啟用同步,則延遲繪制操作直到下次同步,這可能是奇怪結果的原因?
更新每個Draw()的簡單方法是:
frameRate = 1 / gameTime.ElapsedGameTime.TotalSeconds;
您也可以在Update()方法中刪除它,以查看觸發的頻率,如果您願意的話。
如果你想減慢更新的速度......
frameRate += (((1 / gameTime.ElapsedGameTime.TotalSeconds) - frameRate) * 0.1);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.