Trying to make collisions work

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Trying to make collisions work

Post by notcl4y »

When the collider collides from the top or the bottom it just goes along the side to either left or right.

Code: Select all

function lCollision.Collider:separate(collider)
  while self:collides(collider) do
    local centerX, centerY = self:getCenter()
    local rightSide = self.x + self.width
    local bottomSide = self.y + self.height
    local colliderCenterX, colliderCenterY = collider:getCenter()
    local colliderRightSide = collider.x + collider.width
    local colliderBottomSide = collider.y + collider.height
    
    if bottomSide > collider.y and self.y < colliderBottomSide then
      if rightSide >= collider.x and rightSide < colliderCenterX then
        self.x = self.x - 1
      elseif self.x <= colliderRightSide and rightSide > colliderCenterX then
        self.x = self.x + 1
      end
    elseif rightSide > collider.x and self.x < colliderRightSide then
      if bottomSide >= collider.y and bottomSide < colliderCenterY then
        self.y = self.y - 1
      elseif self.y <= colliderBottomSide and bottomSide > colliderCenterY then
        self.y = self.y + 1
      end
    end
  end
end

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
darkfrei
Party member
Posts: 1181
Joined: Sat Feb 08, 2020 11:09 pm

Re: Trying to make collisions work

Post by darkfrei »

Where are you choosing if it horizontal or vertical collision solving? Is it possible that you need vertical and horizontal solving simultaneously?
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: Trying to make collisions work

Post by notcl4y »

darkfrei wrote: Sun Jun 11, 2023 2:58 pm Where are you choosing if it horizontal or vertical collision solving? Is it possible that you need vertical and horizontal solving simultaneously?
I mean I'm trying to make a function that separates a collider from another one when they collide. But for some reason when the collider collides with another one from the top or the bottom side it just goes alongside to the left or the right side. (Sorry for bad English)

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
darkfrei
Party member
Posts: 1181
Joined: Sat Feb 08, 2020 11:09 pm

Re: Trying to make collisions work

Post by darkfrei »

notcl4y wrote: Sun Jun 11, 2023 3:08 pm
darkfrei wrote: Sun Jun 11, 2023 2:58 pm Where are you choosing if it horizontal or vertical collision solving? Is it possible that you need vertical and horizontal solving simultaneously?
I mean I'm trying to make a function that separates a collider from another one when they collide. But for some reason when the collider collides with another one from the top or the bottom side it just goes alongside to the left or the right side. (Sorry for bad English)
Here must be the condition like

Code: Select all

if horizontalCollision and verticalCollision then
	if  horizontal_collision > verticalCollision then
		-- solve horizontal collision
	else 
		-- solve vertical collision
	end
elseif horizontalCollision then
	-- solve horizontal collision
elseif verticalCollision then
	-- solve vertical collision
else
	-- no collision
end
Now if you have one of them the then the another one has no influence at all.

:awesome: Update:
Solution:

Code: Select all

local function checkCollision(x1,y1,w1,h1, x2,y2,w2,h2)
  return x1 < x2+w2 and
         x2 < x1+w1 and
         y1 < y2+h2 and
         y2 < y1+h1
end

local function separateRectangles (agent, box)
	local x1, y1 = agent.x, agent.y
	local w1, h1 = agent.w, agent.h

	local x2, y2 = box.x, box.y
	local w2, h2 = box.w, box.h
	
	if checkCollision(x1,y1,w1,h1, x2,y2,w2,h2) then
		-- collision exists!
		local dx, dy = 0, 0
		if x1+w1/2 < x2+w2/2 then
			-- middle point of agent is more left than by the box
			dx = -w1+(x2-x1)
		else
			dx = w2-(x1-x2)
		end
		
		if y1+h1/2 < y2+h2/2 then
			-- middle point of agent is higher than by the box
			dy = -h1+(y2-y1)
		else
			dy = h2-(y1-y2)
		end
		
		if math.abs (dx) < math.abs (dy) then
			-- horizontal solution is shorter
			return dx, 0
		else	
			return 0, dy
		end
	end

	return 0, 0
end

function love.load()
	Agent = {x=0, y=0, w=100, h=120}
	Box = {x=300, y=250, w=120, h=100}	
end

function love.draw()
	love.graphics.rectangle ('line', Agent.x, Agent.y, Agent.w, Agent.h)
	love.graphics.rectangle ('line', Box.x, Box.y, Box.w, Box.h)
end

function love.mousemoved( x, y, dx, dy, istouch )
	Agent.x = x
	Agent.y = y
	local dx1, dy1 = separateRectangles (Agent, Box)
	Agent.x = Agent.x + dx1
	Agent.y = Agent.y + dy1
end
Attachments
rectangle-collision-01.love
(800 Bytes) Downloaded 69 times
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: Trying to make collisions work

Post by notcl4y »

darkfrei wrote: Sun Jun 11, 2023 4:06 pm :awesome: Update:
Solution:

Code: Select all

local function checkCollision(x1,y1,w1,h1, x2,y2,w2,h2)
  return x1 < x2+w2 and
         x2 < x1+w1 and
         y1 < y2+h2 and
         y2 < y1+h1
end

local function separateRectangles (agent, box)
	local x1, y1 = agent.x, agent.y
	local w1, h1 = agent.w, agent.h

	local x2, y2 = box.x, box.y
	local w2, h2 = box.w, box.h
	
	if checkCollision(x1,y1,w1,h1, x2,y2,w2,h2) then
		-- collision exists!
		local dx, dy = 0, 0
		if x1+w1/2 < x2+w2/2 then
			-- middle point of agent is more left than by the box
			dx = -w1+(x2-x1)
		else
			dx = w2-(x1-x2)
		end
		
		if y1+h1/2 < y2+h2/2 then
			-- middle point of agent is higher than by the box
			dy = -h1+(y2-y1)
		else
			dy = h2-(y1-y2)
		end
		
		if math.abs (dx) < math.abs (dy) then
			-- horizontal solution is shorter
			return dx, 0
		else	
			return 0, dy
		end
	end

	return 0, 0
