Box2D碰撞错误

时间:2017-05-31 17:55:13

标签: java box2d collision

我目前在libgx中使用java中的box2d物理引擎,我遇到了碰撞问题。 问题是身体停止移动,并且在平坦区域上出现碰撞点。 我工作的方式是制作多个实体,每个实体代表一个块,这些块是并排的。 看看这里的碰撞点:

enter image description here

身体不应该在这里碰撞,因为身体的Y坐标是相等的,他们的身体也是相等的。

float PPM = 100;
float side = 45;
     for (float i = start; i < end; i++) {
        /**
         * perlin noise for terrain
         */
        def.type = BodyDef.BodyType.StaticBody;
        float place = Maths.map(noise.noise(off, off), 0, 1, -10, 50);
        if (place < 10) {
            place = 0;
        } else if (place < 20) {
            place = side;
        } else if (place < 30) {
            place = side * 2;
        } else if (place < 40) {
            place = side * 3;
        } else if (place <= 50) {
            place =  side * 4;
        }


        place += side / 2;

        float posx = (i * side);
        float posy = place;
        float size = side / 2f;
        def.position.set(posx / PPM, posy / PPM);
        b = world.createBody(def);
        shape.setAsBox(size / PPM, size / PPM);
        fdef.shape = shape;
        fdef.isSensor = false;
        b.createFixture(fdef);
        off += 0.01;
        toSetLast = posx + side;

        GrassBlock grass = new GrassBlock(b, new 
        Vector2(b.getPosition().x * PPM, b.getPosition().y * PPM));
        //dirt under grass
        for (float j = (place / side) - 1; j >= -1; j--) {
            posy = j * side;

            def.position.set(posx / PPM, posy / PPM);
            b = world.createBody(def);
            shape.setAsBox(size / PPM, size / PPM);
            fdef.isSensor = false;
            fdef.shape = shape;
            b.createFixture(fdef);
            DirtBlock dirt = new DirtBlock(b, new 
            Vector2(b.getPosition().x * PPM, b.getPosition().y * PPM));
            addBlock(dirt.getLocation(), dirt);
        }
        addBlock(grass.getLocation(), grass);

    }

2 个答案:

答案 0 :(得分:2)

我相信你所经历的是Box2D库的一个众所周知的短缺。

有关此问题的其他说明,请参阅What could cause a sudden stop in Box2D?。请参阅Box2D C++ tutorials - Ghost vertices,了解正在进行的操作以及您可以采取哪些措施来缓解此问题......

基本上,对于 ground 使用链状形状,如纹理而不是多边形(或多边形),因此移动块实际上在链的顶部移动。这假设您正在使用的java box2d实现的版本具有链形状,其中提供了&#34;鬼顶点&#34;支持。

引擎盖细节......

虽然从用户的角度来看,链条形状提供了平滑,引擎盖,它的边缘形状已经习惯了平滑。边缘形状使用两个特殊的额外顶点(除了预期的两个边缘之外)。当库评估链形状和多边形(或圆形)之间的接触时,它通过识别接触可能发生的链段来实现。然后,它将该链段转换为边,其额外顶点设置为链中的相邻顶点。然后在该平移边和多边形(或圆)之间评估接触。这种情况会随链形状自动发生,并且链形状中没有用于获得此行为的选项。

通过将链条的所有部分的边缘形状拼接在一起并设置所有边缘,用户可以获得与链形状相同的结果。额外顶点到逻辑上相邻的顶点。然而,它使用比链形状更多的内存,并且需要用户编写更多代码(至少对于具有两个以上顶点的链)。

答案 1 :(得分:2)

虽然 Louis Langholtz 的答案已经很好,但我还有更多要补充的内容。

链或鬼顶点通常是推荐的方法,但是: -

  • 在实践中很难使用。
  • 它需要编码器手动将这些边/角连接在一起 (在某些情况下很乏味)

我建议斜切方框: -

enter image description here

我已经测试过(jbox2d) - 它可以显着减少毛刺的影响 这种方法的缺点是它需要额外的顶点 (例如4个顶点 - > 8个顶点)

因此,它需要更多的计算能力。

因此,在实践中,我通常将所有机构分为两组: -

  • 确定有毛刺(例如碎片) - &gt;不要修改(便宜)
  • 不能出现故障(例如字符) - &gt;使用斜角方法(更昂贵)

就个人而言,我希望有一种简单的方法可以使用链/鬼作为 Louis Langholtz 推荐。