Search code examples
luacollision-detection

How do I detect a collision with a poly line in the lua love engine?


I am using the lua love engine to make a simple game. However, im having a little trouble with collision.

I have a polyline between a set of points (representing the rocky ground) and a box I need to collide with it, but I cant think of an easy implementation.

love.graphics.line( 0,60, 100,70, 150,300, 200,230, 250,230, 300,280, 350,220, 400,220, 420,150, 440,140, 480,340 )

If anyone could help with code snippets or advice, it would be much appreciated.


Solution

  • You need to create a more abstract representation of the ground, from which you can generate both the line for the graphics, and the body for the physics.

    So for example:

    --ground represented as a set of points
    local ground = {0,60, 100,70, 150,300, 200,230, 250,230, 300,280, 350,220, 400,220, 420,150, 440,140, 480,340}
    

    This may not be the best representation, but I will continue with my example.

    You now have a representation of the ground, now you a way of converting that something that your physics can understand (to do the collision) and something that your graphical display can understand (do draw the ground). So you declare two functions:

    --converts a table representing the ground into something that
    --can be understood by your physics.
    --If you are using love.physics then this would create 
    --a Body with a set PolygonShapes attached to it.
    local function createGroundBody(ground)
        --you may need to pass some additional arguments,
        --such as the World in which you want to create the ground.
    end
    
    --converts a table representing the ground into something
    --that you are able to draw.
    local function createGroundGraphic(ground)
        --ground is already represented in a way that love.graphics.line can handle
        --so just pass it through.
        return ground
    end
    

    Now, putting it all together:

    local groundGraphic = nil
    local groundPhysics = nil
    love.load()
        groundGraphic = createGroundGraphic(ground)
        physics = makePhysicsWorld()
        groundPhysics = createGroundBody(ground)
    
    end
    
    love.draw()
        --Draws groundGraphic, could be implemented as
        --love.graphics.line(groundGraphic)
        --for example.
        draw(groundGraphic)
        --you also need do draw the box and everything else here.
    end
    
    love.update(dt)
        --where `box` is the box you have to collide with the ground.
        runPhysics(dt, groundPhysics, box)
        --now you need to update the representation of your box graphic
        --to match up with the new position of the box.
        --This could be done implicitly by using the representation for physics
        --when doing the drawing of the box.
    end
    

    Without knowing exactly how you want to implement the physics and the drawing, it is hard to give more detail than this. I hope that you use this as an example of how this code could be structured. The code that I have presented is only a very approximate structure, so it will not come close to actually working. Please ask about anything that I have been unclear about!