September 23, 2009 3

Box2D – Quick bomb explosion / implosion.

By admin in Uncategorized

So I wanted to apply a bomb, to my small physics based app I’m creating. However I found out that in Box2D, there’s no built in method to do that. Which after reading a little more into it, makes sense.

So what you do is apply force to all the objects yourself, OR you can throw out X number of Rays (bullets) – and they’ll hit the objects going outward but that’s a bit more expensive for the iPhone. Maybe it’s not, i don’t know but this is what I did.

It’s quick, and doesn’t take into account the proper fall of (inverse square of the distance). I’m not great at writing tutorials, so I’ll post this for now and edit/update it based any questions I receive in the comments.

// Pos comes from the ccTouchesEnded function. I've already converted it to Cocos2D coordinates. 
-(void) launchBomb:(CGPoint)pos 
{
	BOOL doSuction = YES; // Very cool looking implosion effect instead of explosion.
 
//In Box2D the bodies are a linked list, so keep getting the next one until it doesn't exist.
	for (b2Body* b = _world->GetBodyList(); b; b = b->GetNext()) 
	{
//Box2D uses meters, there's 32 pixels in one meter. PTM_RATIO is defined somewhere in the class.
		b2Vec2 b2TouchPosition = b2Vec2(pos.x/PTM_RATIO, pos.y/PTM_RATIO);
		b2Vec2 b2BodyPosition = b2Vec2(b->GetPosition().x, b->GetPosition().y);
 
//Don't forget any measurements always need to take PTM_RATIO into account 
		float maxDistance = 9 // In your head don't forget this number is low because we're multiplying it by 32 pixels;
		int maxForce = 22;
		CGFloat distance;
		CGFloat strength;
		float force;
		CGFloat angle;
 
		if(doSuction) // Get sucked towards the mouse
		{
			// Get the distance, and cap it
			distance = b2Distance(b2BodyPosition, b2TouchPosition);
			if(distance > maxDistance) distance = maxDistance - 0.01; 
			// Get the strength
			//strength = distance / maxDistance; // Uncomment and reverse these two. and ones further away will get more force instead of less 
			strength = (maxDistance - distance) / maxDistance; // This makes it so that the closer something is - the stronger, instead of further
			force  = strength * maxForce;
 
			// Get the angle
			angle = atan2f(b2TouchPosition.y - b2BodyPosition.y, b2TouchPosition.x - b2BodyPosition.x);		
			//NSLog(@" distance:%0.2f,force:%0.2f", distance, force);
			// Apply an impulse to the body, using the angle
			b->ApplyImpulse(b2Vec2(cosf(angle) * force, sinf(angle) * force), b->GetPosition());
		}
		else // To go towards the press, all we really change is the atanf function, and swap which goes first to reverse the angle
		{
			distance = b2Distance(b2BodyPosition, b2TouchPosition);
			if(distance > maxDistance) distance = maxDistance - 0.01;
 
			// Normally if distance is max distance, it'll have the most strength, this makes it so the opposite is true - closer = stronger
			strength = (maxDistance - distance) / maxDistance; // This makes it so that the closer something is - the stronger, instead of further
			force = strength * maxForce;
			angle = atan2f(b2BodyPosition.y - b2TouchPosition.y, b2BodyPosition.x - b2TouchPosition.x);	
			//NSLog(@" distance:%0.2f,force:%0.2f,angle:%0.2f", distance, force, angle);
			// Apply an impulse to the body, using the angle
			b->ApplyImpulse(b2Vec2(cosf(angle) * force, sinf(angle) * force), b->GetPosition());
		}
	}	
}

That’s it – it’s quick and dirty, and probably has some mistakes so feel free to point them out.

Tags:

3 Responses to “Box2D – Quick bomb explosion / implosion.”

  1. Joe says:

    Love your articles. Keep up the great work.

  2. Nick says:

    Thanks for the awesome sample code. Just FYI for anyone that arrives here from google: the current Box2D API method is b->ApplyLinearImpluse with the same arguments.

  3. admin says:

    Np Nick, thanks for the heads up.
    This is the number one point of entry for this blog, so im sure people will find that info useful.

    I been meaning to update this actually… so maybe ill do that now – cus that doSuction conditional really only differs by 1 line

Leave a Reply

Powered by WP Hashcash

Spam protection by WP Captcha-Free