Box2d似乎随机创建特定的身体和夹具

时间:2017-07-12 03:18:03

标签: android libgdx box2d jbox2d

我使用Libgdx和Box2d创建了一个类似于Not Tetris 2的Android应用程序。

它可以成功地从世界中移除切片,这显然涉及复制多个实体并破坏/创建固定装置。然而,似乎随机出现了一个带有2x2夹具的机身。主体和夹具在创建时使用与其周围的对象相关的信息显示,因此我将其创建范围缩小到以下功能:

Body duplicateBody(Body original){
    BodyDef d = new BodyDef();
    d.position.set(original.getPosition());
    d.angle = original.getAngle();
    d.linearVelocity.set(original.getLinearVelocity());
    d.angularVelocity = original.getAngularVelocity();

    Body dup = world.createBody(d);
    dup.setType(BodyDef.BodyType.DynamicBody);

    return dup;
}

我在两种不同的环境中使用此功能:

  1. 如果"切片"制作身体的副本削减一两个 - 然后我将下面的灯具转移到它。
  2. 如果灯具位于线下方,则会将其添加到为
  3. 以下的灯座创建的灯箱中
  4. 在分离灯具组时制作正文的副本
  5. 我注释掉了负责第三个实例的代码并且仍然生成了2x2框,所以这里有与其他相关的函数:

    ...
    if (below && !above) {
        //copy fixture, add copy to lower body and remove original
        Body top = fixture.getBody();
        FixtureDef n = new FixtureDef();
        PolygonShape s = new PolygonShape();
        s.set(getLocalVerticesOfFixture(fixture));
        n.shape = s;
        n.density = fixture.getDensity();
        //create lower body if a lower one doesn't already exist
        if (!topBottomPairs.containsKey(top)) {
            Body dup = duplicateBody(top);
            topBottomPairs.put(top, dup);
        }
        //delete fixture
        remove.add(fixture);
        Fixture f = topBottomPairs.get(top).createFixture(n);
        s.dispose();
    }
    ...
    if (below && above) {
        //copy fixture, add copy to lower body, but keep original on upper as it needs to split
        FixtureDef n = new FixtureDef();
        PolygonShape s = new PolygonShape();
        s.set(getLocalVerticesOfFixture(fixture));
        n.shape = s;
        n.density = fixture.getDensity();
    
        Body top = fixture.getBody();
        //create lower body if a lower one doesn't already exist
        if (!topBottomPairs.containsKey(top)) {
            Body dup = duplicateBody(top);
            topBottomPairs.put(top, dup);
        }
        Fixture second = topBottomPairs.get(top).createFixture(n);
        s.dispose();
    }
    
    ....
    
    private Vector2[] getLocalVerticesOfFixture(Fixture fixture) {
        PolygonShape shape = ((PolygonShape) fixture.getShape());
        Vector2[] localVertices = new Vector2[shape.getVertexCount()];
        for (int i = 0; i < shape.getVertexCount(); i++) {
            localVertices[i] = new Vector2();
            shape.getVertex(i, localVertices[i]);
        }
        return localVertices;
    }
    

    我还有这个移除夹具功能,它可以在我要移除的所有灯具上运行:

    private void smartDeleteFixture(Fixture f){
        f.getBody().destroyFixture(f);
        if(f.getBody().getFixtureList().size == 0){
            world.destroyBody(f.getBody());
        }
    }
    

    我无处创建顶点,更不用说2x2形状的夹具了。我想知道这个复制功能是否有任何缺陷,或者我偶然发现了一些&#34;默认形状&#34; box2d使用的。

    编辑:我删除了与box2d实体操作无关的任何内容。希望有所帮助

1 个答案:

答案 0 :(得分:0)

删除了这个问题,因为我决定执行一次重大的重新编码并希望能解决我的问题。它没有,但我想出了原因。

我查看了box2d,在多边形形状类中找到了几个与此类似的代码实例:

if (n < 3)
{
    // Polygon is degenerate.
    b2Assert(false);
    SetAsBox(1.0f, 1.0f);
    return;
}

这些实例检查各种操作后的顶点数,如果少于3,则将形状转换为2x2框。其中一个操作使形状凸起。另一个检查顶点是否靠近(小于0.0025f),如果是,则删除一个。

就我而言,问题很简单。我的一些顶点相互之间的距离小于0.0025f,导致它们被删除,顶点数减少到3以下,一个断言被忽略,然后我的形状变成了一个2x2的盒子。我希望这可以帮助别人。