collision detection problem

Official forum for the Chipmunk2D Physics Library.
Post Reply
cire
Posts: 2
Joined: Wed Jun 24, 2009 2:34 pm
Contact:

collision detection problem

Post by cire »

Hi,
1st thanks for chipmunk - really comes in handy..
2nd, i have a "slight" problem with collision detection in my iphone game: the collisions are between a ball and some static polygon shapes.
The thing is , it works for around 5 game scenes (level 1 - 5 , for ex.) but fails for the 6th one, and then everything continues ok for a while and so on..
am using cocos2d as the 2d engine.

I dint think its a problem with setting spaces, bodies etc.. because everything works ok for a while and the error only occurs once after a series of "correct scenes".
At 1st i thought the problem was my not removing shapes and bodies from the space after a scene is over, but the problem still continues after removed the bodies and shapes from the space.

are there any suggestions as to how to go around this.. ?
thanks in advance ..
coolman
Posts: 45
Joined: Fri Feb 27, 2009 7:59 am
Contact:

Re: collision detection problem

Post by coolman »

How you do the shape & body removal? Post some code for looking the problem.

Anyhow search also in the cocos2d forums cause there are some threads regarding this.
strider
Posts: 15
Joined: Mon Jun 29, 2009 1:14 am
Contact:

Re: collision detection problem

Post by strider »

Cire,

Could you clarify "slight problem"...do collisions stop occurring altogether, intermittently, or collide with an incorrect behavior?

Do the collision problems occur for specific "collision_types"?
What happens if you just start at level 6? Is it always after 5 or so levels?

For the removal of collision objects...a very simple removal process we use for one of our games involves just changing the "visible" status of the object "going away" in our rendering engine (Cocos2D in this case) and in our collision function we ignore collisions on any object that is not visible (through shape->data parameter that references the Cocos2D object).

This is only efficient because each level has a fixed number of objects and so performance is consistent. If your situation is similar its a handy way of avoiding any changes to the "space" for simple games.

Thanks,

strider
cire
Posts: 2
Joined: Wed Jun 24, 2009 2:34 pm
Contact:

Re: collision detection problem

Post by cire »

Hi,
thanks all for replying and sorry for not being very clear..
@coolman
For body and shape removal, i have linked lists containing pointers to the current scene's bodies and shapes. After each scene i traverse the list to remove each space and body from the space and eventually free up the memory occupied. Methods used: cpSpaceRemoveStaticShape/cpSpaceRemoveShape, cpSpaceRemoveBody, cpShapeFree and cpBodyFree.

@strider
What i meant is, when collisions problems appear for a particular scene, the collisions actually occur but not correctly. What i mean is , in the shapes in the chipmunk space do not correspond to the images displayed, meaning collisions occur where there's nothing but pass through a displayed image. Take the example of a wall, a ball may go through a wall but stop at a place where there's no wall, meaning that the position of the shapes in the space does not correspond to the position of the images in the scene.

Also, the occurs randomly i.e not exactly the same behaviour. It may occur on level 3 then on restarting the game, level 5 etc.. If it occurs on level 3, level 4 will be ok etc..

I worked around the problem by actually simplifying the game a bit i.e pre-creating and recycling scenes, instead of removing all collisions objects after every scene. This works fine for me, in fact i think the cause of the problem was the inefficieny that resulted from my initial solution.

Your solution also sounds interesting (will try it out sometime... in addition to working on my communication skills :D , currently busy on other stuff).

Thanks alot guys, once again.
strider
Posts: 15
Joined: Mon Jun 29, 2009 1:14 am
Contact:

Re: collision detection problem

Post by strider »

Cire,

From your description you may already be doing this, so apologies if this is redundant.

One of the things we do in our games is we implement the drawing code from the Chipmunk demos as a category extension for our "GameLevel" object (Layer descendant in Cocos2D), so that it renders the physics boundaries along with our actual Cocos2D game objects.

This makes debugging anomalous collisions or incorrect polygon winding issues visually very rapidly. It also has no other affect on our games as it strictly depends on the internal Chipmunk data for its drawing.

