Окно Pyglet не рисуется со скоростью 60 кадров в секунду, если только скорость вызова функции обновления не составляет менее 1/60 секунды

#python-3.x #pyglet

Вопрос:

Итак, в свободное время я начал писать небольшую игру и решил воспользоваться библиотекой, которой никогда раньше не пользовался: pyglet. Я привык работать с pygame и даже аркадой (которая реализована с помощью pyglet), но подумал, что мне стоит попробовать использовать pyglet хоть раз, особенно потому, что аркада еще не доступна в python 3.10. Итак, фактическая проблема в том, что при создании окна и попытке что-то нарисовать на нем я заметил, что изображение мерцает, поэтому я решил проверить, сколько кадров в секунду я получаю. Следующий код-это просто тест, который я запускал, чтобы попытаться выяснить, что могло произойти.

 import pyglet  window = pyglet.window.Window(800, 600, vsync=False) fps_display = pyglet.window.FPSDisplay(window)  # Redundant just to be sure vsync was indeed disabled window.set_vsync(False)   @window.event def on_draw():  window.clear()  fps_display.draw()  def update(dt):  print(f"FPS: {pyglet.clock.get_fps()}")  if __name__ == "__main__":  pyglet.clock.schedule_interval(update, 1.0/60.0)  pyglet.app.run()  

Итак, с помощью этого простого кода через FPSDisplay в окне я получаю около 30 кадров в секунду, но из функции печати в методе обновления, которая проверяет часы pyglet, я получаю сотни (или тысячи при перемещении мыши по экрану, что я тоже нахожу странным) кадров в секунду. Я попытался включить и отключить vsync при создании окна и с помощью функции set_vsync, но ничего не изменилось. Единственное, что заставило FPSDisplay (а это была скорость, которую на самом деле рисовали в окне) увеличиться, — это установить частоту обновления функции ниже 1/60 (даже 1/70 уже было достаточно, чтобы получить около 60 кадров в секунду).

 pyglet.clock.schedule_interval(update, 1.0/70.0)  

Итак, я блуждал, так ли на самом деле работает pyglet или, может быть, проблема с vsync?

Комментарии:

1. 1 — Это происходит даже тогда, когда на экране обновляется информация, например, движущийся спрайт, который заставляет изображение двигаться со скоростью 30 кадров в секунду, а не с желаемыми 60 кадрами в секунду. Приведенный пример был просто тестом, который я проводил. Если pyglet на самом деле работает именно так, как я должен заставить его рисовать материал по крайней мере со скоростью 60 кадров в секунду?

2. 2 — Я, возможно, не был ясен в своем вопросе, за который я извиняюсь, поэтому: почему окно на самом деле будет отображаться с частотой 60 кадров в секунду, просто установив частоту обновления функции обновления на 1/70 вместо 1/60?

3. Я использую экземпляр спрайта pyglet для тестирования. Попытался напрямую добавить значение x в функцию обновления, а затем попытался вызвать базовую функцию обновления, передав увеличивающееся значение x. Они оба приводят к одинаковым 30 кадрам в секунду. Как я заметил ошибку, я не пытался использовать key_press или что-либо еще.

4. Подумал, что это тоже было что-то из этих строк, и экспериментировал с этим. С 61,0 до 64,0 он колеблется в пределах 40-50; с 65,0 до 67,0 он остается на уровне ниже 50-х годов; с 68 до 60-х годов он достигает и остается довольно стабильным. Без перемещения мыши или нажатия чего-либо, даже с 120,0, это дает мне те же 60 кадров в секунду, но при перемещении мыши она увеличивается примерно до 120 кадров в секунду. Я действительно не понимаю, почему это происходит

Ответ №1:

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

В основном цикл событий пытается оптимизировать это для вас. Чтобы ответить на вопрос, почему, Pyglet обновит FPS только в том случае, если произойдет какое-либо событие. (Это изменяется в Pyglet 2.0, так как это не совсем интуитивно понятно) Вы можете увидеть это, перемещая курсор мыши вокруг и наблюдая, как увеличивается частота кадров в секунду. Windows помещает события в окно, заставляя приложение работать больше. Планируя обновление, вы заставляете цикл работать больше, поэтому он увеличивается.

Если вы хотите увеличить максимальную частоту кадров в секунду даже с помощью vsync, вы можете просто сделать:

 def update(dt):  pass  pyglet.clock.schedule(update)  

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

Комментарии:

1. Хорошо, теперь это определенно имеет больше смысла. Спасибо за ответ