XNA 4.0 C # предел FPS - PullRequest
       13

XNA 4.0 C # предел FPS

0 голосов
/ 07 января 2019

Я пытаюсь ограничить количество кадров в секунду в проекте Monogame XNA, но моя функция limitFrames является неточной.

Например, мой проект работает на скорости 60 кадров в секунду без ограничителя. Но когда я использую ограничитель и настраиваю переменную frameRateLimiter на 30 кадров в секунду, максимальная частота кадров проекта составляет около 27.

Может кто-нибудь придумать решение для этого?

Код ограничителя фреймов

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));
        }
     }
}

кадров в секунду, душ

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;
}

1 Ответ

0 голосов
/ 07 января 2019

Вам не нужно заново изобретать колесо.

MonoGame и XNA уже имеют встроенные переменные, которые обрабатывают это для вас.

Чтобы ограничить частоту кадров до 30 кадров в секунду, установите IsFixedTimeStep и TargetElapsedTime в следующем методе Initialize():

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;
...