重力强度和跳跃高度在某种程度上取决于帧率 - Pygame

Gravity strength and jump height somehow dependant on framerate - Pygame

我目前正处于为学校项目使用 pygame 制作经典 2D 平台游戏的早期阶段,并且我正在试验跳跃机制,当我 运行 进入这个相当 st 运行ge 问题。即使我已经考虑了更新之间的时间增量,当帧之间的时间量增加时,跳跃长度和高度都会变得 更短

Here 我让 Player 对象的 3 个实例在屏幕上跳跃,以 700 pixels/second 的恒定速度向右移动,初始向上速度为 700 pixels/second.他们各自人为增加了最小值 delta_time,分别为 0.001s、0.017s 和 0.1s。

这是在 Player 对象的更新函数中计算新速度和位置向量的方式,该函数每帧调用一次(delta_time 从主更新循环传入):

self.speed.y += 1000.0 * delta_time
self.position += self.speed * delta_time

这就是在主更新循环的每个周期结束时计算 delta_time 的方式(第一帧用零值初始化):

delta_time = time.time() - pre_time
pre_time = time.time()
if delta_time < min_delta_time:
    time.sleep(min_delta_time - delta_time)
    delta_time += time.time() - pre_time
    pre_time = time.time()

min_delta_time表示帧更新之间的最小时间。

经过多次尝试修复此问题后,我很确定缺陷出在更新速度的那条线上,但即使在仔细检查数学之后,我仍然无法弄清楚问题出在哪里。一开始我以为可能是delta_time不精确,但如果是这样水平速度也会受到影响,轨迹还是会排成一排。

那么我可以更改任何内容以使 jump/gravity 更一致吗?

这与其说是编码错误,不如说是模型中的逻辑错误:通过将加速度建模为在更新点瞬时发生而不是在整个时间跨度内连续发生,引入的误差会越来越大更新越稀疏。

为了说明这一点,考虑一个物体以 1m/s^2 的速度从停止处加速。如果我们以 1 秒的间隔按上述方式对其进行建模,则六秒后我们的模型会将对象放置在 21 米处。以 2 秒的间隔重复,我们将其置于 24m,以 3 秒的间隔将其置于 27m。不过实际位置应该是18m。

解决方案是考虑模拟时间跨度内的平均速度,而不是样本点处的瞬时速度。换句话说,不是计算整个跨度的加速度值,而是将结果用作整个跨度的速度,加上跨度加速度的一半,使用 that 速度来计算行进的距离在那个跨度内,然后加上剩下的一半加速度。

所以你的更新逻辑会变成这样:

self.speed.y += 500.0 * delta_time
self.position += self.speed * delta_time
self.speed.y += 500.0 * delta_time