4ian / GDevelop

🎮 Open-source, cross-platform 2D/3D/multiplayer game engine designed for everyone.
https://gdevelop.io
Other
10.99k stars 857 forks source link

Add new condition/expression to find the impact speed of a physics collision #4226

Open tristanbob opened 2 years ago

tristanbob commented 2 years ago

Description

In a physics game, you might want to apply damage, points, or sound and visual effects based on the force of the impact.

The speed of the impact should be made available to the user in an expression and condition.

Solution suggested

function preSolve(contact)
  local x1, y1, x2, y2 = contact:getPositions()
  if x1 and y1 then
    local f1, f2 = contact:getFixtures()
    local b1 = f1:getBody()
    local b2 = f2:getBody()
    -- Campbell's method
    local lvx1, lvy1 = b1:getLinearVelocityFromWorldPoint(x1, y1)
    local lvx2, lvy2 = b2:getLinearVelocityFromWorldPoint(x1, y1)
    -- velocity difference vector
    local dvx, dvy = lvx1 - lvx2, lvy1- lvy2
    -- impact speed (in Meters per second)
    local nx, ny = contact:getNormal()
    local impactSpeed = dvx*nx + dvy*ny -- dot product

Reference: https://2dengine.com/?p=box2d#What_is_the_relative_velocity_at_the_moment_of_collision

tristanbob commented 1 year ago

This excellent article talks about the ways to use physics to make a platformer game. https://bhopkins.net/pages/mmphysics/

The section on "Crushing Force" is relevant to the proposed feature described in this issue..

In Box2D's PostSolve for collisions, we can access the contact impulse. 
This can be used to determine how much force is being applied to our
character and if they should take damage from being crushed. 
Each frame, all impulses are added together and tracked over time. 
This is important because a collision might apply its force over multiple
frames depending on exactly how the objects collide.