I'm trying to create a bomb explosion in Farseer. I created a circle for the bomb. However, if the bomb explodes, the objects (bodies) that are around it should fly away because they're pushed back by the enormous force of the explosion. I'm not sure how to create that force, though - how can I do it?
-
\$\begingroup\$ It's worth pointing out that Farseer comes with a sample that implements explosions. It's "AdvancedDemo5" (in the current source). It's similar to the proximity method in Classic Thunder's excellent answer, only less-sophisticated (a fixed-magnitude impulse within an AABB). \$\endgroup\$– Andrew RussellCommented Mar 28, 2014 at 2:01
2 Answers
I would recommend checking out the explosion iforce2d page. It does a great job going over the various ways of handling explosions with the performance vs. accuracy tradeoffs. It goes over 3 methods which I will summarize here. So this is simply me summarizing information I found while researching and none of it is my own work.
Also you want to apply impulses here not forces. To understand why read this.
The Proximity method
This is the same method that Byte56 goes over in his answer. The concept is simple. Have an explosion point and apply an impulse in the opposite direction away from the point which will affect all objects with a strength based on their distance away.
Pros:
- Very fast
- Easy to code.
Cons:
- Explosions pass through immovable objects and static bodies.
- Objects that are in the influence area of the blast may be skipped if you only check the distance to the center of mass.
- Surface area is not taken into account.
- Everything is affected at once.
The Raycast method
This one is simple enough, cast out rays from the origin of your explosion and apply impulses when they collide into an object with an impulse dictated by the distance.
Pros:
- Less performance intensive than the projectiles method.
- Explosion blocked by objects.
- Surface area taken into account.
Cons:
- Everything is affected at once.
- The larger the explosion the more rays you need to make sure the explosion affects everything.
- More performance intensive than the proximity method.
The Particle method
My personal favorite. Similar to the RaySasting method but instead of rays you leverage the physics engine and spit out small pellets that interact with your scene.
Pros:
- Extremely easy code-wise. Generate the balls and apply an impulse to each one. You have no code to write per tick. Just have a timer that goes though and disables/resets the bodies after the explosion is complete.
- Explosion is blocked by objects.
- Surface area is taken into account.
- Explosion reflects off of surfaces.
- Objects further from the blast respond to it more slowly.
- You can use the balls as the basis for generating partials allowing your effects to accurately reflect the explosions impact.
Cons:
- Adds per-tick complexity.
-
5\$\begingroup\$ Very nice answer. I especially like the particle method. Seems like it would make it more difficult to get a powerful explosion though. Is it trivial to make the particles higher mass? \$\endgroup\$– HouseCommented Mar 27, 2014 at 22:01
-
1\$\begingroup\$ It is trivial to effect all the physical aspects of the particles, the most relevant being density, velocity, and the damping. Cranking the density way up and setting a high velocity would let you make a comically violent explosion. \$\endgroup\$ Commented Mar 27, 2014 at 22:09
-
\$\begingroup\$ Did you make explosion particles decelerate on purpose, or is just the entire animation stopping. It would make sense to add constant friction to the particles. \$\endgroup\$– thisCommented Mar 28, 2014 at 0:47
-
\$\begingroup\$ @self Box2D allows you to add liner damping to an object which slows it down lineally at a certain rate, this is the technique used in the gif. \$\endgroup\$ Commented Mar 28, 2014 at 1:16
-
1\$\begingroup\$ Excellent answer :) I would add one more pro to the last method, in that you could use the pellet positions to draw some nice-looking smoke or dust. \$\endgroup\$– iforce2dCommented Apr 3, 2014 at 12:20
- Select all the objects within the bomb's radius of influence.
- For each object
- Use the object position and the center of the explosion to calculate the vector of the impulse. Something like
normalize(object - center)
. - Use the distance from the center of the bomb to the object to calculate the magnitude of the impulse. Something like
(object - center).length
- Apply an impulse to the object using the vector and magnitude found in the previous steps.
- Use the object position and the center of the explosion to calculate the vector of the impulse. Something like
As for calculating the magnitude you can start of with simple linear falloff, then move to other formulas if you don't like the results.
-
\$\begingroup\$ Forces are for when you want to influence an object over time which isn't the situation here. It would be more correct to apply an impulse. \$\endgroup\$ Commented Mar 27, 2014 at 21:55
-
\$\begingroup\$ Sorry, I said force, but linked to impulse. \$\endgroup\$– HouseCommented Mar 27, 2014 at 21:59