【问题标题】:Gravity trajectory with already known destination已知目的地的重力轨迹
【发布时间】:2014-06-04 12:16:55
【问题描述】:

我已经花了几天时间试图解决这个问题,我快要发疯了。非常感谢您的帮助。

我在 libgdx 中使用 2D 舞台。我想用“重力”显示效果将演员(或精灵)移动到这个舞台:例如演员1,他的初始坐标是(0, 0),目标坐标是(100, 50),我想移动这个演员到这个目的地具有重力轨迹效果。然后我想使用相同的重力让 actor2 从 (0, 0) 移动到 (25, 75),然后让 actor3 从 (0, 0) 移动到 (200, 75) 等等。

我设法根据这个众所周知的循环将重力轨迹应用于任何演员:

setX(getX() + velocity.x);
setY(getY() + velocity.y);
velocity.y += getGravity().y * delta;

因此,调整重力值会修改轨迹。它工作正常。 现在,正如我之前所说,我想给每个演员一个独特的轨迹,给他们预定的目的地。

所以我试图找到一个公式来确定每个演员在他们轨迹的每一帧上的 x 和 y 我正在使用以下静态参数:

gravity.y : 所有演员都一样 延迟:每个演员在他的初始坐标和他的目标坐标之间移动的帧数。所有演员的价值也相同

首先我用这个我绝对不引以为豪的 SUPER UGLY 公式计算速度:

velocity = new Vector2 ( (destinationx - b.getX() )/time,  initdisty/time + ( Math.sqrt(delta*1000)*time / ( 500/Math.abs(gravity) ) ));

其中 delta = Gdx.graphics.getDeltaTime();

然后我在每一帧应用这个速度来计算每个演员的 x 和 y:

public void act(float delta){
for (int i=0; i<delay; i++) {
setX(getX() + velocity.x);
setY(getY() + velocity.y);
velocity.y += gravity.y * delta;
}
}

它有点工作,但当然,这不可能是一个长期的解决方案。为每个演员计算每帧的 x 和 y(可能有 5-6 个演员同时移动)看起来一点也不好看。 主要问题是轨迹在计算机上运行良好,60FPS 一致,在平板电脑上还可以,但在内存有限且 30

在阅读了几篇博文后,我似乎可以通过从公式中删除 delta 参数来避免多设备内存 fps 问题,但我还没有找到方法。而且它仍然没有给我一个强有力的长期解决方案来计算具有预定目的地坐标的轨迹。

感谢您的阅读和您的宝贵时间,如果不清楚,请告诉我,我会尽力解释得更好。

【问题讨论】:

  • 只是为了确保:您有一个具有已知起始位置的特定对象,并且您想计算给它的初始速度,以便该对象在已知时间段后位于另一个已知位置?这一切都是在物体受到重力影响的时候发生的?
  • @sashoalm:好的,谢谢,我删除了标签
  • @goncalopp:确实,这就是我的意思

标签: libgdx 2d


【解决方案1】:

问题原因

同时保持位置和速度会导致系统离散化,从而导致量化误差。因此,当 fps 波动时,您当前的方法会遇到不一致的行为。


解决方案

您只需将状态变量的数量减少到只有两个,即不存储当前速度。它导致了最终位置的错误。

改为使用轨迹的参数形式。

v = u + at

s = ut + ½at²


实施

假设您想在时间 'totalTime' 内从 (sourceX, sourceY) 转到 (targetX, targetY)。

  • 计算初始速度。

    Vector2 initialVelocity = new Vector2((targetX - sourceX) / totalTime,
                (targetY - sourceY) / totalTime - gravity * totalTime / 2);
    float currentTime = 0;
    
  • 在每次迭代中,直接计算位置并跟踪currentTime。

    public void act(float delta){
        if (currentTime < totalTime) {
            currentTime += delta;
    
            setX((initialVelocity.x + gravity.x * currentTime / 2) * currentTime);
            setY((initialVelocity.y + gravity.y * currentTime / 2) * currentTime);
        } else {
            setX(targetX);
            setY(targetY);
        }
    }
    

【讨论】:

  • 您好,感谢您的出色回答。在您的场景中,gravity.x 应该是什么?我认为它应该是 0?
  • 很高兴知道它有帮助。在大多数情况下,gravity.x 为 0,gravity.y 为负数。
  • 好的,我设法让它工作了,谢谢!但是,在像以前一样低帧率(30 fps)的情况下,我仍然遇到问题。知道如何解决这个问题吗? 60fps,没问题
  • 再次您好,也许您还没有阅读我对我上一条评论的最后编辑(我的错误,当您回答第一部分时,我正在编辑我的评论)。给您添麻烦了!
  • 您的位置是否不正确或者您是否遇到口吃?
猜你喜欢
  • 1970-01-01
  • 2016-06-09
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多