7

我在玩 Pygame,制作一些简单的游戏只是为了学习它。但是,我很难以我想要的方式实现 fps。

据我了解,fps 通常设置为:

import pygame
...
clock = pygame.time.Clock()
while True:
    clock.tick(60)

然后在整个程序中,我确保每个循环/帧的写入时间为 1/60 秒,这样我就可以让对象也以我想要的速度移动。将滴答声增加到 120 fps 会使游戏运行过快,而降低它会使游戏运行过慢。

但是,这不是我熟悉的 fps 为任何其他游戏工作的方式。在大多数游戏中,fps 可以随心所欲地变化(通常取决于系统运行应用程序的好坏),但游戏将始终以相同的速度运行(例如,在屏幕上移动 100 个像素将需要 1 秒那一秒发生了多少帧)。

我能想到让它以我想要的方式工作的唯一方法是每帧获取当前的 fps,并将其纳入每个运动或基于时间的事件的计算中。但这似乎不必要地复杂,我想知道我是否完全错过了为我解决这个问题的 pygame 功能的一部分。

4

4 回答 4

7

游戏使用固定的物理时间步长,同时允许视频时间步长 (fps) 变化。这意味着您的update(delta)函数会以恒定的 delta 值调用。这保持了稳定性。

这意味着在实践中,update平均每次调用 可能最终会被调用多次draw(),具体取决于经过的时间。

有关详细信息,请参阅:Gaffer 的“修复您的时间步长”

一个更大的(python)示例在食谱中:ConstantGametime

于 2012-11-27T20:04:27.113 回答
3

您可以以像素/秒为单位定义对象的速度,然后使用返回的值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))
于 2012-11-27T23:21:57.660 回答
2

虽然@monkey 的答案是完整的数据转储,但您可能应该time.Clock再次查看 pygame 文档。可选的帧率参数Clock.tick()设置 FPS 的上限,而不是固定的 FPS;换句话说,如果你的游戏循环花费的时间超过了完成的时间,如果你假设传递该值确保了固定的游戏速度,那么游戏将会滞后。它看起来像Clock.get_time()并且Clock.get_raw_time()是用来获取最后一个游戏循环的执行时间的东西,然后您可以从中计算游戏元素的行为。

于 2012-11-27T20:15:46.560 回答
1

如果您想在每个 FPS 上以固定速度移动对象,您可以不使用绝对值来指示速度,而是使用与一秒钟内要完成的移动相关的值来指示速度,然后将其除以每秒的帧数。

例如,如果您希望您的对象以每帧 2 个像素的速度移动,例如 30 FPS,并且您希望此速度在每个 FPS 上都相同,您可以将其表示为一秒内的像素移动,应该是60。在游戏循环中,当你需要更新速度时,你会使用这个速度除以FPS,从而得出每帧更新使用的相对速度。这样,在 30 FPS 时,您将获得每帧 2 个像素的移动,而在 60 FPS 时,您将获得 1 个像素的移动,但在 1 秒后,您将获得相同的像素移动量,即 60。

于 2014-11-06T15:37:25.480 回答