转载:https://www.cnpython.com/qa/1466090
- 提问
我目前正处于使用pygame为学校项目制作经典2D平台的早期阶段,当时我正在试验跳跃机制,这时我遇到了这个相当奇怪的问题。即使我考虑了更新之间的时间差,当帧间时间增加时,跳转长度和高度都会缩短
Here我让播放器对象的3个实例在屏幕上跳跃,以700像素/秒的恒定速度向右移动,初始向上速度为700像素/秒。它们各自的人工增加的最小delta_时间分别为0.001s、0.017s和0.1s
这是在播放器对象的更新函数中计算新速度和位置向量的方式,该函数每帧调用一次(增量时间从主更新循环传入):
1
2self.speed.y += 1000.0 * delta_time
self.position += self.speed * delta_time这就是在主更新循环的每个周期结束时计算delta_时间的方式(第一帧的值为零):
1
2
3
4
5
6delta_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()最小增量时间表示帧更新之间的最小时间
在多次尝试修复此问题后,我非常确定该缺陷存在于更新速度的线路中,但即使在仔细检查数学后,我仍然无法找出问题所在。起初我认为可能是三角洲时间不精确,但如果是这样的话,水平速度也会受到影响,轨迹仍会排列整齐
那么我能改变什么使跳跃/重力更一致吗
- 回答
这与其说是编码中的错误,还不如说是模型中的逻辑错误:通过将加速建模为在更新点瞬时发生,而不是在整个时间跨度内连续发生,引入了不准确,这将使更新越稀疏,误差就越大
为了说明这一点,考虑一个对象从停止时加速到1M/s^ 2。如果我们像上面那样以1秒的间隔建模,六秒钟后,我们的模型会将对象放置在21m处。以2秒的间隔重复,我们将其设置为24米,3秒的间隔将其设置为27米。但是,实际位置应为18米
解决方案是考虑在模拟时间跨度上的平均速度,而不是采样点处的瞬时速度。换句话说,不是计算整个跨度的加速度值,而是使用结果作为整个跨度的速度,加上跨度加速度的一半,使用该速度计算在该跨度内行驶的距离,然后加上剩余的一半加速度
因此,您的更新逻辑将类似于:1
2
3self.speed.y += 500.0 * delta_time
self.position += self.speed * delta_time
self.speed.y += 500.0 * delta_time
- JS的简单实现
1
2
3
4
5
6
7
8
9
10
11let gameObject = { y = 0 };
let jumpPower = 600;
let _G = 2000;
function update(dt) {
if (jumpPower > 0 || gameObject.y > 0) {
gameObject.y -= (jumpPower / 2) * dt;
jumpPower -= _G * dt;
gameObject.y -= (jumpPower / 2) * dt;
}
}