如何获得 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,您应该会在大多数帧速率下看到固定时间步的平滑运动。
我正在尝试为我的游戏循环实现线性插值和固定时间步长。我正在使用 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,您应该会在大多数帧速率下看到固定时间步的平滑运动。