Pyglet window 不会以 60FPS 的速度绘制,除非在不到 1/60 秒的时间内调用更新函数的速率

Pyglet window don't draw at 60FPS unless the rate of an update function is called in less than 1/60 of a second

所以,开始在空闲时间写一个小游戏,并决定使用一个我以前从未使用过的库:pyglet。我曾经使用 pygame 甚至 arcade(使用 pyglet 实现),但我认为我应该尝试使用 pyglet 一次,特别是因为 arcade 在 python 3.10 中尚不可用。 所以,实际的问题是,当创建 window 并尝试在其上绘制一些东西时,我注意到图像在闪烁,所以我决定检查我得到了多少 FPS。 下面的代码只是一个测试,我正在 运行 试图弄清楚可能发生了什么。

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

所以,通过这个简单的代码,通过 window 中的 FPSDisplay,我得到了大约 30 FPS,但是从更新方法中的打印功能,检查 pyglet 时钟,我得到了数百(或数千时在屏幕上移动我的鼠标,实际上我也觉得这很奇怪)FPS。 我尝试在 window 创建时和通过 set_vsync 函数启用和禁用垂直同步,但没有任何改变。唯一让 FPSDisplay(这是速度的东西实际上被吸引到 window)上升的是将更新函数速率设置为低于 1/60 的值(即使 1/70 已经足够了大约 60 FPS)。

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

所以,我在徘徊,这是 pyglet 实际工作的方式还是 vsync 的问题?

通常您不希望游戏 运行 以最大 FPS 进行,否则您会使卡超载并无缘无故地浪费 CPU 周期。

基本上,事件循环会尝试为您优化这一点。要回答为什么这个问题,Pyglet 只会在发生某种事件时更新 FPS。 (这在 Pyglet 2.0 中有所改变,因为它不是很直观)您可以通过四处移动鼠标光标并查看 FPS 上升来查看这一点。 Windows 将事件推送到 window,导致应用程序工作更多。通过安排更新,您迫使循环工作得更多,这就是它增加的原因。

如果你想在垂直同步时强制使用最大 FPS,你可以这样做:

def update(dt):
    pass

pyglet.clock.schedule(update)

通常,一旦您开始添加要求更高的功能和特性,这应该不是问题。