AABB collision between player and multiple boxes

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
User avatar
NoreoAlles
Party member
Posts: 107
Joined: Mon Jan 03, 2022 5:42 pm

AABB collision between player and multiple boxes

Post by NoreoAlles »

Hey, i want to make a game where you have blocks wich can be broken an build so the player has to move over them smothly. I was asking about this issue yesterday, when i was told that the Box2d engine isnt the best for this task. So i then dove into AABB collision and got it working. So now, i have a collide() function wich takes x1, y1, width1, height1 and x2, y2, width2, height2 and returns a bool. I then made a for loop that goes thru the blocks in my Map and calls the collide functoin on them and the player. I did something like this pseudo code, to determine what side / where the collison took place:

Code: Select all

for blocks do 
	if collision(player, box) then
		if player.y > box.y then 
			hit ceiling
		elseif player.y < box.y then 
			hit ground
		elseif player.x > box.x then 
			stop moving on x axsis
		elseif player.x < box.x then 
			stop moving on x axsis
		end
	end
end
I then noticed it wouldnt let me move side to side because it check for all of the blocks, wich ended with the player not being able to move horizontally, wich makes sense.
I then thought i should only check for the two nearest blocks, so it wouldnt happen and even tho im not sure if it would work started trying.
then for what ever reason, it told me that the function arguments in this function were nil or tabel values, wich doesnt make sense, so now i am completly stuck.

Code: Select all

function distance ( x1, y1, x2, y2 )
  local dx = x1 - x2
  local dy = y1 - y2
  return math.sqrt ( dx * dx + dy * dy )
end
I am completly stuck and just want to move from physics
"Why do they call it oven when you of in the cold food of out hot eat the food?" - Jon Arbuckle
User avatar
Jeeper
Party member
Posts: 611
Joined: Tue Mar 12, 2013 7:11 pm
Contact:

Re: AABB collision between player and multiple boxes

Post by Jeeper »

NoreoAlles wrote: Wed Apr 13, 2022 6:17 pm Hey, i want to make a game where you have blocks wich can be broken an build so the player has to move over them smothly...
Your AABB is wrong, that's why it doesn't work. It will always return true.

Below is a proper implementation of it, note how all 4 conditions need to be true in order for a collision to occur.

Code: Select all

function aabb(a, b)
	return (a.x < b.x + b.width and a.x + a.width > b.x and a.y < b.y + b.height and b.y < a.y + a.height)
end
Next you need to either:
A) Look into the "future" by checking the next position of the player vs the boxes, and only moving if it's clear

or B) "Solve" the collision by moving the player out of it.

Otherwise your player will notice a collision, and won't be able to move out of the colliding state.
User avatar
NoreoAlles
Party member
Posts: 107
Joined: Mon Jan 03, 2022 5:42 pm

Re: AABB collision between player and multiple boxes

Post by NoreoAlles »

Jeeper wrote: Wed Apr 13, 2022 7:26 pm
NoreoAlles wrote: Wed Apr 13, 2022 6:17 pm Hey, i want to make a game where you have blocks wich can be broken an build so the player has to move over them smothly...
Your AABB is wrong, that's why it doesn't work. It will always return true.

Below is a proper implementation of it, note how all 4 conditions need to be true in order for a collision to occur.

Code: Select all

function aabb(a, b)
	return (a.x < b.x + b.width and a.x + a.width > b.x and a.y < b.y + b.height and b.y < a.y + a.height)
end
Next you need to either:
A) Look into the "future" by checking the next position of the player vs the boxes, and only moving if it's clear

or B) "Solve" the collision by moving the player out of it.

Otherwise your player will notice a collision, and won't be able to move out of the colliding state.
JO, your tutoriel series was the thing that made me do some actual stuff. My collision detection works fine, atleast i think it does.

Code: Select all

