Is it possible to get the force of a collision between two objects in Love2D/Box2D? If so, how?

  • \$\begingroup\$ rigidbody.velocity.magnitude is a velocity, not a force. And you can't get the force of a collision from the velocity of one object, you need information about the other object as well. Do you want to know how to get the velocity, or the force? And when do you want to get it? \$\endgroup\$ – MichaelHouse Jan 1 '14 at 16:51
  • \$\begingroup\$ @Byte56 ok, thanks, I want to to get the force of the collision. \$\endgroup\$ – CharlesL Jan 1 '14 at 17:43

You have access to the b2ContactImpulse in the PostSolve callback on the b2ContactListener. The normalImpulses field on b2ContactImpulse holds an impulse applied to both bodies in the direction of the contact normal.

An impulse is calculated as a change in velocity times the mass of the object, so the normalImpulses well describes how hard the two fixtures hit each other. Given the same relative velocity between two fixtures, the greater the sum of the masses of the fixtures, the greater the normalImpulses.

An impulse is equal to a force acting on an object over a period of time, so if you need to calculate the actual force, you can divide the impulse by the frame time you passed to the Step function and you should get a reasonable assessment of the actual force acting on the two objects, though since i don't understand the inner workings of Box2D, i don't know how accurate this assessment is. If you're just interested in gauging the force of impact, not in the strict physics sense, then using an impulse is just as effective.


World:setCallbacks( beginContact, endContact, preSolve, postSolve ) may solve your problem.

The postSolve function receive two fixtures and a Contact object (https://love2d.org/wiki/Contact).

A very good article: https://love2d.org/wiki/Tutorial:PhysicsCollisionCallbacks


You can use normalimpulse in postSolve() callback.

Here's the example:

force = ""
function love.load()
    world = love.physics.newWorld(0, 200, true)
        world:setCallbacks(beginContact, endContact, preSolve, postSolve)

    ball = {}
        ball.b = love.physics.newBody(world, 400,200, "dynamic")
        ball.s = love.physics.newCircleShape(50)
        ball.f = love.physics.newFixture(ball.b, ball.s)
        ball.f:setRestitution(0.4)    -- make it bouncy
    static = {}
        static.b = love.physics.newBody(world, 400,400, "static")
        static.s = love.physics.newRectangleShape(200,50)
        static.f = love.physics.newFixture(static.b, static.s)

    text       = ""   -- we'll use this to put info text on the screen later
    persisting = 0    -- we'll use this to store the state of repeated callback calls

function love.update(dt)

    if love.keyboard.isDown("right") then
        ball.b:applyForce(1000, 0)
    elseif love.keyboard.isDown("left") then
        ball.b:applyForce(-1000, 0)
    if love.keyboard.isDown("up") then
        ball.b:applyForce(0, -5000)
    elseif love.keyboard.isDown("down") then
        ball.b:applyForce(0, 1000)

    if string.len(text) > 768 then    -- cleanup when 'text' gets too long
        text = ""

function love.draw()
    love.graphics.circle("line", ball.b:getX(),ball.b:getY(), ball.s:getRadius(), 20)
    love.graphics.polygon("line", static.b:getWorldPoints(static.s:getPoints()))

    love.graphics.print(text, 10, 10)

    love.graphics.print(force, 100, 400)

function beginContact(a, b, coll)
    x,y = coll:getNormal()
    text = text.."\n"..a:getUserData().." colliding with "..b:getUserData().." with a vector normal of: "..x..", "..y

function endContact(a, b, coll)
    persisting = 0
    text = text.."\n"..a:getUserData().." uncolliding with "..b:getUserData()

function preSolve(a, b, coll)
    if persisting == 0 then    -- only say when they first start touching
        text = text.."\n"..a:getUserData().." touching "..b:getUserData()
    elseif persisting < 20 then    -- then just start counting
        text = text.." "..persisting
    persisting = persisting + 1    -- keep track of how many updates they've been touching for

function postSolve(a, b, coll, normalimpulse, tangentimpulse)
    force = normalimpulse

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.