1

我正在创建一个跑步游戏,这是一个截图: screenshot1

我把我的世界分成几块,我遇到了碰撞问题。正如你在左下角看到的(非常小的),我有多个理由,他们正在向左移动。有时(有时,我的意思是随机地)跑步者在两个块之间颠簸并跟随地面向左...... screenshot2 (在截图上我把跑步者放在中间,这样我就可以截图了)

我为此写了一个小修复,但我发现它非常非常 [...] 非常肮脏:

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

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

我还有另一个问题。我希望我的跑步者能够以正 x 速度跳跃,这样他就可以在地面上前进。我的地面是一个运动体,我的球员是一个动态体。我将玩家的摩擦力设置为 0,因此他保持初始状态并且不会“跟随”地面。问题是我希望跑步者在跳跃时继续前进并慢慢回到初始状态。

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

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
}

(这是在跑步者的 act() 方法中)

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

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

4

1 回答 1

1

关于第一个问题...

听起来您遇到了“卡住”问题。其他人也遇到了这个问题并在这里询问过,我怀疑很多其他人也遇到了同样的问题。

iforce2d在他们的网站上写了这个问题以及如何解决它。我喜欢 iforce2d 的文章并推荐阅读。

我还解释了这个问题以及如何解决它,您可以在此处找到。如果你喜欢我的文章,请给它投票。

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

至于第二个问题……

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

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

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

检查调用层次结构以b2MixFriction确认上述评论。混合摩擦函数仅在触点构造和调用触点ResetFriction方法时调用。因此,当您的代码调用setFriction并且您没有看到您期望的结果时,我敢打赌已经为该固定装置与地面建立了一个触点。

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

于 2017-04-22T20:01:14.477 回答