function collide(x1, y1, width1, height1, x2, y2, width2, height2 )
    if x1 > x2 + width2 or x2 > x1 + width1 then 
        return false 
    end

    if y1 > y2 + width2 or y2 > y1 + height1 then 
        return false 
    end
    print("collsion")
    return true
end
"Why do they call it oven when you of in the cold food of out hot eat the food?" - Jon Arbuckle
User avatar
Jeeper
Party member
Posts: 611
Joined: Tue Mar 12, 2013 7:11 pm
Contact:

Re: AABB collision between player and multiple boxes

Post by Jeeper »

NoreoAlles wrote: Wed Apr 13, 2022 6:17 pm JO, your tutoriel series was the thing that made me do some actual stuff. My collision detection works fine, atleast i think it does.
I'm sorry, I misread your code thinking

Code: Select all

if player.y > box.y then 
			hit ceiling
		elseif player.y < box.y then 
			hit ground
		elseif player.x > box.x then 
			stop moving on x axsis
		elseif player.x < box.x then 
			stop moving on x axsis
		end
The above was your attempt at AABB :)

To see why you get nil, I would need to see more of your actual code.
User avatar
NoreoAlles
Party member
Posts: 107
Joined: Mon Jan 03, 2022 5:42 pm

Re: AABB collision between player and multiple boxes

Post by NoreoAlles »

Jeeper wrote: Thu Apr 14, 2022 8:32 am
NoreoAlles wrote: Wed Apr 13, 2022 6:17 pm JO, your tutoriel series was the thing that made me do some actual stuff. My collision detection works fine, atleast i think it does.
To see why you get nil, I would need to see more of your actual code.
I implemented your aabb because i was sure it would be better then mine (it is) and then tried resolving the collision (moving the player out of the tile after the intitial collision). It works like a bad luck charm.
player.lua:

Code: Select all

function Player:collide()
    for i, b in ipairs(blocks) do 
        if aabb(self, b) then --collide(self.x, self.y, self.w, self.h, b.x, b.y, b.w, b.h) then
            self:solveCollision(b)
            if self.x > b.x then 
                self.xVel = 0 
            end
            if self.x < b.x then 
                self.xVel = 0 
            end
            if self.y < b.y then 
                self.grounded = true
            end
        end
    end
    
end

function Player:solveCollision(b)
    if self.x > b.x then 
        local wert1 = b.x - self.x + b.w
        self.x = self.x + wert1
    end
    if self.x < b.x then 
        local wert2 = b.x - self.x - b.w
        self.x = self.x + wert2
    end
    if self.y > b.y then 
       local wert3 = b.y - self.y + b.h
       self.y = self.y + wert3
    end
    if self.y < b.y then
        local wert4 = b.y - self.y - b.h
        self.y = self.y + wert4
    end
end
main.lua:

Code: Select all

function collide(a, b)
    if a.x > b.x + b.w or b.x > a.x + a.w then 
        return false 
    end

    if a.y > b.y + b.w or b.y > a.y + a.h  then 
        return false 
    end
    print("collsion")
    return true
end

function aabb(a, b)
	return (a.x < b.x + b.w and a.x + a.w  > b.x and a.y < b.y + b.h and b.y < a.y + a.h)
end
It pushes the player out of the tile, wich would work if it was only one tile in the game, but its not. So if the player falls between two tiles still gets pushed out to the sides, instead of just landing on top.
Attachments
game.love
(3.89 KiB) Downloaded 45 times
"Why do they call it oven when you of in the cold food of out hot eat the food?" - Jon Arbuckle
User avatar
NoreoAlles
Party member
Posts: 107
Joined: Mon Jan 03, 2022 5:42 pm

Re: AABB collision between player and multiple boxes

Post by NoreoAlles »

btw i never know what to name my variables so theyre always just "wert", value in my language
"Why do they call it oven when you of in the cold food of out hot eat the food?" - Jon Arbuckle
Post Reply

Who is online

Users browsing this forum: No registered users and 53 guests