Mark Harrison
Mark Harrison

Reputation: 304484

Chipmunk: how to delete a body?

What's the right way to delete a Chipmunk body? Simply calling cpBodyFree or cpBodyDestroy doesn't seem to work, as the body still shows up in the cpSpaceEachBody iteration.

if(body->p.y < -260 || fabsf(body->p.x) > 340) {
    /* body is permanently off the screen    */
    /* so it needs to be permanently deleted */
    cpBodyFree(body);      ??
    cpBodyDestroy(body);   ??
}

Upvotes: 2

Views: 2695

Answers (3)

Mark Harrison
Mark Harrison

Reputation: 304484

Here's how to delete a body:

  1. if there's a shape associated with the body, remove the shape from the space and delete it.
  2. remove the body from the space. (this is the part I was missing.)
  3. finally, delete the space if it is not needed anymore.

Here's how to make the Plink demo rain down a single shower of pentagons and clean them up when they go off screen.

  1. Add this line to the "//Add lots of pentagons" loop. This is so we can free the shape attached to the body.

    body->data=shape;
    
  2. remove the shape and body from the space, then free the shape and body. It doesn't seem to matter if you remove/free the shape first or the body first, so long as you keep in mind that you lose the pointer to the shape when you free the body. Change the eachBody function to:

    if (body->p.y < -260 ) {
        cpSpaceRemoveShape(space, body->data);
        cpSpaceRemoveBody(space, body);
        cpShapeFree(body->data);
        cpBodyFree(body);
    }
    

Upvotes: 4

Nitin
Nitin

Reputation: 46

you have to make sure whether the shape has been added as static or not, may be this code will help a bit:

    if(shape != NULL)
    {
        int isStatic = 1;
        cpBody *bd = cpShapeGetBody(shape);
        if(bd != NULL)
        {
            if(!cpBodyIsRogue(bd) && !cpBodyIsStatic(bd)) //second condition is just to make sure
            {
                isStatic = 0;
                cpSpace *sp1 = cpBodyGetSpace(bd);
                if(sp1 != NULL)
                {
                    cpSpaceRemoveBody(sp1, bd); //remove body from space and then free it
                }
            }
            cpBodyFree(bd);
        }

        cpSpace *sp = cpShapeGetSpace(shape);
        if(sp != NULL)
        {
            if(isStatic)
                cpSpaceRemoveStaticShape(sp, shape);
            else
                cpSpaceRemoveShape(sp, shape); //remove shape from space and then free it
        }

        cpShapeFree(shape);
        shape = NULL;
    }

Upvotes: 0

SDReyes
SDReyes

Reputation: 9954

After looking in the lib code

void cpBodyDestroy(cpBody *body){}

void
cpBodyFree(cpBody *body)
{
    if(body){
        cpBodyDestroy(body);
        cpfree(body);
    }
}

Call cpBodyFree (it calls internally cpBodyDestroy internally.

UPDATE: Except in cases where you don't need the validation and the cpfree(body) call ; )

Upvotes: 0

Related Questions