In a game I’m developing I wanted to have some realistic explosion effects. At first, I thought I would just apply an impulse to all objects within range of the explosion. However, this created unrealistic movement in the affected objects and the objects didn’t rotate. I tried using ray casts to set points to apply the forces to create rotation. This made the explosion look more realistic and worked well enough until the explosions exploded near a static body in which case objects would sometimes be missed as they were shielded by the static body. I decided to dive in fully and use particles to represent the force of the blast.
The first thing I made was an array to store where the explosions would explode and an array to store each particle from the explosion.
1 2 |
public Array<Vector2> bombsToExplode = new Array<Vector2>(); public Array<ExplosionParticle> partys = new Array<ExplosionParticle>(); |
Next, I created the method that would be run for each explosion.
1 2 3 4 5 6 7 8 9 |
private void explodeABomb(Vector2 vector){ int numRays = ExplosionParticle.NUMRAYS; for (int i = 0; i < numRays; i++) { float angle = (i / (float)numRays) * 360 * MathUtils.degreesToRadians; Vector2 rayDir = new Vector2( (float) Math.sin(angle),(float) Math.cos(angle) ); partys. add(new ExplosionParticle(world, vector, rayDir)); // create the particle } this.explosions.add(vector); // add explosion particle effect at vector } |
I needed to create a class for the Explosion particles which would contain a reference to the body. In this class, I create a body definition and use it to create a Body. The body position is then set to the place the bomb exploded. The linear velocity is then set to give the particle a direction and force. A Fixture is then created to give the body a shape, size, weight etc, and added to the body.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
public class ExplosionParticle { public int blastPower = 100; public static final int NUMRAYS = 60; public Body body; public ExplosionParticle(World world, Vector2 vector, Vector2 rayDir){ BodyDef bd = new BodyDef(); bd.type = BodyType.DynamicBody; bd.fixedRotation = true; // rotation not necessary bd.bullet = true; // prevent tunneling at high speed bd.linearDamping = 10; // drag due to moving through air bd.gravityScale = 0; // ignore gravity bd.position.x = vector.getPosition().x; bd.position.y = vector.getPosition().y;// start at blast center rayDir.scl(blastPower); bd.linearVelocity.x = rayDir.x; bd.linearVelocity.y = rayDir.y; body = world.createBody( bd ); //create a reference to this class in the body(this allows us to loop through the world bodies and check if the body is an Explosion particle) body.setUserData(this); CircleShape circleShape = new CircleShape(); circleShape.setRadius(0.05f); // very small FixtureDef fd = new FixtureDef(); fd.shape = circleShape; fd.density = 120 / (float)NUMRAYS; // very high - shared across all particles fd.friction = 0; // friction not necessary fd.restitution = 0.99f; // high restitution to reflect off obstacles fd.filter.groupIndex = -1; // particles should not collide with each other body.createFixture( fd ); } } |
The Box2D world would soon fill up with particles unless they are removed once they’ve finished expelling all their energy.
1 2 3 4 5 6 7 |
for(ExplosionParticle party: partys){ if(Math.abs(party.body.getLinearVelocity().x) < 5f && Math.abs(party.body.getLinearVelocity().y) < 5f){ world.destroyBody(party.body); partys.removeValue(party, true); } } |
In my contact listener I have this code to tell the game model to make an explosion
1 |
parent.createBlast(bomb); |
which runs this method in my Game Model
1 2 3 4 |
public void createBlast(Bomb bomb) { bombsToExplode.add(bomb.body.getPosition()); bomb.isDead = true; // sets the bomb to dead so it can be removed outside of the box2d physics calculations } |
This is how the explosions look when using the box2D debug renderer.
[embedyt] http://www.youtube.com/watch?v=iN6Faut9g0A[/embedyt]
Further Reading:
Every weekend i used to pay a quick visit this web site, for the reason that
i want enjoyment, since this this web page conations truly pleasant funny
data too.
I’ve been exploring for a bit for any high-quality articles oor
weblog posts on this kind of space . Exploring in Yahoo I at last stumbled upon this
website. Studying this information So i am happy to express that
I’ve a very excellent uncanny feeling I discovered
just what I needed. I such a lot definitely will make sure to don?t
faill to remember this web site and give it a look regularly.
Every weekend i used to pay a quick visit this web site, for the reason that
i want enjoyment, since this this web page conations truly pleasant funny
data too
Saved as a favorite, I love your site!
Magnificent website. Ⅼots of helpful infoгmation here.
Very interesting.
Damn, I wiѕh I could think of somеthing smart ⅼike that!
Тhіs іs one օf the Ƅest thingѕ I haѵᥱ rеad thіs mоnth.
ӏs it mʏ computeer оr somebody else too haѕ the
issue with viewing thiѕ website ᥙnder chrome?
I am sure this paragraph has touched all the internet visitors,
its really really nice piece of writing on building up new blog.
I don’t realize the way i wound up here, nevertheless i thought this post was good.
I don’t know your identiity but certainly you happen to be going to a famous blogger if you usually are not
already 😉 Cheers!
Howdy, I do think your website may be having web browser compatibility problems.
Whenever I look at your blog in Safari,
it looks fine however when opening in Internet Explorer, it’s got some overlapping issues.
I simply wanted to provide you with a quick heads up!
Aside from that, wonderful site!
this is filled with bots, I just wanna be nice and leave a comment for a future visitor to see. Love from germany.