Page 1 of 1

detecting collisions only with a certain force

Posted: Fri Oct 21, 2011 7:32 am
by ashkanys
HI Fellows,

I develop a game on iphone that has some similitude with angry birds although different
I use space manager v0.7
i have block piled on each other and i would like to detect impacts between this blocks
i cannot add the regular callbacks for each blocks between them because they touch each other and i would have multiple continuous callbacks calls to treat that would slow down the game
i would like to detect collisions between blocks only if the impact force is over a determined threshold.
In that case if blocks fall on each other i could make them break.
I know it is possible with box2D as angry birds do it.
I would like to know if there is a similar solution with chipmunk

Many thanks and regards,

Benoit

Re: detecting collisions only with a certain force

Posted: Fri Oct 21, 2011 9:00 am
by slembcke
Yes, create a post-solve callback between the blocks and check the impact force. I have an Objective-C example on the downloads page called Angry Chipmunks that is vaguely similar:
http://chipmunk-physics.net/downloads.php

Basically it uses cpArbiterIsFirstContact() to check if it's the first frame two objects have hit each other. If it is, then it calculates the impact force and uses that to apply damage.

Code: Select all

static inline void BreakableApplyDamage(BreakableBox *box, cpArbiter *arb, GameWorld *self){
	if(cpArbiterIsFirstContact(arb)){
		// Divide the impulse by the timestep to get the collision force.
		cpFloat impact = cpvlength(cpArbiterTotalImpulse(arb))/FIXED_TIMESTEP;
		
		if(impact > 1.0f){
			box.strength -= impact/500.0f;
			if(box.strength < 0.0f){
				// Create the broken chunks and add them to the GameWorld.
				BrokenBox *broken = [[BrokenBox alloc] initFromBox:box];
				[self add:broken];
				[broken release];
				
				// If you broke the goal box you lose!
				if([box isKindOfClass:[GoalBox class]]) [self scheduleRestart];
				
				[self remove:box];
			}
		}
	}
}

// This is an Objective Chipmunk callback.
- (void)PostSolve_Default_BreakableBox:(cpArbiter *)arbiter space:(ChipmunkSpace*)space
{
	CHIPMUNK_ARBITER_GET_SHAPES(arbiter, unused, box);
	BreakableApplyDamage(box.data, arbiter, self);
}
Don't worry about calling collision functions to much. Realize that Chipmunk runs a lot of math for each collision pair it finds. Yeah, you might run a few hundred or maybe a few thousand of them per frame, just don't do anything really expensive in them like loading data from disk or calculate pi to a million digits.

Re: detecting collisions only with a certain force

Posted: Fri Oct 21, 2011 8:32 pm
by ashkanys
Many thanks Slembcke, i'll try that