XNA 4.0 C#限制FPS

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了XNA 4.0 C#限制FPS相关的知识,希望对你有一定的参考价值。

我试图限制我的Monogame XNA项目的'每秒帧数',但我的limitFrames函数是不准确的。

例如,我的项目在没有限制器的情况下以60 fps运行。但是当我使用限制器并将frameRateLimiter变量设置为每秒30帧时,项目的最大fps大约为27。

有人可以为它找到解决方案吗?

Frames Limiter Code

private float frameRateLimiter = 30f;
// ...

protected override void Draw(GameTime gameTime)
{
    float startDrawTime = gameTime.TotalGameTime.Milliseconds;
    limitFrames(startDrawTime, gameTime);
    base.Draw(gameTime);
}

private void limitFrames(float startDrawTime, GameTime gameTime)
{
    float durationTime = startDrawTime - gameTime.TotalGameTime.Milliseconds;
    // FRAME LIMITER
    if (frameRateLimiter != 0)
    {
        if (durationTime < (1000f / frameRateLimiter))
        {
            // *THE INACCERACY IS MIGHT COMING FROM THIS LINE*
            System.Threading.Thread.Sleep((int)((1000f / frameRateLimiter) - durationTime));
        }
     }
}

Frames Per Second Shower

public class FramesPerSecond
{
    // The FPS
    public float FPS;

    // Variables that help for the calculation of the FPS
    private int currentFrame;
    private float currentTime;
    private float prevTime;
    private float timeDiffrence;
    private float FrameTimeAverage;
    private float[] frames_sample;
    const int NUM_SAMPLES = 20;

    public FramesPerSecond()
    {
        this.FPS = 0;
        this.frames_sample = new float[NUM_SAMPLES];
        this.prevTime = 0;
    }

    public void Update(GameTime gameTime)
    {
        this.currentTime = (float)gameTime.TotalGameTime.TotalMilliseconds;
        this.timeDiffrence = currentTime - prevTime;
        this.frames_sample[currentFrame % NUM_SAMPLES] = timeDiffrence;
        int count;
        if (this.currentFrame < NUM_SAMPLES)
        {
            count = currentFrame;
        }
        else
        {
            count = NUM_SAMPLES;
        }
        if (this.currentFrame % NUM_SAMPLES == 0)
        {
            this.FrameTimeAverage = 0;
            for (int i = 0; i < count; i++)
            {
                this.FrameTimeAverage += this.frames_sample[i];
            }
            if (count != 0)
            {
                this.FrameTimeAverage /= count;
            }
            if (this.FrameTimeAverage > 0)
            {
                this.FPS = (1000f / this.FrameTimeAverage);
            }
            else
            {
                this.FPS = 0;
            }
        }
        this.currentFrame++;
        this.prevTime = this.currentTime;
}
答案

您无需重新发明轮子。

MonoGame和XNA已经有内置变量来处理这个问题。

要将帧速率限制为最大30fps,请在IsFixedTimeStep方法中将TargetElapsedTimeInitialize()设置为以下值:

IsFixedTimeStep = true;  //Force the game to update at fixed time intervals
TargetElapsedTime = TimeSpan.FromSeconds(1 / 30.0f);  //Set the time interval to 1/30th of a second

您可以使用以下方法评估游戏的FPS:

//"gameTime" is of type GameTime
float fps = 1f / gameTime.ElapsedGameTime.TotalSeconds;

以上是关于XNA 4.0 C#限制FPS的主要内容,如果未能解决你的问题,请参考以下文章

XNA 4.0 在 Windows 上加载外部 3D 对象

使用 XNA 4.0 从 fbx 模型中提取顶点

FBX 模型在 XNA 4.0 中无法正确显示

csharp C#代码片段 - 使类成为Singleton模式。 (C#4.0+)https://heiswayi.github.io/2016/simple-singleton-pattern-us

将纹理 3d 模型和纹理从搅拌机导出到 xna 4.0

[XNA问题,绘制许多不同批次时