LIBGDX - 碰撞问题和滑动效果问题

LIBGDX - collision issue and sliding effect issue

我正在创建一个跑酷游戏,下面是截图: screenshot1

我把我的世界分成几块,但我遇到了碰撞问题。正如您在左下角看到的(非常小),我有多个地面,它们正在向左移动。有时(有时,我的意思是随机)跑步者在两个块之间颠簸并沿着地面向左移动...... screenshot2 (在屏幕截图上我将跑步者放在中间所以我可以截图)

我为此写了一些修复程序,但我发现它非常非常 [...] 非常脏:

public void fixWeirdCollisionBug() {
    body.setTransform(body.getPosition().x, body.getPosition().y + transformToScreen(0.0002f), body.getAngle());
}

我将地面向上移动(只是一点点)跑步者在哪里以避免两个地面之间的这个错误。其实我正在寻找一个更好的方法来做到这一点...

我还有一个问题。我希望我的跑步者能够以正 x 速度跳跃,这样他就会在地面上前进。我的地面是一个运动体,我的玩家是一个动态体。我将玩家的摩擦力设置为 0,这样他就可以保持初始状态,不会 'follow' 着地。问题是我希望跑步者继续前进,然后在他跳跃时慢慢回到初始状态。

我尝试了以下但它不起作用,跑步者一直在地面上滑动:

public void jump() {
    if(!jumping) {
        System.out.println("Jump !");
        body.getFixtureList().get(0).setFriction(0.1f);
        body.applyLinearImpulse(getUserData().getJumpingLinearImpulse(), body.getWorldCenter(), true);
        jumping = true;
    }
}

当跑步者处于初始状态时:

if(body.getFixtureList().get(0).getFriction() != 0 && body.getPosition().x < Constants.RUNNER_X_DEFAULT) {
        System.out.println("reset friction");
        body.getFixtureList().get(0).setFriction(0);
        body.setTransform(Constants.RUNNER_X_DEFAULT, body.getPosition().y, body.getAngle());
        body.setLinearVelocity(0, 0); //also try to reset velocity to remove the sliding effect, but doesn't work
}

(这是在runner的act()方法中)

我希望有人能找出我的代码有什么问题,因为它开始让我头疼...非常感谢

编辑:我尝试使用 Horizo​​ntalGroup 来解决随机颠簸:不起作用

关于第一个问题...

听起来您遇到了 "getting stuck" 问题。其他人也遇到了这个问题并询问了它 here 我怀疑很多其他人也 运行 遇到了同样的问题。

A write-up of this problem and how it can be worked-around 是由 iforce2d 在他们的网站上完成的。我喜欢 iforce2d 的文章,推荐阅读。

我还解释了这个问题及其解决方法,您可以找到 here。如果喜欢我的文章,请点赞。

TL;DR... 地面使用链形(使用边缘形状的可选相邻顶点)。

关于第二个问题...

根据您所写的内容、您添加的评论以及我为此所做的一些 Box2D 资源审查,我相信您 运行 正在面对的问题是改变固定装置的摩擦不是为了更新现有接触的摩擦。

这是与此相关的 2.3.2 来源中 b2Fixture::SetFriction 的声明:

/// Set the coefficient of friction. This will _not_ change the friction of
/// existing contacts.
void SetFriction(float32 friction);

检查 b2MixFriction 的调用层次结构证实了上述评论。混合摩擦函数仅在构造接触和调用接触的 ResetFriction 方法时被调用。因此,当您的代码调用 setFriction 而您没有看到预期的结果时,我敢打赌已经为该固定装置与地面建立了联系。

要解决此问题,从算法上讲,在更改夹具的摩擦力后,立即搜索与该夹具的任何接触并调用这些接触的重置摩擦方法以使这些接触识别新的混合摩擦值。我相信在这种情况下,您可以使用 fixture body 的 get-contact-list 方法来获取要检查的联系人列表。然后遍历所有接触边,同时检查边的接触,看看是否有一个接触的固定装置是您刚刚为其设置新摩擦的固定装置。对于 fixture-A 或 fixture-B 有问题的 fixture 的所有触点,调用它们的 reset-friction 方法。