如何获得 body 在 box2D 世界步中移动的距离?

How to get the distance that a body has moved during a box2D world step?

我正在尝试为我的游戏循环实现线性插值和固定时间步长。我正在使用 libGDX 引擎和 box2D。我试图找到模拟在这样的世界步骤中移动角色 body 的数量:

  old_pos = guyBody.getPosition();
  world.step(STEP_TIME, VELOCITY_ITERATIONS, POSITION_ITERATIONS);
  new_pos = guyBody.getPosition();
  printLog(new_pos.x-old_pos.x);

这个returns每次都是0。模拟工作正常,body 肯定会移动每一步。

附加代码:

@Override
public void render(float delta) {

    accumulator+=delta;
    while (accumulator>=STEP_TIME){
        accumulator-=STEP_TIME;
        stepWorld();
    }
    alpha = accumulator/STEP_TIME;
    update(delta);
    //RENDER 
}


    private void stepWorld() {
       old_pos = guyBody.getPosition();
       old_angle = guyBody.getAngle() * MathUtils.radiansToDegrees;
       world.step(STEP_TIME, VELOCITY_ITERATIONS, POSITION_ITERATIONS);
       new_angle = guyBody.getAngle() * MathUtils.radiansToDegrees;
       new_pos = guyBody.getPosition();
    }

我正在尝试使用 alpha 检查我在物理步骤之间的距离,以便我可以插入 Sprite 的位置。

谢谢!

Body 的 getPosition 方法返回 Vector 引用 - 这意味着您不是按值复制它,而是仅将位置对象上的 "pointer" 分配给 old_pos/new_pos。但是,您在 step 之前分配一次,然后在 step 之后分配一次,总而言之,两个变量都保持 相同的对象 ,状态在 step 之后。

您需要做的是按值复制位置向量 - 为此,您可以使用 Vector 的 cpy() 方法。

您的代码应该如下所示

old_pos = guyBody.getPosition().cpy();
world.step(STEP_TIME, VELOCITY_ITERATIONS, POSITION_ITERATIONS);
new_pos = guyBody.getPosition().cpy();
printLog(new_pos.x-old_pos.x);

如果您不使用 y 坐标,您还应该考虑在 float 类型变量中只保留 x 以不复制整个对象(但是它应该不会真正影响您的性能)。

虽然已接受的回复确实回答了我的问题,但我想添加一些我在尝试让它工作时发现的信息,我希望我在本文开始时就知道这些信息。

如果您要为物理计算使用固定的时间步长(您应该这样做),您还应该在物理步长之间内插(或外推)精灵的位置。在我的代码中,屏幕的渲染频率高于世界的步进频率:

@Override
public void render(float delta) {

    accumulator+=delta;
    while (accumulator>=STEP_TIME){
        accumulator-=STEP_TIME;
        stepWorld();
    }
    alpha = accumulator/STEP_TIME;
    update(delta);
    //RENDER using alpha
}

为避免移动时出现抖动渲染 objects,请在其位置渲染 Sprites 或纹理,并通过 alpha 进行修改。由于 alpha 是累加器与步进时间的比率,因此它始终介于 0 和 1 之间。

然后您需要计算您的 body 在一步中移动了多少。这可以通过接受的答案或使用 body 速度来完成:

newPos = oldPos + body.getLinearVelocity()*STEP_TIME*alpha

然后只需在新位置渲染 Sprite,您应该会在大多数帧速率下看到固定时间步的平滑运动。