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; // Why do i want to use CGFloat vs float - I'm not sure, but this mixing seems to work fine for this little test.
CGFloat strength;
float force;
CGFloat angle;
if(doSuction) // To go towards the press, all we really change is the atanf function, and swap which goes first to reverse the angle
{
// 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
{
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.
Hopefully it helps someone.
-Mario
http://learningiphone.com
http://onedayitwillmake.com