end

function love.load()
	Agent = {x=0, y=0, w=100, h=120}
	Box = {x=300, y=250, w=120, h=100}	
end

function love.draw()
	love.graphics.rectangle ('line', Agent.x, Agent.y, Agent.w, Agent.h)
	love.graphics.rectangle ('line', Box.x, Box.y, Box.w, Box.h)
end

function love.mousemoved( x, y, dx, dy, istouch )
	Agent.x = x
	Agent.y = y
	local dx1, dy1 = separateRectangles (Agent, Box)
	Agent.x = Agent.x + dx1
	Agent.y = Agent.y + dy1
end
Thanks but...Can you make this for top-down controls please? I'm making a library and you can use it. (And its example as well) viewtopic.php?f=5&t=94628

Sorry I just couldn't re-implement the code that uses the mouse into the code that uses keyboard.

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
darkfrei
Party member
Posts: 1181
Joined: Sat Feb 08, 2020 11:09 pm

Re: Trying to make collisions work

Post by darkfrei »

notcl4y wrote: Sun Jun 11, 2023 7:25 pm Thanks but...Can you make this for top-down controls please? I'm making a library and you can use it. (And its example as well) viewtopic.php?f=5&t=94628

Sorry I just couldn't re-implement the code that uses the mouse into the code that uses keyboard.
Just
https://love2d.org/wiki/love.keyboard.isScancodeDown

Code: Select all

function love.update (dt)
	local scancodeW = love.keyboard.isScancodeDown("w")
	local scancodeS = love.keyboard.isScancodeDown("s")
	local scancodeD = love.keyboard.isScancodeDown("d")
	local scancodeA = love.keyboard.isScancodeDown("a")
	local dx, dy = 0, 0
	local speed = 100
	if scancodeW then
		dy = -speed * dt
	elseif scancodeS then
		dy = speed * dt
	end
	if scancodeD then
		dx = speed * dt
	elseif scancodeA then
		dx = -speed * dt
	end
	
	-- changing the position of agent:
	Agent.x = Agent.x + dx
	Agent.y = Agent.y + dy
	
	-- and than push agent rectangle from collision:
	local dx1, dy1 = separateRectangles (Agent, Box)
	Agent.x = Agent.x + dx1
	Agent.y = Agent.y + dy1
end
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: Trying to make collisions work

Post by notcl4y »

darkfrei wrote: Sun Jun 11, 2023 8:17 pm Just
https://love2d.org/wiki/love.keyboard.isScancodeDown

Code: Select all

function love.update (dt)
	local scancodeW = love.keyboard.isScancodeDown("w")
	local scancodeS = love.keyboard.isScancodeDown("s")
	local scancodeD = love.keyboard.isScancodeDown("d")
	local scancodeA = love.keyboard.isScancodeDown("a")
	local dx, dy = 0, 0
	local speed = 100
	if scancodeW then
		dy = -speed * dt
	elseif scancodeS then
		dy = speed * dt
	end
	if scancodeD then
		dx = speed * dt
	elseif scancodeA then
		dx = -speed * dt
	end
	
	-- changing the position of agent:
	Agent.x = Agent.x + dx
	Agent.y = Agent.y + dy
	
	-- and than push agent rectangle from collision:
	local dx1, dy1 = separateRectangles (Agent, Box)
	Agent.x = Agent.x + dx1
	Agent.y = Agent.y + dy1
end
So it only works via dx and dy? No checking if the collider collides with another one and separate it from that collider just via setting the position but dx and dy?

Code: Select all

loves_lua = "not so",
wants_to = true
User avatar
darkfrei
Party member
Posts: 1181
Joined: Sat Feb 08, 2020 11:09 pm

Re: Trying to make collisions work

Post by darkfrei »

notcl4y wrote: Sun Jun 11, 2023 8:30 pm So it only works via dx and dy? No checking if the collider collides with another one and separate it from that collider just via setting the position but dx and dy?
If nothing moves then nothing collides! But if you move something, then you need to solve this for all colliding objects.

Of coarse you can use this separation to move the other object, dx and dy will be same, but negative.
Or use dx/2 and dy/2 to move both of them in the half distance of separation solution.
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
dusoft
Party member
Posts: 510
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: Trying to make collisions work

Post by dusoft »

darkfrei wrote: Sun Jun 11, 2023 9:00 pm
notcl4y wrote: Sun Jun 11, 2023 8:30 pm So it only works via dx and dy? No checking if the collider collides with another one and separate it from that collider just via setting the position but dx and dy?
If nothing moves then nothing collides! But if you move something, then you need to solve this for all colliding objects.
You can have static colliding objects. For anything more complicated I would recommend using love.physic / Box2D model. It has steep learning curve, but then collisions are easy.
User avatar
notcl4y
Citizen
Posts: 85
Joined: Fri Nov 25, 2022 12:23 pm

Re: Trying to make collisions work

Post by notcl4y »

darkfrei wrote: Sun Jun 11, 2023 9:00 pm
notcl4y wrote: Sun Jun 11, 2023 8:30 pm So it only works via dx and dy? No checking if the collider collides with another one and separate it from that collider just via setting the position but dx and dy?
If nothing moves then nothing collides! But if you move something, then you need to solve this for all colliding objects.
The system I'm trying to make is if it collides then it will separate, so it means that if the object will move or instantly teleport into a collider then it will separate. Not when a collider moves into another one.

Code: Select all

loves_lua = "not so",
wants_to = true
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 56 guests