在 python 中检测延迟并将其从 .after() 中删除的问题

Problems with detecting delay and removing it from .after() in python

我正在开发 Tkinter python 游戏 - 长话短说它需要能够 运行 在不同的 FPS 值。但是,我无法保持一致的秒长度。

我试图让它检测滞后并将其从 .after() 函数中移除:

def UpdatesEveryFrame():
    s = time.perf_counter()

    # Code here

    s = int((time.perf_counter()  - s)*1000)
    LabelProductionTime3.after(int(1000 / fps) - s, UpdatesEveryFrame)

然而,这是不成功的。它似乎以毫秒为单位(通常在 15 左右)创建了一个准确的值,但这并没有产生准确的秒延迟。我尝试用 time() 替换 perf_counter() 但这具有相同的效果。

由于游戏的基础,必须有准确的秒延迟。你能帮我吗?谢谢

如果这里的目标是精度,那么也许你应该尝试 time.perf_counter_ns method of the time module, it specifically is made to be more precise than time.perf_counter,并以纳秒为单位给出时间,此外,如果必须将时间转换回秒,则可以使用单位转换来完成。

此外,time.perf_counter方法的documentation也提到了这一点-:

Use perf_counter_ns() to avoid the precision loss caused by the float type.

def UpdatesEveryFrame():
    s = time.perf_counter_ns()/(10 ** 9) # used perf_counter_ns, divided by (10 ** 9) to convert to seconds.

    # Code here

    s = int((time.perf_counter_ns()/(10 ** 9) - s)*1000) # used perf_counter_ns, divided by (10 ** 9) to convert to seconds.
    LabelProductionTime3.after(int(1000 / fps) - s, UpdatesEveryFrame)

编辑: 还有 time.monotonic 方法,专门用于测量两次连续调用之间经过的时间,它 returns 时间以小数秒为单位,类似于 time.perf_counter,因此无需对当前进行任何更改除了函数本身的名称之外的代码。

def UpdatesEveryFrame():
    s = time.monotonic() # Changed method name.

    # Code here

    s = int((time.monotonic()  - s)*1000)
    LabelProductionTime3.after(int(1000 / fps) - s, UpdatesEveryFrame) # Changed method name.

此外,类似于 time.perf_counter_ns 方法可作为 time.perf_counter 的更精确版本,还有 time.monotonic 方法的更精确版本 returns以纳秒为单位的时间和类似于 time.monotonic 的函数,即 time.monotonic_ns.