Как правильно вычислить кадр/с в XNA?

Я записал компонент для отображения текущего кадр/с.
Самая важная часть его:

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

Основная идея этого кода состоит в том, чтобы выполнить новаторский алгоритм в другом потоке все время.

Странными вещами я подразумеваю, что иногда кадр/с решительно уменьшается, это - очевидные, но отображенные изменения кадр/с чаще, чем однажды секунда. Если я понимаю, что этот кадр/с кода не может изменяться чаще, чем однажды секунда.

Кто-то может объяснить меня, что продолжается?

Редактирование 26.03.2010
Я отправил также код метода Ничьей.

Отредактируйте 31.03.2010 Ответа на вопросы о Venesectrix
1) Вы работаете с фиксированным или переменным временным интервалом?
IsFixedTimeStep и SynchronizeWithVerticalRetrace имеют значение true.
2) Вы перемещали окно XNA вокруг, когда это произошло?
Нет
3) Окно XNA фокусировалось?
Да
4) Насколько примечательный было это (т.е., обновление настолько быстро Вас не может считать его, или едва-едва обновляющий больше, чем секунда)?
Я смог считать обновления, кадр/с обновлял ~3 раза в секунду.
5) И все это только происходит с кодом потока там?
Да

13
задан Tomek Tarczynski 31 March 2010 в 16:12
поделиться

3 ответа

Кстати ... вам следует избегать установки приоритета потока. Назначив наивысший приоритет потока тому, что должно быть фоновым потоком, вы можете в конечном итоге лишить основной поток времени процессора, потому что планировщик будет отдавать приоритет threadPath

1
ответ дан 2 December 2019 в 00:17
поделиться

У Шона Харгривза есть отличный пост об этом здесь . Первое различие, которое я вижу между его кодом и вашим, заключается в том, что вы каждый раз сбрасываете elapseTime на 0, что приведет к потере некоторого времени, тогда как Шон просто вычитает 1 секунду из своего elapsedTime. Кроме того, Шон использует ElapsedGameTime вместо ElapsedRealTime. Он также обновляет свой frameCounter в функции Draw, а не в функции Update.

Что касается того, почему он использует ElapsedRealTime, он объясняет это в комментарии после сообщения:

> Конечно, 1 / gameTime.ElapsedRealTime.TotalSeconds

>, следовательно, даст текущую частоту кадров.

Это покажет вам, сколько времени прошло с момента предыдущего вызова Update, но это не то же самое, что ваша частота кадров!

а) Если игра пропускает кадры, Обновление будет вызываться чаще , чтобы наверстать упущенное. Вы хотите рассчитать время количества фактических розыгрышей, которые имеют место, а не только эти дополнительные логические кадры догоняющего типа.

б) Время для одного обновления может сильно колебаться, поэтому цифра, которую вы получите, будет слишком нестабильной , чтобы ее можно было легко прочитать.

Я бы попробовал его компонент и посмотрел, работает ли он у вас. Сообщение довольно старое, и я думаю, вам придется изменить LoadGraphicsContent на LoadContent и UnloadGraphicsContent на UnloadContent, как указывает еще один из комментариев.

12
ответ дан 2 December 2019 в 00:17
поделиться

Вы активно проверяете, изменяется ли IsRunningSlowly? Даже если для IsFixedTimeStep установлено значение true, если ваша программа не может выполнять столько обновлений, сколько ожидает, она будет вызывать ее чаще.

Раньше я смягчал это путем прямого вызова ResetElapsedTime () вместо того, чтобы отслеживать это самостоятельно.

Не уверен, что это сработает для вас. Я заметил, что, когда я отлаживал предыдущую проблему, она не вызывала дополнительных обновлений, вероятно, это «функция» при отладке.

0
ответ дан 2 December 2019 в 00:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: