破坏身体时Box2D崩溃(表达式:m_bodyCount< m_bodyCapacity)

时间:2014-07-22 19:43:12

标签: java libgdx box2d

  

表达式:m_bodyCount< m_bodyCapacity

这就是我得到的错误。当我收到此错误时整个游戏崩溃。现在,事情就是这样:我只会在某些事情上得到错误,我试图摧毁,更具体地说,是在游戏过程中制造的身体。我的意思是在游戏开始时,我加载关卡并为每个关卡创建所有实体。但是,有些项目是在游戏运行时制作的,例如子弹,大炮和硬币。我可以摧毁加载关卡时创建的任何物体,但是当我试图摧毁后来创建的物体时,我得到了上述错误。

这是一个例子。我用我的大炮生产一个CannonBall: Cannon.class

if(reloadProgress >= RELOAD_TIME) {
            CannonBall cannonBall = new CannonBall();
            cannonBall.setXDirection(xDirection);
            cannonBall.setYDirection(yDirection);
            cannonBall.position.set(cannonBallPos);
            Box2DHelper.makeFixture(cannonBall, BodyType.KinematicBody, origin, WorldController.b2world,
                    true, false);
            Level.cannonBalls.add(cannonBall);
            reloadProgress -= RELOAD_TIME;
        } else {
            reloadProgress += deltaTime;
        }

Box2DHelper.makeFixture()的位置是:

public static void makeFixture(GameObject object, BodyType type,
            Vector2 origin, World b2world, boolean addUserData, boolean isMonster) {
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = type;
        bodyDef.position.set(object.position);
        Body body = b2world.createBody(bodyDef);
        if(addUserData)
            body.setUserData(object);
        object.body = body;
        PolygonShape polygonShape = new PolygonShape();
        origin.x = object.bounds.width / 2.0f;
        origin.y = object.bounds.height / 2.0f;
        polygonShape.setAsBox(object.bounds.width / 2.0f,
                object.bounds.height / 2.0f, origin, 0);
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = polygonShape;
        if(isMonster) fixtureDef.filter.groupIndex = Constants.GROUP_MONSTER;
        body.createFixture(fixtureDef);
        polygonShape.dispose();
    }

所以现在我创造了我的CannonBall并设置了它的身体。现在,10秒后,如果它没有击中任何东西,我将其销毁:

CannonBall.class

if (existanceDuration >= CANNON_BALL_EXISTANCE_DURATION) {
            //Destroy cannon ball
            CollisionHandler.bodiesToRemoveList.add(this.body);
        }

现在我已将主体添加到列表中,我必须将其删除: CollisionHandler.class:

public static void removeSpecifiedBodies() {
        Iterator<Body> i = bodiesToRemoveList.iterator();
        while (i.hasNext()) {
            Body desBod = i.next();
            removeObjectFromList(desBod); //This is just to remove the object as well

            WorldController.b2world.destroyBody(desBod);

            if (perCharHitAction == true) {
                performCharacterDeathAction(Level.character);
                perCharHitAction = false;
            }
            i.remove();
        }
        bodiesToRemoveList.clear();
    }

但现在,我需要实际调用此方法。我在我的主要更新方法中执行此操作,就在b2world.step()之后: WorldController.class:

public void update(float deltaTime) {
        ...
        b2world.step(deltaTime, 8, 3);
        if (CollisionHandler.bodiesToRemoveList.size() > 0)
            CollisionHandler.removeSpecifiedBodies();

现在,正如我之前所说的,当我破坏在加载关卡时创建的对象时,此方法可以正常工作,但是对于我后来创建的对象,它并没有。

为什么我的游戏在试图破坏我之后在游戏中创建的box2d尸体后会继续崩溃?

编辑:我在加载关卡后立即调用此方法来创建对象的主体:

private void initPhysics() {
        if (b2world != null)
            b2world.dispose();
        b2world = new World(new Vector2(0, -9.81f), true);
        Vector2 origin = new Vector2();
        b2world.setContactListener(new CollisionHandler());

        // Create Box2D Fixtures
        for (Grass grass : Level.grasses)
            Box2DHelper.makeEdgeChain(grass, BodyType.StaticBody, origin,
                    b2world, true);

        // Bricks
        for (Brick brick : Level.bricks)
            // Box2DHelper.makeFixture(brick, BodyType.KinematicBody, origin,
            // b2world, true);
            Box2DHelper.makeEdgeChain(brick, BodyType.StaticBody, origin,
                    b2world, true);

        // Item Boxes
        for (ItemBox box : Level.itemBoxes)
            Box2DHelper.makeFixture(box, BodyType.KinematicBody, origin,
                    b2world, true, false);

        //Enemies
        for (Goomba goomba : Level.goombas)
            Box2DHelper.makeFixture(goomba, BodyType.DynamicBody, origin,
                    b2world, true, true);

        for (Koopa koopa : Level.koopas)
            Box2DHelper.makeFixture(koopa, BodyType.DynamicBody, origin,
                    b2world, true, true);

        // Cannons
        for (Cannon cannon : Level.cannons)
            Box2DHelper.makeFixture(cannon, BodyType.KinematicBody, origin,
                    b2world, true, true);


        // Character
        BodyDef bodyDef = new BodyDef();
        bodyDef.type = BodyType.DynamicBody;
        bodyDef.position.set(Level.character.position);
        Body body = b2world.createBody(bodyDef);
        body.setUserData(Level.character);
        Level.character.body = body;

        CircleShape polygonShapeHead = new CircleShape();
        origin.x = Level.character.circleBoundOrigin.x * 2.0f;
        origin.y = Level.character.circleBoundOrigin.y * 3.0f;
        // polygonShapeHead.setAsBox(level.character.circleBoundOrigin.x,
        // level.character.circleBoundOrigin.y, origin, 0);
        polygonShapeHead.setPosition(origin);
        polygonShapeHead.setRadius(Level.character.circleBoundOrigin.x);
        FixtureDef fixtureDefHead = new FixtureDef();
        fixtureDefHead.shape = polygonShapeHead;
        fixtureDefHead.friction = Level.character.friction.x;
        body.createFixture(fixtureDefHead);

        polygonShapeHead.dispose();

        PolygonShape polygonShapeBod = new PolygonShape();
        origin = Level.character.rectBoundOrigin;
        polygonShapeBod.setAsBox(Level.character.rectBoundOrigin.x,
                Level.character.rectBoundOrigin.y, origin, 0);
        FixtureDef fixtureDefBod = new FixtureDef();
        fixtureDefBod.shape = polygonShapeBod;
        fixtureDefBod.friction = Level.character.friction.x;
        body.createFixture(fixtureDefBod);

        polygonShapeBod.dispose();
    }

也许在游戏后期创建实体的问题是b2world?

1 个答案:

答案 0 :(得分:3)

我有同样的错误 - 我想通了,如果你多次摧毁同一个身体就会发生这种情况。

在我的情况下,我将正文放入联系人监听器的列表中......但我没有确定它只在列表中一次。

这也解释了为什么一旦你使用布尔标志就解决了你的问题,这也确保同一个主体只被销毁一次。

简而言之:如果你试图一遍又一遍地摧毁同一个身体,就会出现这个错误。