Code: Select all

@interface GameLevel(DebugChipmunk)


@end

@implementation GameLevel(DebugChipmunk)

void drawCircleShape(cpShape *shape)
{
	cpBody *body = shape->body;
	cpCircleShape *circle = (cpCircleShape *)shape;
	cpVect c = cpvadd(body->p, cpvrotate(circle->c, body->rot));
	drawCircle( ccp(c.x, c.y), circle->r, body->a, 15, YES);
}

void drawSegmentShape(cpShape *shape)
{
	cpBody *body = shape->body;
	cpSegmentShape *seg = (cpSegmentShape *)shape;
	cpVect a = cpvadd(body->p, cpvrotate(seg->a, body->rot));
	cpVect b = cpvadd(body->p, cpvrotate(seg->b, body->rot));
	
	drawLine( ccp(a.x, a.y), ccp(b.x, b.y) );
}

void drawPolyShape(cpShape *shape)
{
	cpBody *body = shape->body;
	cpPolyShape *poly = (cpPolyShape *)shape;
	
	int num = poly->numVerts;
	cpVect *verts = poly->verts;
	
	CGPoint *vertices = malloc( sizeof(CGPoint)*poly->numVerts);
	if( ! vertices )
		return;
	
	for(int i=0; i<num; i++){
		cpVect v = cpvadd(body->p, cpvrotate(verts[i], body->rot));
		vertices[i] = v;
	}
	drawPoly( vertices, poly->numVerts, YES );
	
	free(vertices);
}

void drawObject(void *ptr, void *unused)
{
	cpShape *shape = (cpShape *)ptr;
	switch(shape->klass->type){
		case CP_CIRCLE_SHAPE:
			drawCircleShape(shape);
			break;
		case CP_SEGMENT_SHAPE:
			drawSegmentShape(shape);
			break;
		case CP_POLY_SHAPE:
			drawPolyShape(shape);
			break;
		default:
			printf("Bad enumeration in drawObject().\n");
	}
}

void drawCollisions(void *ptr, void *data)
{
	cpArbiter *arb = (cpArbiter *)ptr;
	for(int i=0; i<arb->numContacts; i++){
		cpVect v = arb->contacts[i].p;
		drawPoint( ccp(v.x, v.y) );
	}
}

-(void) draw
{
	[super draw];
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	cpSpaceHashEach(space->activeShapes, &drawObject, NULL);
	cpSpaceHashEach(space->staticShapes, &drawObject, NULL);
	
	cpArray *bodies = space->bodies;
	int num = bodies->num;
	
#if 1	// comment this block for better performance
	glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
	for(int i=0; i<num; i++){
		cpBody *body = (cpBody *)bodies->arr[i];
		drawPoint( ccp(body->p.x, body->p.y) );
	}
	
	glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
	cpArrayEach(space->arbiters, &drawCollisions, NULL);
#endif
}


@end
strider
coolman
Posts: 45
Joined: Fri Feb 27, 2009 7:59 am
Contact:

Re: collision detection problem

Post by coolman »

@cire,

See this thread about how to do object removal on Chipmunk collision

http://groups.google.com/group/cocos2d- ... cede600310

I'm doing:
1. remove cocos2 sprite - [self removeChild:miSprite cleanup:NO];
2. remove shape - cpSpaceRemoveShape
3. remove body - cpSpaceRemoveBody
4. free shape - cpShapeFree
5. free body - cpBodyFree

But I'm doing this after a SpaceStep (after the collision). Collision -> a Space Step -> removal

@strider,

Depending on the situation that :

Code: Select all

   cpSpaceHashEach(space->activeShapes, &drawObject, NULL);
   cpSpaceHashEach(space->staticShapes, &drawObject, NULL);
Could not be fine. Ie: If you have bullets and aliens moving, you may need to only iterate by the bullets or only by the aliens.

I'm doing this with two arrays that holds referenced to bullets and aliens, and only iterate in the needed array, not all the activeshapes. I always prefer to handle my object into an array.
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 1 guest