我试图让这个Vector3
在它向右加速时加速,在它没有加速时减速。这是我的更新方法。为什么它不加速?它具有恒定的速度。我知道你可以在vel.x
添加-5,如果它在左边,+ 5,如果它在右边,然后在vel.x
为0时停止,但是我&# 39;我试图做这项工作。我真的不明白我做错了什么。
在课堂上我宣布了两个Vector3
s(用于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);
}
答案 0 :(得分:1)
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);
}
每帧都调用一次update方法。所以你上面的代码会发生的事情是你每帧减少20%的速度,这意味着如果你有60FPS,你将速度降低到0.8^60 = 1.eE-6
或者当你进入左半边的屏幕。
你还希望在适当的时候加速......在哪个方向加速?你现在正在做的是,如果位置是屏幕的右半部分,那么它加速到LEFT意味着一旦你到达右半边,它就会移回到左边!将-5
更改为+5
然后它会飞出,因为您的速度提高了5*60=300 px/s^2
。您需要按时间增量缩放加速度。
此外,您还需要按时间增量缩放减速度。除以三角洲(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.
}
如果没有更多代码可以继续,我所能做的只是向您展示在一般情况下进行计算的正确方法。
如果你想使用Euler的方法来解决运动ODE,你可以这样做:
// 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那样准确,并且它也会在振荡时出现一些稳定性问题。
你知道什么时候你看到像它一样发抖的东西,当它被卡在游戏中时会发疯吗?是的,可能欧拉的方法变得不稳定了。