ekstrakt

Apply force to sprite

Recommended Posts

Hi all,

 

I'm struggling a bit to find a way to make a realistic explosion effect (physics, not visual).

 

The situation is this:

The game is a horizontal side-scrolling platformer.
I have a player that's throwing grenades.

On impact with a tile, the grenade explodes.

 

I want all enemies (sprites) within the blast to be affected by a realistic circular blast wave, pushing the enemies away in relation to how close they were to the impact point.

I have the impact vector (distance and angle from impact point), and I can calculate the impact force (closest - max force, further - less force) in relation to the blast radius, but so far I have no means to apply it to an enemy.

 

 

Some ways I can think of:

- push the enemy back by setting it's x,y, which is instantly, and not realistic

 

- apply (add) negative/positive velocity to the enemy (which will be constant, and unrealistic)

 

- create many concentric circles with center at the impact point, and over time degrade their velocity effect to 0, while having a onOverlap callback adding the velocity effect to the enemy sprite 

 

- create a circle at the explosion point, which will expand by time, and push out the sprites by collision (maybe add bounce to the enemies). But unless I use P2 physics, this will be unrealistic

 

- using

    - Phaser.Physics.Arcade.accelerateToObject(enemy, blastOrigin, -500, 0, 0)

    - Phaser.Physics.Arcade.accelerateToXY(enemy, PointFromForce, 500, 0, 0)

    - Phaser.Physics.Arcade.moveToObject(enemy, blastOrigin, -500, 0, 0)

    - Phaser.Physics.Arcade.moveToXY(enemy, PointFromForce, 500, 0, 0)

   but with all these methods the enemy continues to move indefinitely, and I don't have a way to stop it

 

 

What I'm trying to achieve is like 2 sprites colliding (with bounce), with a finite stop point, or a planet with inverse gravity (pushing bodies away).

 

 

Best aproach I can think of at the moment is to have something like deccelerateToXY(Point) function, which will stop the sprite when the point is reached.

At the moment I'm using Arcade physics, but if this can be done with P2, I will switch.

Also, note that, at the moment, the enemies don't move by themself, but when I'm done with implementing the AI, they will move (try to follow the player, run away from player, move independently ...), which will bring additional complications.

 

 

Any ideas and help are appreciated.

 

 

P.S.

Can I mix Arcade and P2 physics?

Share this post


Link to post
Share on other sites

An explosion can be thought of as a single frame velocity change on all objects in a radius of the epicentre, with the amount of change determined by the distance from the epicentre and the mass of the object. If you're using gravity and drag, the objects will react relatively realistically, and not go flying away from the explosion forever. Here's how I see an explosive force working:

  • Grab all of the objects in a predetermined radius of the explosion by looping over your game objects and using Circle.contains to see if their position lies within the circle. You could maybe make use of an overlap test with a square body of the same size as the circle to make use of the QuadTree optimisation if you have lots of objects in your world.
  • For each object, check the distance and the angle (in radians) from the explosion's centre point.
  • Using the angle and the inverse of the distance, perform some simple trigonometry to determine which direction and with what force you need to add to an object (optionally taking into account mass):
var force = (radius - distance) / mass;
object.body.velocity.x += Math.cos(angle) * force;
object.body.velocity.y += Math.sin(angle) * force;

By adding the forces rather than setting them, you alter the existing motion of objects rather than just overriding it. This means objects moving into an explosion will be less affected than objects moving away, which is desirable if realism is your thing.

The above calculations are pretty simplified in the grand scheme of things, but they should provide a pretty nice effect nonetheless. To increase the force of the explosion, you just need to increase the radius and things should react accordingly; objects at the same distance from a larger explosion will have more force applied to them. You can of course add a separate 'force' value into the explosion and the calculation which I guess could act as a multiplier, so you could make small but powerful blasts. I'll leave that to you to add if you wish! :)

Share this post


Link to post
Share on other sites

Thanks.

 

As you can read in my post

- apply (add) negative/positive velocity to the enemy (which will be constant, and unrealistic)

- create many concentric circles with center at the impact point, and over time degrade their velocity effect to 0, while having a onOverlap callback adding the velocity effect to the enemy sprite 

I considered this option (only getting the math on paper, without testing in game, which is my bad), but I wasn't aware that the velocity will degrade by time (and I still don't know why it degrades or how to control the rate, so if you have time to explain, please do, or link to the source code).

 

With this, the effect is pretty close to what I'm after. Next I need to see how will the sprites behave when they have AI (movement).

Share this post


Link to post
Share on other sites

The key here is drag. Drag reduces velocity by a constant amount over time - if you don't apply any drag, then objects will continue to hold their momentum like they're travelling in a vacuum. In real life, air resistance and surface friction are also factors, so maybe you'll want to increase the drag for all objects touching a surface, or, if using P2, use its physics materials to make surfaces have more friction. Whatever way you do it, an explosion should really be a discreet event rather than an event over time for it to look correct. You can simulate a shockwave by applying a delay based on the distance from the epicentre but make sure it's fast (real shockwaves travel at the speed of sound) otherwise again it won't look right.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.