【问题标题】:Box2d collisions assert errorBox2d 碰撞断言错误
【发布时间】:2014-08-06 17:31:25
【问题描述】:

我正在使用 AndEngine 锚中心 分支,所以我不能使用 PhysicsEditor 创建主体/固定装置,因为唯一的解析器 PhysicsEditor-AndEngine 它有点过时了并且没有支持锚中心,所以我想我可以改用 R.U.B.E,它是AndEngineRubeLoaderExtension。到目前为止一切顺利,我可以用所有复杂的固定装置创建我的身体,因为 RUBE 会(自动)将它们分成凸多边形。

解析器工作得很好,我有我的身体。但我遇到了一些碰撞错误:

A/libc﹕ jni/Box2D/Dynamics/Contacts/b2ContactSolver.cpp:72: b2ContactSolver::b2ContactSolver(b2ContactSolverDef*): assertion "pointCount > 0" failed

A/libc﹕ Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 32158 (UpdateThread)

它的身体是一架飞机。如果我使用 RUBE 模型,当我与多个对象碰撞时会出现此异常(用户必须抓住一些硬币并与敌人分开(RUBE 模型也是如此)),相反,如果我使用 BoxBody,一切都会很好。

让我想知道它是否与构成身体的非凸多边形无关(即使 RUBE 正确创建了它们)...发生在任何人身上?

谢谢。

编辑: 我忘了说我正在使用 RUBE 创建我的身体,但我在创建身体时并没有使用 RUBE 创建的世界,所以这是我用来在我的世界中创建身体的代码:

private Body createPolygonBody(PhysicsWorld pPhysicsWorld, IShape pShape, BodyDef.BodyType pBodyType, FixtureDef pFixtureDef, Jb2dJsonLoader jsonLoader, String fixtureName) {
        BodyDef boxBodyDef = new BodyDef();
        boxBodyDef.type = pBodyType;

        float[] sceneCenterCoordinates = pShape.getSceneCenterCoordinates();
        boxBodyDef.position.x = sceneCenterCoordinates[Constants.VERTEX_INDEX_X] / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
        boxBodyDef.position.y = sceneCenterCoordinates[Constants.VERTEX_INDEX_Y] / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;

        Body rubeBody = jsonLoader.getBodyByName(fixtureName);
        Body boxBody = pPhysicsWorld.createBody(boxBodyDef);
        // boxBody.setTransform(rubeBody.getPosition(), rubeBody.getAngle());
        boxBody.setLinearVelocity(rubeBody.getLinearVelocity());
        boxBody.setLinearDamping(rubeBody.getLinearDamping());
        boxBody.setAngularVelocity(rubeBody.getAngularVelocity());
        boxBody.setAngularDamping(rubeBody.getAngularDamping());
        boxBody.setSleepingAllowed(rubeBody.isSleepingAllowed());
        boxBody.setAwake(rubeBody.isAwake());
        boxBody.setFixedRotation(rubeBody.isFixedRotation());
        boxBody.setBullet(rubeBody.isBullet());
        boxBody.setActive(rubeBody.isActive());
        boxBody.setMassData(rubeBody.getMassData());

        Fixture[] bodyFixtures = jsonLoader.getFixturesByName(fixtureName);
        for (int i = 0; i < bodyFixtures.length; i++) {
            FixtureDef fixtureDef = pFixtureDef;
            fixtureDef.shape = bodyFixtures[i].getShape();
            boxBody.createFixture(fixtureDef);
        }
        return boxBody;
    }

也许这就是问题所在。我做的一切正确吗?

EDIT2: 所以我已经替换了这段代码:

private void performCoinCollision(boolean coinIsBodyA, Contact contact) {
    if (coinIsBodyA) {
       contact.getFixtureA().setSensor(true);
    } else {
       contact.getFixtureB().setSensor(true);
    }
    contact.setEnabled(false);
    ...
}

与:

private void performCoinCollision(boolean coinIsBodyA, Contact contact) {
    if (coinIsBodyA) {
       elementsToBeRemoved.add(contact.getFixtureA().getBody());
    } else {
       elementsToBeRemoved.add(contact.getFixtureB().getBody());
    }
    contact.setEnabled(false);
...
}

并将此 onUpdate 添加到 physicWorld:

@Override
public void onUpdate(float pSecondsElapsed) {
    if (elementsToBeRemoved != null) {
        for (Body body : elementsToBeRemoved) {
            if (body != null) {
                physicsWorld.destroyBody(body);
            }
        }
    }
    elementsToBeRemoved.clear();
}

问题依然存在。

【问题讨论】:

  • 所有的物件都是用RUBE做的吗?在 RUBE 内置播放器中可以正常工作吗?
  • @iforce2d 是的,所有对象都是用 RUBE 制作的,并且可以在内置播放器中使用。飞机和敌人是“复杂”的物体,但硬币是简单的圆形固定装置。
  • 那么,如果形状存在一些基本问题,我预计 RUBE 播放器也会崩溃。当您不从世界上移除硬币时,是否会出现问题?您不是在更改联系人侦听器回调中的世界吗?
  • 不,我不会改变世界,也不会从中取出硬币。当在飞机硬币之间检测到碰撞时,我所做的就是设置硬币夹具传感器 = true。会是这样吗?
  • 记下需要做的事情,在步骤完成后做。

标签: android box2d andengine jbox2d


【解决方案1】:

我已遵循 iforce2d 建议,这是正确的程序,现在它正在工作:

private void performCoinCollision(boolean coinIsBodyA, Contact contact) {
    if (coinIsBodyA) {
       elementsToBeRemoved.add(contact.getFixtureA());
    } else {
       elementsToBeRemoved.add(contact.getFixtureB());
    }
    contact.setEnabled(false);
...
}

...

@Override
public void onUpdate(float pSecondsElapsed) {
    if (elementsToBeRemoved != null) {
        for (Fixture fixture : elementsToBeRemoved) {
             fixture.setSensor(true);
        }
    }
    elementsToBeRemoved.clear();
}

注意: 在我的 EDIT2 中,我采用了相同的方法,但我试图移除身体,而不是 setSensor(true)。这种方法也失败了,不知道为什么。

编辑:问题是我试图摧毁一个已经被摧毁的身体。解决方案是确保elementsToBeRemoved 没有重复的正文

【讨论】:

  • 确保 elementsToBeRemoved 不包含重复项。您可以通过将其设置为集合而不是向量来轻松完成此操作。
猜你喜欢
  • 2017-11-01
  • 2010-10-30
  • 2012-06-10
  • 2013-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多