限制循环帧速率

时间:2014-09-09 11:26:54

标签: python

pygame一样,我想限制循环的帧速率。 Pygame提供了 pygame.time.Clock.tick()方式:

  

如果你传递了可选的帧率参数,该函数将延迟使游戏运行速度低于每秒给定的滴答数。这可以用于帮助限制游戏的运行时速度。通过每帧调用一次Clock.tick(40),程序将永远不会超过每秒40帧。

但是如何在python中原生呢?

举例说明:

import time

max_frames = 125 # 25*5
current_frame = 1
while current_frame <= max_frames:
    print('frame', time.clock(), current_frame)
    current_frame += 1

产生

('frame', 0.01, 1)
('frame', 0.01, 2)
('frame', 0.01, 3)
[...]
('frame', 0.01, 124)
('frame', 0.01, 125)

我想每秒25帧,所以

('frame', 0.01, 1)
('frame', 0.05, 2)
('frame', 0.08, 3)
[...]
('frame', 4.98, 124)
('frame', 5.00, 125)

2 个答案:

答案 0 :(得分:1)

您可以使用time.sleep(1./25)等待 1/25 秒。

while current_frame <= max_frames:
    # ... do stuff 
    time.sleep(1./25)

请注意,无论如何,将始终等待另外到循环体所需的任何时间。或者,记住上次执行时间并等到这个时间+ 1/25 秒。

while current_frame <= max_frames:
    start = time.time()
    # ... do stuff that might take significant time
    time.sleep(max(1./25 - (time.time() - start), 0))

答案 1 :(得分:0)

假设“本机在python中”意味着使用Python标准库,time模块确实提供了足够的构建块,但它很可能不是你想要的。从本质上讲,帧速率限制只是等待合适的时间通过:

from time import time, sleep

fps=5
frameperiod=1.0/fps
now=time()
nextframe=now+frameperiod
for frame in range(120):
  print frame, now
  while now<nextframe:
    sleep(nextframe-now)
    now=time()
  nextframe+=frameperiod

clock在这里不起作用的原因是它测量的是处理器时间而不是墙上时间。

但是,这种方法存在一些缺陷:

  1. 它不会与适当的更新事件(例如监视器框架)同步
  2. 内环可以补偿下冲,但不能过冲
  3. 此处无法对外部事件做出反应
  4. 所有这些都是使用更紧密联系或更高级别框架的充分理由。例如,将等待时间折叠成select或类似(asyncore或Twisted之类的主循环的一部分)可以快速响应事件,Kivy可以帮助您做time based animation处理帧,Pygame可以sync with the monitor给出适当的标志,并提供evenly spaced events(而interval timers也可以这样做,它们不适用于Windows并需要信号处理)。