3

据我了解,有一种非常标准的方式来实现重力,这几乎是真正的交易;在每个时间步长上添加一个数字(例如 9.8)到对象的向下垂直速度。

然而,这个简单的数学在我的程序(显然还有其他程序)中导致了“无限反弹”的问题。到目前为止,简单的测试用例有一个球直接落下,并击中“地板”。碰撞时,球的矢量偏转并减少 1/4(占位符恢复系数)。在每个时间步长上,重力值(在我的情况下约为 2)被添加到向量中。结果,球弹了起来,然后弹得越来越低……然后它并没有真正停止,甚至没有明显地停止(真正的目标),而是在屏幕底部上下抖动。调试读数表明,它的速度永远不会低于 2 帧超过几帧,因为该常数只是不断地被添加和取消,然后无限期地再次添加。

现在,理解为什么不是困难的部分。这正是我从一开始就担心的问题,我只是认为我忽略了一些数学魔法,因为在解释数学时没有人真正提到过这样的问题。但是 - 由于没有人讨论过它 - 这确实让我想知道,修复它的“典型”方法是什么?

编辑:经过大量工作,我已经确定单独使用单独的加速度值不会解决问题 - 它仍然会始终尝试添加一些恒定的重力分数。恒定时间步长意味着恒定加速度;恒定的加速度意味着恒定的速度增加。反弹时的恢复系数会导致速度减小到一点,并抵消加速度,但加速度将从 0 开始。像这样:

  1. 加速度从 0 开始,速度从 y 开始。
  2. 加速度增加 (grav * timestep)。
  3. 速度随加速度增加。
  4. 重复 2-3 直到与地板相撞。
  5. 加速度现在回到 0。
  6. 相应地反映速度矢量,然后乘以 CoR。
  7. 随着速度从负数变为 0,再次变为正数,重复 2-3。
  8. 重申 2-7,每次反弹都比上一次保留更少的动力。
  9. 反弹现在非常小。
  10. 速度现在小于 (grav * timestep)。
  11. 与地板的碰撞将加速度设置回 0。
  12. 加速度再次增加 (grav * timestep)。
  13. 速度因加速度而增加——现在足以同时从负向正向摆动。
  14. 无限重复 11-13。

现在,总体问题不是速度永远不会等于 0。这是意料之中的。但同样令人期待的是一个无限递减的数字。将恢复系数设置为 0.5,产生的弹跳速度应该是上一个的一半,逐渐减小,直到它可以被丢弃为“停止”。通过引入纯常数加法——无论是直接加到速度上,还是将它加到另一个加到速度上的值上——就会出现这个问题。具体来说,我需要知道如何解决这个问题。

4

2 回答 2

1

刚刚处理了同样的问题。

这是为我修复它的代码:

if (cat.y + cat.height >= ground.y)    // if the cat has hit the ground
{
    cat.y = ground.y - cat.height;    // reset to the bottom
    cat.vector.y = Math.round(COR * -cat.vector.y);    // might want to round down
}

这里的重要部分是四舍五入。

于 2013-10-26T02:06:52.147 回答
0

要解决这个问题,你唯一需要做的就是当球撞到地面时反转垂直速度并将球放在障碍物上,这样球就会锁定在地面上,因为 9.8 / 4 向上的速度是不够的将其“解锁”并将其设置为另一个反弹。

于 2013-04-01T18:05:21.410 回答