【问题标题】:Box2D collisions errorBox2D 碰撞错误
【发布时间】:2017-11-01 15:56:32
【问题描述】:

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

身体不应该在这里碰撞,因为身体的 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);

    }

【问题讨论】:

    标签: java box2d collision


    【解决方案1】:

    我相信您遇到的是 Box2D 库的一个已知缺点。

    请参阅What could cause a sudden stop in Box2D? 以获取有关此问题的另一篇文章。请参阅 Box2D C++ tutorials - Ghost vertices 了解正在发生的事情以及您可以采取哪些措施来缓解问题...

    基本上,对 ground 类纹理使用链形而不是多边形(或在多边形上),这样您的移动块实际上会在链的顶部移动。假设您正在使用的 java box2d 实现的版本中具有提供“幽灵顶点”支持的链形状。

    幕后细节...

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

    用户可以通过将链的所有段的边缘形状缝合在一起并将所有边缘的额外顶点设置为逻辑上相邻的顶点来实现与链形状相同的结果。但是,这比链形状使用的内存要多得多,并且需要用户编写更多代码来做(至少对于具有两个以上顶点的链)。

    【讨论】:

    • 今晚我会试试这个,然后回复你。虽然,如果我将 box2d 主体保留为多边形,但用链形制作该多边形,这仍然有效吗?
    • @Liwaa 链形状适用于任意非实体形状。此外,链(和边缘)形状不适用于动态物体。如果您使用的是 C++(而不是 Java),您可以尝试 my fork of Box2D,它支持动态链和边缘形状以及在多边形上滑动的多边形。不过,我的 fork 没有移植到 Java。所以对你没用。顺便说一句,如果有人感兴趣,我有a write-up of this sticking problem and how I solved it in my fork
    • @LousLangholtz 它设法完美地使用了链条形状,我首先遇到了链条形状的问题,然后他们设法工作。谢谢!
    【解决方案2】:

    虽然Louis Langholtz的回答已经不错了,但我还有更多要补充的。

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

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

    我建议对盒子进行斜切:-

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

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

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

    • 可以有故障(例如碎片)-> 不要修改(便宜)
    • 不能有故障(例如字符)-> 使用斜切方法(更昂贵)

    就个人而言,我希望有一种简单的方法来使用链/幽灵,就像 Louis Langholtz 推荐的那样。

    【讨论】:

    • 我知道我应该使多边形的边缘弯曲?我怎么能用多边形形状做到这一点? @javaLover
    • @Liwaa 是的。这不是特别难。你可能需要一些时间来思考它。这里有一些类似的东西,可能会给你一些粗略的想法。 youtube.com/watch?v=3qMNuoTHNHsdoc.cgal.org/latest/Straight_skeleton_2/index.html
    • 感谢所有帮助,我很感激 :)
    • @javaLover 是的,我同意,添加斜角也是一个缓解选项。我链接的教程称之为“裁剪多边形角”。不确定您使用的 java 端口是什么样的 w.r.t.链形状支持,但用于链形状的底层 Box2D C++ 代码(至少在 Box2D 2.3.2 中)为用户处理幻影顶点。但是,如果要将边缘形状缝合在一起,那么用户将不得不手动设置额外的顶点(但不适用于链形状,只是边缘形状)。
    • @javaLover 听起来可能有些混乱。对于那个很抱歉。我已经更新了我的答案,希望编辑能让事情变得更清楚。至于我的 Box2D 库的分支,我更改了评估接触的方式,以便可以在任意两种形状之间发生平滑滑动,并且不需要边缘形状或任何其他形状的额外顶点。由于不再需要额外的顶点,我从边缘和链形状中删除了这些顶点以减少内存使用。我所做的是否或多或少是你必须决定的黑客行为,但我更喜欢这种变化。
    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 2012-06-10
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多