[SOLVED] Physics - Detect Force of Object Hitting

SirLagsalott

Member
I'm currently programming a physics-based game in GameMaker Studio (I'm using the Early Access 1.99.525). I have a "wood" object that is destructible, by the player and by hitting other objects with force. However, the current force-detection method is flawed.

Code:
``````if abs(phy_linear_velocity_x) + abs(phy_linear_velocity_y) > 50 then {
woodhealth = woodhealth - ((abs(phy_linear_velocity_x) + abs(phy_linear_velocity_y))/32)
}``````
This is the code in the collision event for another instance of wood. Let's say X is the wood executing this code, and Y is the object hitting X. It calculates both their speeds at that moment and applies damage to each of them. The issue is that it is using X's speed to calculate how much damage will be dealt, instead of taking Y's speed and applying damage accordingly. How do I use code to call the properties of the object that just hit it?

sp202

Member
If I understand correctly you want to access the velocity of the object colliding with X, in which case I believe the "other" keyword refers to the other object in a collision event, hence the velocity of Y would be other.velocity within the collision event with Y inside object X.

SirLagsalott

Member
Thank you. Didn't know it'd be that easy.

No problem.

flyingsaucerinvasion

Member
Hey, I'm assuming that box2d works the same in 2 than it does in 1.4, so my answer will be based on that.

First of all you need to know that at the time of the collision event, the speed have already been altered by the collision.

Therefore you must have a couple of variables keep track of what the speed vector was previous to the collision. I think you can do that by setting the variables equal to phy_speed_x and phy_speed_y in the end step event. I'm not totally sure when collision events fire, so you might want to look into that if you want totally accurate results. Becuase accelerations that happened during this step might not have applied yet if the collision event fires first.

Anyway, to get the force of the collision, all you need to know is what your change in velocity was. And you can get that by measuring the distance between your previous velocity vector and your vector after the collision. And you should also take into account the mass of the instance that has been moved by the collision, becuase it will take more force to change a more massive object the same speed over the same length of time.

var _force = point_distance(old_speed_x, old_speed_y, phy_speed_x, phy_speed_y) * phy_mass;

Jezla

Member
I'm not totally sure when collision events fire, so you might want to look into that if you want totally accurate results. Becuase accelerations that happened during this step might not have applied yet if the collision event fires first.
If I'm not mistaken, the collision event for physics objects fires every iteration of the physics world, so if physics world iterations are set to 60, then the collision event fires 60 times per step that the instances are colliding. This is what I seemed to notice when working on the landing collisions for Cave Lander.

P

Paul Holt

Guest
Hey, I'm assuming that box2d works the same in 2 than it does in 1.4, so my answer will be based on that.

First of all you need to know that at the time of the collision event, the speed have already been altered by the collision.

Therefore you must have a couple of variables keep track of what the speed vector was previous to the collision. I think you can do that by setting the variables equal to phy_speed_x and phy_speed_y in the end step event. I'm not totally sure when collision events fire, so you might want to look into that if you want totally accurate results. Becuase accelerations that happened during this step might not have applied yet if the collision event fires first.

Anyway, to get the force of the collision, all you need to know is what your change in velocity was. And you can get that by measuring the distance between your previous velocity vector and your vector after the collision. And you should also take into account the mass of the instance that has been moved by the collision, becuase it will take more force to change a more massive object the same speed over the same length of time.

var _force = point_distance(old_speed_x, old_speed_y, phy_speed_x, phy_speed_y) * phy_mass;
No, this wont work if the object is spinning. Imagine a fast-spinning top hitting another top, making a big change to angular momentum. The impulse might be very high, but the change in linear velocity would be very low.

I wish there was a way of determining the magnitude of the collision impulse, but all we get is a unit vector. Would it be so hard to also supply the impulse vector for the collision?

flyingsaucerinvasion

Member
@Paul Holt?

Are you sure? According to what I read, and the tests that I'm doing, the change in linear velocity is always the same when the same magnitude of force is applied, no matter where it is applied. Is there something different about collisions that would change that?