AndEngine GLES1 Destroy and Create Object During Box2D Collision crashes app

0

I am working (still) on an implementation of a Chain Reaction game. I have a lot of particles bouncing around the screen, and the user can tap the screen to create a single 'sticky' particle.

When any normal particle hits the user's sticky particle, that normal particle needs to become sticky also, so anything hitting it becomes sticky, and so on (chain reaction right!)

However, the first time a normal ball collides with the user's sticky ball, the app crashes with the following error in LogCat:

Fatal signal 11 (SIGSGV) at 0x0000005c (code=1), thread 24936 (chainreaction)

Here is the function I use when a collision has been detected (I have commented the line causing the error):

    private void ParticleCollision(Contact contact)
{
    if (contact.getFixtureA().getBody().getUserData() != null &&
        contact.getFixtureB().getBody().getUserData() != null) 
    {
        final String objA = (String)contact.getFixtureA().getBody().getUserData();
        Body bodyA = contact.getFixtureA().getBody();
        final String objB = (String)contact.getFixtureB().getBody().getUserData();
        Body bodyB = contact.getFixtureB().getBody();

        // Get the body objects for each of the bodies in the collision
        Body pBody2 = objA.startsWith("particle_") ? bodyA : bodyB;
        String cud = (String)pBody2.getUserData();

        // Find the normal body in the collision in our mBodyList array                        
        for (int i=0; i < mBodyList.size(); i++)
        {
            Body b = mBodyList.get(i);
            String tud = (String)b.getUserData();

            if(cud.equals(tud))
            {
                // We have a match
                // Get the cooresponding Particle (to get it's X/Y pos)
                Particle p = mParticleList.get(i);
                float x = p.getX();
                float y = p.getY();

                // Remove the particle that collided from our Lists
                mParticleList.remove(i);
                mFixtureList.remove(i);
                mBodyList.remove(i);

                // Remove the particle from the scene and the Body from the PhysicsWorld
                mScene.detachChild(p);
                mPhysicsWorld.destroyBody(b);

                // Create a new sticky particle where the old one was
                particle = new Particle(x, y, mPurpleParticleTextureRegion, 100);
                particle.setScale(0.3f);
                mScene.attachChild(particle);

                particleFixture = PhysicsFactory.createFixtureDef(10, 0.9f, 0.1f);
                    // Using the debugger, I see that this next line is causing the error
                            particle_body = PhysicsFactory.createBoxBody(mPhysicsWorld, particle, BodyType.StaticBody, particleFixture);
                particle_body.setUserData("sticky");
                mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(particle, particle_body, true, false));

                // Save this info to the sticky particle lists
                mStickyParticleList.add(particle);
                mStickyBodyList.add(particle_body);
                mStickyFixtureList.add(particleFixture);
            }
        }
    }
}

Previously I had that code in the mPhysicsWorld.setContactListener(), in the beginContact() method, but I read that you couldn't create bodies in the ContactListener. So, I moved the code to the function you see, and I call that from the ContactListener.

Any comments or suggestions as to what I have wrong would be greatly appreciated!!

Thanks!!

android
box2d
andengine
asked on Stack Overflow Jun 6, 2014 by user3704686 • edited Jun 6, 2014 by user3704686

1 Answer

0

You can't change anything in the world inside the Step function. You'll need to create the new body after the Step function.

The same problem happens if you try to destroy a body inside the contact listener callback, and that seems to be a much more common situation, so you could try searching for problems related to removing bodies, eg. AndEngine Sprite/Box2D Body removal crashes my program with no error/exception information?

The typical method is to have some kind of list that can be accessed from both the main loop (where Step() is called) and inside the contact listener. Make a note of what needs to be modified by adding to the list, and in the main loop immediately after the Step function, you can carry out the changes.

answered on Stack Overflow Jun 7, 2014 by iforce2d • edited May 23, 2017 by Community

User contributions licensed under CC BY-SA 3.0