简体   繁体   English

极限环帧率

[英]Limit loop frame rate

As like of pygame i want to limit the frame rate of a loop. 就像pygame一样,我想限制循环的帧速率。 Pygame provide the pygame.time.Clock.tick() way to do it: pygame提供了pygame.time.Clock.tick()方法:

If you pass the optional framerate argument the function will delay to keep the game running slower than the given ticks per second. 如果您传递可选的帧速率参数,该功能将延迟以使游戏的运行速度低于给定的每秒滴答声。 This can be used to help limit the runtime speed of a game. 这可以用来帮助限制游戏的运行速度。 By calling Clock.tick(40) once per frame, the program will never run at more than 40 frames per second. 通过每帧调用Clock.tick(40)一次,该程序将永远不会以每秒40帧以上的速度运行。

But how to do it natively in python ? 但是如何在python中本地执行呢?

To illustrate: 为了显示:

import time

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

produce: 生产:

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

I would like 25 frames per seconds, so 我想每秒25帧,所以

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

You could just use time.sleep(1./25) to wait 1/25 of a second. 您可以只使用time.sleep(1./25)等待1/25秒。

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

Note that will will always wait that time additionally to whatever time the loop body takes anyway. 需要注意的是意志总会等到那个时候到任何时间循环体采取反正。 Alternatively, memorize the last execution time and wait until this time + 1/25 of a second. 或者,记住上一次执行时间,然后等待直到该时间+ 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))

Assuming that by "natively in python" you meant using the Python standard library, the time module does provide sufficient building blocks, but it rather likely not what you want. 假设“本机使用python”是指使用Python标准库,那么time模块确实提供了足够的构造块,但很可能不是您想要的。 At its core, frame rate limiting is simply waiting for the right amount of time to pass: 从根本上讲,帧速率限制只是在等待正确的时间过去:

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

The reason clock doesn't work here is that it measures processor time rather than wall time. clock在这里不起作用的原因是它测量的是处理器时间,而不是墙上的时间。

However, this approach has a couple of flaws: 但是,这种方法有两个缺陷:

  1. It does not synchronize to a suitable update event (such as monitor frames) 它不会同步到合适的更新事件(例如监视器帧)
  2. The inner loop can compensate for undershooting, but not overshooting 内循环可以补偿欠调,但不能补偿过调
  3. There is no facility to react to outside events here 这里没有对外界事件做出反应的设施

All of which are good reasons to use more closely tied or higher level frameworks. 所有这些都是使用更紧密或更高级的框架的充分理由。 For instance, folding the waiting time into select or similar (part of the main loop of things like asyncore or Twisted) allows fast response to events, Kivy can help you do time based animation without ever dealing with frames, and Pygame can sync with the monitor given appropriate flags as well as provide evenly spaced events (while interval timers also do this, they don't work on Windows and require signal handling). 例如,将等待时间放到选择的或类似的内容中( 异步循环或Twisted之类的主循环的一部分)可以快速响应事件,Kivy可以帮助您进行基于时间的动画,而无需处理帧,而Pygame可以与监视给定的适当标志并提供间隔均匀的事件 (虽然间隔计时器也这样做,但它们在Windows上不起作用,并且需要信号处理)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM