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.
If you move object by the dx, dy then you teleport this object to the new position, same as it was by the mouse position.
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.
If you move object by the dx, dy then you teleport this object to the new position, same as it was by the mouse position.
function teleportObj (obj, x, y)
obj.x = x
obj.y = y
end
Would you like me to share the code of the library I am trying to make so you can find out how it works and how to make the separate() function. Sorry for me being like this.
notcl4y wrote: ↑Mon Jun 12, 2023 9:51 am
Wouldn't you mind me sharing the code of the library I'm trying to make so you can find out how it works and how to make the separate() function. Sorry for me being like this.
You can share your lib and we are trying to fix it. Here dx and dy are just the position difference, we don't change the velocity of object, but position.
notcl4y wrote: ↑Mon Jun 12, 2023 9:51 am
Wouldn't you mind me sharing the code of the library I'm trying to make so you can find out how it works and how to make the separate() function. Sorry for me being like this.
You can share your lib and we are trying to fix it. Here dx and dy are just the position difference, we don't change the velocity of object, but position.
local lCollision = {}
local function range(x1, y1, width1, height1, x2, y2, width2, height2)
if x1 >= x2 and x1 + width1 <= x2 + width2 and y1 >= y2 and y1 + height1 <= y2 + height2 then
return true
end
return false
end
local function rangeWhole(x1, y1, width1, height1, x2, y2, width2, height2)
--if x1 >= x2 and x1 + width1 <= x2 + width2 + width1 and y1 >= y2 and y1 + height1 <= y2 + height2 + height1 then
if x1 + width1 >= x2 and x1 <= x2 + width2 and y1 + height1 >= y2 and y1 <= y2 + width2 then
return true
end
return false
end
lCollision.Collider = {}
lCollision.Collider.__index = lCollision.Collider
function lCollision.Collider:new(x, y, width, height)
local collider = setmetatable({}, self)
collider.x = x
collider.y = y
collider.width = width
collider.height = height
return collider
end
function lCollision.Collider:draw()
love.graphics.rectangle("line", self.x, self.y, self.width, self.height)
end
-- This function used to be called collider:collides(collider) until it showed that it can detect if a collider is INSIDE of another one
function lCollision.Collider:insideOf(collider)
if range(self.x, self.y, self.width, self.height, collider.x, collider.y, collider.width, collider.height) then
return true
end
return false
end
function lCollision.Collider:collides(collider)
if rangeWhole(self.x, self.y, self.width, self.height, collider.x, collider.y, collider.width, collider.height) then
return true
end
return false
end
-- Ah yes, the function that gave a lot of PAIN to make
function lCollision.Collider:separate(collider)
if self.x + self.width / 2 < collider.x + collider.width / 2 then
-- middle point of agent is more left than by the box
self.x = -self.width + (collider.x - self.x)
else
self.x = collider.width - (self.x - collider.x)
end
if self.y + self.height / 2 < collider.y + collider.height / 2 then
-- middle point of agent is higher than by the box
self.y = -self.height + (collider.y - self.y)
else
self.x = collider.height - (self.y - collider.y)
end
--[[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 = collider.x - self.width
elseif self.x <= colliderRightSide and rightSide > colliderCenterX then
self.x = collider.x + collider.width
end
elseif rightSide >= collider.x and self.x <= colliderRightSide then
if bottomSide >= collider.y and bottomSide < colliderCenterY then
self.y = collider.y - self.height
elseif self.y <= colliderBottomSide and bottomSide > colliderCenterY then
self.y = collider.y + collider.height
end
end]]
--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]]
--[[if self.x <= colliderX then
self.x = self.x - 1
end
if self.x >= colliderX then
self.y = self.y + 1
end
if self.y <= colliderY then
self.y = self.y - 1
end
if self.y >= colliderY then
self.y = self.y + 1
end]]
--[[if self.y > collider.y and self.y + self.height < collider.y + collider.height then
if self.x <= colliderX then
self.x = self.x - 1
end
if self.x >= colliderX then
self.x = self.x + 1
end
elseif self.x > collider.x and self.x + self.width < collider.x + collider.width then
if self.y <= colliderY then
self.y = self.y - 1
end
if self.y >= colliderY then
self.y = self.y + 1
end
end]]
--end
end
function lCollision.Collider:getCenter()
local x = self.x + self.width / 2
local y = self.y + self.height / 2
return x, y
end
return lCollision
notcl4y wrote: ↑Mon Jun 12, 2023 11:26 am
And here's the library's github repo, but it doesn't have the current changes like in the code I've sent above: https://github.com/notcl4y14/lCollision
-- lCollision.lua
-- https://github.com/notcl4y14/lCollision/blob/main/lCollision.lua
local lCollision = {}
lCollision.__index = lCollision
local function checkCollision(x1,y1,w1,h1, x2,y2,w2,h2)
-- from https://love2d.org/wiki/BoundingBox.lua
return x1 < x2+w2 and x2 < x1+w1 and y1 < y2+h2 and y2 < y1+h1
end
function lCollision:collides(collider)
if checkCollision(self.x, self.y, self.width, self.height, collider.x, collider.y, collider.width, collider.height) then
return true
end
return false
end
function lCollision:insideOf(collider)
if checkCollision(
self.x, self.y, self.width, self.height,
collider.x+self.width, collider.y+self.height, collider.width-2*self.width, collider.height-2*self.height
) then
return true
end
return false
end
function lCollision:onBorder(collider)
if self:collides(collider) and not self:insideOf(collider) then
return true
end
return false
end
function lCollision:separate(collider)
if not checkCollision(self.x,self.y,self.width,self.height, collider.x,collider.y,collider.width,collider.height) then
-- no collision: nothing to do
return
end
-- (dx, dy) will be orthogonal separation vector
local dx = collider.x - self.x
local dy = collider.y - self.y
if self.x + self.width / 2 < collider.x + collider.width / 2 then
-- middle point of agent is more left than by the box
dx = dx - self.width
else
dx = dx + collider.width
end
if self.y + self.height / 2 < collider.y + collider.height / 2 then
-- middle point of agent is higher than by the box
dy = dy - self.height
else
dy = dy + collider.height
end
-- making the separation vector orthogonal:
if math.abs (dx) > math.abs (dy) then
dx = 0 -- dx was longer than dy
else
dy = 0
end
-- moving the self
self.x = self.x + dx
self.y = self.y + dy
end
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
function lCollision:new(x, y, width, height)
local collider = setmetatable({x=x, y=y, width=width, height=height}, self)
return collider
end
function lCollision:draw()
love.graphics.rectangle("line", self.x, self.y, self.width, self.height)
end
return lCollision
Screenshot 2023-06-12 175938.png (13.19 KiB) Viewed 1840 times
notcl4y wrote: ↑Mon Jun 12, 2023 11:26 am
And here's the library's github repo, but it doesn't have the current changes like in the code I've sent above: https://github.com/notcl4y14/lCollision
-- lCollision.lua
-- https://github.com/notcl4y14/lCollision/blob/main/lCollision.lua
local lCollision = {}
lCollision.__index = lCollision
local function checkCollision(x1,y1,w1,h1, x2,y2,w2,h2)
-- from https://love2d.org/wiki/BoundingBox.lua
return x1 < x2+w2 and x2 < x1+w1 and y1 < y2+h2 and y2 < y1+h1
end
function lCollision:collides(collider)
if checkCollision(self.x, self.y, self.width, self.height, collider.x, collider.y, collider.width, collider.height) then
return true
end
return false
end
function lCollision:insideOf(collider)
if checkCollision(
self.x, self.y, self.width, self.height,
collider.x+self.width, collider.y+self.height, collider.width-2*self.width, collider.height-2*self.height
) then
return true
end
return false
end
function lCollision:onBorder(collider)
if self:collides(collider) and not self:insideOf(collider) then
return true
end
return false
end
function lCollision:separate(collider)
if not checkCollision(self.x,self.y,self.width,self.height, collider.x,collider.y,collider.width,collider.height) then
-- no collision: nothing to do
return
end
-- (dx, dy) will be orthogonal separation vector
local dx = collider.x - self.x
local dy = collider.y - self.y
if self.x + self.width / 2 < collider.x + collider.width / 2 then
-- middle point of agent is more left than by the box
dx = dx - self.width
else
dx = dx + collider.width
end
if self.y + self.height / 2 < collider.y + collider.height / 2 then
-- middle point of agent is higher than by the box
dy = dy - self.height
else
dy = dy + collider.height
end
-- making the separation vector orthogonal:
if math.abs (dx) > math.abs (dy) then
dx = 0 -- dx was longer than dy
else
dy = 0
end
-- moving the self
self.x = self.x + dx
self.y = self.y + dy
end
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
function lCollision:new(x, y, width, height)
local collider = setmetatable({x=x, y=y, width=width, height=height}, self)
return collider
end
function lCollision:draw()
love.graphics.rectangle("line", self.x, self.y, self.width, self.height)
end
return lCollision
Screenshot 2023-06-12 175938.png
Thanks! Should I put the credits only in the library file as a comment?
notcl4y wrote: ↑Tue Jun 13, 2023 5:16 am
Thanks! Should I put the credits only in the library file as a comment?
As you want, it's more education project, I am sure that anyone wrote almost same lib, but we are making it for better understanding and for experience for next more complicated projects.