I would like to have a collision callback that I can delete one of the objects in the collision within the collision callback without a crash as mentioned here: http://www.cocos2d-iphone.org/forum/topic/3770
Any Ideas?
A fast, easy to use, free, and community supported 2D game engine
I would like to have a collision callback that I can delete one of the objects in the collision within the collision callback without a crash as mentioned here: http://www.cocos2d-iphone.org/forum/topic/3770
Any Ideas?
Move the body off screen and make sure it does not collide with other chipmunk offscreen bodies. Keep track of it. In the next step you should be able to remove it safely. I think if it's in the same step it's possible it will still register collision and crash.
could I execute a method from within the callback and delete the object?
I just looked at the documentation for chipmunk and it shows an alternative at the bottom of the page
http://code.google.com/p/chipmunk-spacemanager/wiki/Introduction
but you have to use space manager.. how would you do this without that, especially if I have a bunch of the same objects like ballons, and i wanted to make them pop on collision, how would I do that?
As of chipmunk 5.0 you can use the callback system in chipmunk. For your example there's already a builtin function that sets this up for you.
cpSpacePostStepRemoveAndFreeShapeAndBody(space, shape);Sweet!
How would I delete something that is not defined in the header.. like if you have a function to create objects, then the objects all have the same name... how would you fix that?
Now when I try the code to delete the shape I get: implicit declaration of function 'cpSpacePostStepRemoveAndFreeShapeAndBody'
Oh... you're right. Its defined on/around Ln 444 in cpSpace.c but it's never declared in the header... wonder if that was intentional?
In either case you can make your own and use the callback system:
void removeAndFreeShapeAndBody(cpShape *shape, cpSpace *space)
{
cpSpaceRemoveBody(space, shape->body);
cpBodyFree(shape->body);
cpSpaceRemoveShape(space, shape);
cpShapeFree(shape);
}
//and then when you want to use it
cpSpaceAddPostStepCallback(space, (cpPostStepFunc)removeAndFreeShapeAndBody, shape, space);
Hope that helps.
Not sure what you mean in your first question about same-named objects.
Wouldn't it be better to mark that particular object to be deleted but not deleted during the callback from the collision detection, and then delete during the main game loop. I'm thinking more how one would go about it in Box2D but I think one could apply the same approach when using Chipmunk.
can anyone help me, Ive been looking for hours...
This is how I do it, though it was with chipmunk 5.0, don't know if anything changed in 5.1 or 5.2
First, you define post step remove function:
static void postStepRemove (cpSpace *space, cpShape *shape, void *data) {
cpSpaceRemoveBody(space, shape->body);
cpBodyFree(shape->body);
CCSprite *sprite = shape->data;
sprite.visible = NO; // I didn't want to remove sprite, just make it invisible
cpSpaceRemoveShape(space, shape);
cpShapeFree(shape);
}
Then you define begining collision function for ball and wall (example):
static int collisionBallWallBegin (cpArbiter *arb, cpSpace *space, void *data) {
CP_ARBITER_GET_SHAPES(arb, a, b);
// this is how you get your sprite if you want to use it, for me 'a' is ball's shape
// CCSprite *ball = a->data;
if (some_condition) { // condition to remove the shape/body of the ball
cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, a, nil);
return 0;
} else {
// do something else here, ball not removed
return 1;
}
}
So you set up functions to handle collision and remove shape/body. All you have to do now is to add collision handler, for example this is my collision handler for ball and wall:
cpSpaceAddCollisionHandler(space, COLLISION_TYPE_BALL, COLLISION_TYPE_WALL, collisionBallWallBegin, nil, nil, nil, nil);
Check cpSpaceAddCollisionHandler for explanation of all those parameters I set as NIL, because I didn't need them for this test...
Hope it helps...
@crmagicxxx Thanks for the response! It Work!!
How would you go about removing it from the layer with that method?
Sorry about that Techy, I guess I had a few params mixed up.
@SDKTutor - you could get rid of the sprite by passing it's parent in the data field, (crmagicxxx passed nil in the above sample) and then just do the removeChild method with it. OR you could just modify the callback to do:
CCSprite *sprite = shape->data;
CCNode *parent = sprite.parent;
[parent removeChild:sprite];@mobilebros you just forgot to delete or hide the data, also you could use:
CCSprite *sprite = shape->data;
[sprite removeChild:sprite cleanup:YES];You must log in to post.