我正在搞乱Pygame,制作一些简单的游戏只是为了学习它。但是,我很难按照我想要的方式实现fps。
根据我的理解,fps通常设置为:
import pygame
...
clock = pygame.time.Clock()
while True:
clock.tick(60)
然后在整个程序中,我确保每个循环/帧被写入需要1/60秒,所以我可以,例如,让对象以我想要的速度移动。将刻度线增加到120 fps将使游戏运行得太快,而减少它会使游戏运行得太慢。
然而,这并不是我熟悉fps为任何其他游戏工作的方式。在大多数游戏中,fps可以根据需要变化(通常基于系统运行应用程序的程度),但游戏总是以相同的速度运行(例如,在屏幕上移动100个像素将花费1秒钟,无论如何在那一秒发生了多少帧。)
我能想到让它以我想要的方式工作的唯一方法是每帧抓取当前的fps,并将其计入每个基于运动或时间的事件的计算中。但这似乎是不必要的复杂,我想知道我是否完全错过了pygame功能的一部分,这些功能可以解决这个问题。
答案 0 :(得分:6)
游戏使用固定时间步进物理,同时允许视频时间步长(fps)变化。这意味着使用常量delta值调用update(delta)
函数。这保持了稳定性。
这意味着在实践中,update
每次调用draw()
时可能会多次调用{{1}},具体取决于经过多长时间。
有关详细信息,请参阅:Gaffer's "fix your timestep"
较大的(python)示例位于cookbook: ConstantGametime
答案 1 :(得分:2)
虽然@ monkey的答案是完整的数据转换,但您应该再次查看time.Clock
上的pygame文档。 Clock.tick()
的可选帧率参数设置了FPS的上限,而不是固定的FPS;换句话说,如果您的游戏循环花费的时间超过完成的时间,那么如果您假设传递该值确保固定的游戏速度,游戏将会滞后。看起来Clock.get_time()
和Clock.get_raw_time()
是用来获取上一个游戏循环的执行时间的东西,然后你可以从中计算游戏元素的行为。
答案 2 :(得分:2)
您可以定义对象的速度(以像素/秒为单位),然后使用tick
中返回的值来了解每个对象应移动多少。
实施例
import pygame
...
player_speed = (20, 0) # (x,y) pixels/second
...
pygame.time.Clock() = clock
elapsed = 0.
while True:
seconds = elapsed/1000.0
update_player(seconds)
...
elapsed = clock.tick(60)
def update_player(seconds):
player.position = (player.position[0] + int(player_speed[0]*seconds),
player.position[1] + int(player_speed[1]*seconds))
答案 3 :(得分:0)
如果你想在每个FPS以固定的速度移动物体,你可以指示速度不是绝对值,而是指示相对于要在一秒钟内完成的移动的值,然后将其除以帧数每秒。
例如,如果您希望对象以每帧2像素的速度移动,假设为30 FPS,并且您希望此速度在每个FPS处都相同,则可以将其指示为像素移动在游戏循环中,当您需要更新速度时,您将使用此速度除以FPS,从而产生每帧更新中使用的相对速度。通过这种方式,在30 FPS时,每帧可获得2像素的移动,而在60 FPS时,您将获得1像素移动,但在1秒后,您将获得相同数量的像素移动,即60。