Simple way to remove on collision

Official forum for the Chipmunk2D Physics Library.
Sloth
Posts: 9
Joined: Sun Apr 04, 2010 7:49 pm
Contact:

Simple way to remove on collision

Post by Sloth »

Hey,

Sorry if this is a really simple / dumb question, but I've been looking into the documentation and can't find anything other than the integrated cocos2d spacemanger to do what I want.

I'm looking for the ability to remove a shape on collision with a static object simply put.

I'm messing about with iphone development and don't want to use cocos2d. I'm also using an NSTimer to iterate my simulation, so what would be the best way of removing a shape when it collides with a specific static shape?

Anyone that helps gets a cookie :D

Thanks.
Sloth
Posts: 9
Joined: Sun Apr 04, 2010 7:49 pm
Contact:

Re: Simple way to remove on collision

Post by Sloth »

Oh may I add I don't think I'm on the latest version of chipmunk. Didn't realise there was a new one until just now! :D, so if it can be in the non objective-C syntax that'd be great.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Simple way to remove on collision

Post by slembcke »

Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Sloth
Posts: 9
Joined: Sun Apr 04, 2010 7:49 pm
Contact:

Re: Simple way to remove on collision

Post by Sloth »

Thanks :)

I'm probably being really dumb but I can't seem to get it to work though :(

Thus far I have the two shapes being created in the same method, each set to their own collision type (5 for the shape I want to disappear and 6 for the one which is static)

I've then made collisionHandler, which is declared in the same method that these shapes are created :

cpSpaceAddCollisionHandler(space, 6, 5, begin, NULL, NULL, NULL, NULL);

then this declared


static void begin(cpArbiter *arb, cpSpace *space, void *ignore)
{
cpShape *goShape, *staticShape; cpArbiterGetShapes(arb, &goShape, &staticShape);

cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, goShape, NULL);

}

static void
postStepRemove(cpSpace *space, cpShape *shape, void *unused)
{
cpSpaceRemoveBody(space, shape->body);
cpBodyFree(shape->body);

cpSpaceRemoveShape(space, shape);
cpShapeFree(shape);
}




This now makes it crash out when the two shapes collide. I know its going to be something simple but any help!? :(
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Simple way to remove on collision

Post by slembcke »

Your shape types are swapped. The order returned by cpArbiterGetShapes() is the same as set by cpSpaceAddCollisionHandler(). Also, you should use an enumeration or static variables for your shape types. Once you have more than like 3 of them it can become difficult to keep track of them all just by number.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Sloth
Posts: 9
Joined: Sun Apr 04, 2010 7:49 pm
Contact:

Re: Simple way to remove on collision

Post by Sloth »

Gotya! :D

So say I wanted to remove the sprite as well and +1 in a label, how do I get it to call through? Currently I can't get the method to communicate with anything externally, it simply removes the shape & body currently.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Simple way to remove on collision

Post by slembcke »

Most Chipmunk structs have a void *data pointer on them that you can use to point to anything you want. I usually create a "game object" that holds references to the sprites, shapes, bodies, joints, etc that the game object references. Then I set all the shapes' and bodies' data field to point at the game object. I also have a "world" object that holds a reference to the list of sprites in the scene and the Chipmunk space.

The last argument when setting up a collision handler is a void *data pointer that is passed to the handler callbacks. I pass my world object as the data pointer to the handler. The post step callback also can take a void *data pointer so I can pass the world object along to the post step callback. In the post step callback, I ask the world to remove my game object, which in turn removes all the shapes, bodies, joints, sprites, etc that the game object references.

So all together it looks something like this:

Code: Select all

static void
postStepRemove(cpSpace *space, GameObject *gameObject, World *world)
{
	// world.remove() handles removing all the Chipmunk objects owned by gameObject
	world.remove(gameObject);
	
	world.addBloodSpatter(); // etc
}

static int
begin(cpArbiter *arb, cpSpace *space, World *world)
{
	CP_ARBITER_GET_SHAPES(arb, bulletShape, monsterShape);
	
	cpSpaceAddPostStepCallback(space, (cpPostStepFunc)postStepRemove, monsterShape.data, world);
	
	return 0;
}

// Define a collision handler for bullets and monsters
// Kill the monster by removing it's shape and body from the space as soon as it's hit by a bullet 
cpSpaceAddCollisionHandler(space, BULLET_TYPE, MONSTER_TYPE, (cpCollisionBeginFunc)begin, NULL, NULL, NULL, world);
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Sloth
Posts: 9
Joined: Sun Apr 04, 2010 7:49 pm
Contact:

Re: Simple way to remove on collision

Post by Sloth »

is the 'World *World' made up of a struct that would be declared in the header?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Simple way to remove on collision

Post by slembcke »

Not knowing what language you are using, I just made it look C++ish. It doesn't really matter if you are using a struct or object or whatever, but yes it would have to be declared in a header for it to be usable in any C-like language.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Sloth
Posts: 9
Joined: Sun Apr 04, 2010 7:49 pm
Contact:

Re: Simple way to remove on collision

Post by Sloth »

I'm starting to feel like a complete dummy now :(

I have this almost all working within Objective-C now, (using the C++ methods as shown above)

I still for whatever reason can't seem to make a simple UILabel increment by 1 when one of these objects collide. I'm not really sure why it doesn't work quite honestly :(

Any help?
Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests