Collisions just don't want to work

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Jipjang
Prole
Posts: 6
Joined: Fri May 24, 2024 7:04 am

Collisions just don't want to work

Post by Jipjang »

I've been trying for multiple hours trying to get my physics engine to work, with thing not passing through eachother, not getting stuck on edges and all that annoying stuff, but everytime I am so close yet so far, one problem fixed, two other problems pop up. Please help, I am not going to use libraries like bump, because I already built my engine on top of my AABB handling, which already has incredible performance.

For context, variables like math.abs, math.sign(which is custom) and math.huge are cached above to abs, sign and huge.

Code: Select all

--set up the local variables
    local totalxov, totalyov, minxov, minyov, minxov_ent, minyov_ent
--A function to setup the total overlap, minimum overlap and getting the relevant entity
    local function collide_with_ent(ent)
        if ent.solid ~= "full" then return end

        local ox, oy = ent.x, ent.y
        local ow, oh = ent.width, ent.height
        local ohw, ohh = ow/2, oh/2

        local myx, myy = self.x, self.y
        local myw, myh = self.width, self.height
        local myhw, myhh = myw/2, myh/2

        local oleft, oright, otop, obottom = ox-ohw, ox+ohw, oy+ohh, oy-ohh
        local myleft, myright, mytop, mybottom = myx-myhw, myx+myhw, myy+myhh, myy-myhh

        if myx>ox then
            local xov = myleft-oright
            if abs(xov) < abs(minxov or huge) then
                minxov_ent = ent
                minxov = xov
            end

            totalxov = totalxov + abs(xov)
        else
            local xov = myright-oleft
            if abs(xov) < abs(minxov or huge) then
                minxov_ent = ent
                minxov = xov
            end

            totalxov = totalxov + abs(xov)
        end
        if myy<oy then
            local yov = mytop-obottom
            if abs(yov) < abs(minyov or huge) then
                minyov_ent = ent
                minyov = yov
            end

            totalyov = totalyov + abs(yov)
        else
            local yov = mybottom-otop
            if abs(yov) < abs(minyov or huge) then
                minyov_ent = ent
                minyov = yov
            end

            totalyov = totalyov + abs(yov)
        end
    end
    local fix, tile
    
--Move on the X axis
    self.x = self.x + vx
--Reset wall detection
    self.wall = 0
--Collide with tiles on the X axis (Tiles work perfectly, it's just entities)
    fix, tile = self:is_touching_solid("x")
--When we have a collision, collide
    if fix ~= 0 then
        self.x = self.x + fix * 1.01
        if sign(vx) == -sign(fix) then
            vx = 0
            self.wall = sign(fix)
        end
    end

--Now my biggest enemy: entity collisions, the reason this is hard, is because I don't know the order:
--there are solid physics-based entities like munchers,
--so we can't seperate the solid and physics entities.
--I am currently testing the physics in the player, which always runs after the entities.
--So I think it works, but then I implement the engine into the entities, and it all breaks :(

--Reset the total overlap
    totalxov, totalyov = 0, 0
--Reset the minimum overlap
    minxov, minyov = nil, nil
--Handle entity collisions
    for _, ent in ipairs(ENTITIES) do
        if ent:colliding_with(self) then collide_with_ent(ent) end
    end

--When we collided
    if minxov then
--Move out
        self.x = self.x - minxov
--When we actually collided on the X axis, reset vx
        if totalxov < totalyov then
            vx = 0
            self.wall = -sign(minxov)
        end
    end

--Do the same on the Y axis
    self.y = self.y + vy
    airtime = airtime + 1
    fix, tile = self:is_touching_solid("y")
    if fix ~= 0 then
        self.y = self.y + fix * 1.01
        if sign(vy) == -sign(fix) then
            if fix > 0 then
                if airtime > 1 then
                    squish = -vy * 0.04
                end
                flip = 0
                airtime = 0
            end
            if fix < 0 then
                if tile then tile:hit(1) end
                squish = 0.4
            end
    
            vy = 0
        end
    end

    totalxov, totalyov = 0, 0
    minxov, minyov = nil, nil
    for _, ent in ipairs(ENTITIES) do
        if ent:colliding_with(self) then collide_with_ent(ent) end
    end

    if minyov then
        self.y = self.y - minyov
        if totalyov < totalxov then
            if minyov < 0 then
                if airtime > 1 then
                    squish = -vy * 0.04
                end
                flip = 0
                airtime = 0
                self.x, self.y = self.x + minyov_ent.vx, self.y + minyov_ent.vy
            end
            if minyov > 0 then
                squish = 0.4
            end

            vy = 0
        end
    end
User avatar
marclurr
Party member
Posts: 164
Joined: Fri Apr 22, 2022 9:25 am

Re: Collisions just don't want to work

Post by marclurr »

There's not really enough to go off of here. If you need arbitrary rectangle collision resolution I really would recommend bump, but if you're determined to do it all yourself this is a good resource https://m.youtube.com/watch?v=8JJ-4JgR7 ... N0YW5nbGVz
Jipjang
Prole
Posts: 6
Joined: Fri May 24, 2024 7:04 am

Re: Collisions just don't want to work

Post by Jipjang »

Thank you, what video really helped me!
Jipjang
Prole
Posts: 6
Joined: Fri May 24, 2024 7:04 am

Re: Collisions just don't want to work

Post by Jipjang »

marclurr wrote: Sun Mar 16, 2025 4:23 am There's not really enough to go off of here. If you need arbitrary rectangle collision resolution I really would recommend bump, but if you're determined to do it all yourself this is a good resource https://m.youtube.com/watch?v=8JJ-4JgR7 ... N0YW5nbGVz
I gave up and decided to use bump, but it also bugs out when I have moving blocks. I just set vx and vy to 0 to test, I already tried adding other.vx and vy to my position, but that also doesn't work. I use the slide filter, but when I stand still, moving blocks just pass through me, I also tried using cross and making a custom response by setting my position to the contact position (with some added code to slide along the floor), which almost worked, but I could still go through walls when moving away from them.

Code: Select all

    self.x = self.x + vx
    col, fix = self:is_touching_solid("x")
    if col then
        self.x = self.x + fix * 1.01
        if sign(vx) == -sign(fix) then
            self.wall = sign(fix)
            vx = 0
        end
    end

    self.y = self.y + vy
    col, fix = self:is_touching_solid("y")
    if col then
        self.y = self.y + fix * 1.01
        if sign(vy) == -sign(fix) then
            if fix > 0 then
                if airtime > 1 then
                    squish = -vy * 0.04
                end
                flip = 0
                airtime = 0
            end
            if fix < 0 then
                squish = 0.4
            end
            vy = 0
        end
    end

--This is just world:move. the function right here | just gets called in the loop through all collisions. Nx and ny are the normal, cx and cy are the contact point.
--                                                 V
    MOVERECT_AND_RESOLVE(self, self.x, self.y, function(other, nx, ny, cx, cy)
        if other.solid ~= "full" then return end

        vx, vy = 0, 0
    end)
User avatar
marclurr
Party member
Posts: 164
Joined: Fri Apr 22, 2022 9:25 am

Re: Collisions just don't want to work

Post by marclurr »

Would be happy to do a bit of debugging (and sure others would too) but would ideally need the full .love attached so we can understand the flow better. There's just not enough of your program there to let us give any useful advice
RNavega
Party member
Posts: 464
Joined: Sun Aug 16, 2020 1:28 pm

Re: Collisions just don't want to work

Post by RNavega »

For reference, there's yet another AABB collision routine in here:
viewtopic.php?t=96288
Post Reply

Who is online

Users browsing this forum: Semrush [Bot] and 2 guests