我试图让这个 Vector3
在它向右时加速,在不向右时减速。这是我的更新方法。为什么不加速?它具有恒定的速度。我知道你可以将-5添加到vel.x
(如果它在左边)和+5(如果它在右边),然后在vel.x
为0时停止它,但是我正在努力让这项工作成功。我真的不明白我做错了什么。
在类中,我声明了两个 Vector3
(在 update
中使用)
public void update(float delta) {
timePassed += Gdx.graphics.getDeltaTime(); //irrelevant
if (pos.x > Kiwi.WIDTH / 2)
vel.add(-5, 0, 0);
vel.x *= 0.8f;
vel.scl(delta);
pos.add(vel.x, 0, 0);
vel.scl(1 / delta);
}
最佳答案
新答案
public void update(float delta) {
if (pos.x > Kiwi.WIDTH / 2)
vel.add(-5, 0, 0);
vel.x *= 0.8f;
vel.scl(delta);
pos.add(vel.x, 0, 0);
vel.scl(1 / delta);
}
每一帧都会调用一次更新方法。因此,上面的代码会发生的情况是,每帧将速度降低 20%,这意味着如果您有 60FPS,您会将速度降低到 0.8^60 = 1.eE-6
或几乎为零当您位于屏幕左半部分时,一秒钟内。
你也想在向右的时候加速...向哪个方向加速?您现在要做的是,如果位置位于屏幕的右半部分,那么它会加速到左侧,这意味着一旦您到达屏幕的右半部分,它就会移回左侧!将 -5
更改为 +5
,然后它就会飞走,因为您将速度提高了 5*60=300 px/s^2
。您需要按时间增量缩放加速度。
此外,您还需要按时间增量来缩放减速度。除以 delta (1/delta
) 也没有任何意义,所以试试这个:
public void update(float delta) {
if (pos.x > Kiwi.WIDTH / 2)
vel.add(5*delta, 0, 0); // Acceleration is now 5 px/s^2 to the right
vel.x -= vel.x*0.2f*delta; // Decay speed by 20% every second
pos.add(vel.x*delta, 0, 0); // Move position by speed.
}
下面是旧答案
没有更多代码可以继续,我所能做的就是向您展示在一般情况下进行计算的正确方法。
如果您想使用欧拉方法求解运动常微分方程,您可以这样做:
// Object state
speed = ...; // Unit is [m/s]
position = ...; // Unit is [m]
// Inputs
frameDelta = ...; // Unit is [s]
acceleration = ...; // Unit is [m/s^2]
// Update step
speed += acceleration * frameDelta; // Unit [m/s^2 * s] = [m/s];
position += speed * frameDelta; // Unit [m/s * s] = [m]
如果您希望速度“衰减”,您可以通过添加合适的减加速度(或阻力/风阻力/摩擦力,无论您如何调用它)来实现:
decayRate = ...; // Unit is [m/(m*s^2) = 1/s^2] ((de)acceleration per meter)
acceleration -= speed * decayRate * frameDelta; // Unit is [m/s*1/s^2*s = m/s]
注意:您不存储加速度,而是根据其他输入(键盘、鼠标、力、碰撞等)计算每帧的加速度。
注2:欧拉方法是可用于根据加速度计算位置和速度的最简单的求解器。它存在一些问题,它不像 Runge-Kutta 那样准确,而且还可能表现出一些振荡稳定性问题。
你知道当你看到某个东西卡在游戏中时会像疯了一样摇晃吗?是的,这可能是欧拉方法变得不稳定。
关于java - 使用 Vector3 的加速逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40042639/