Postanowiłem opisać problem jeszcze raz, ostatnio faktycznie może nie wyglądało to zbyt składnie.
Próbuję stworzyć kolizję z w grze platformowej, używam SFMLa,C++ i Lua. Kolizja którą chcę stworzyć to kolizja obiektów o różnych rozmiarach, obiekty mogą być statyczne albo się poruszać(ruchome kafelki), natomiast zawsze będą prostokątami.
Obecnie wygląda to tak,
local cLeft = character:getPositionX()
local cRight = character:getPositionX() + character:getBoundingRectWidth()
local cTop = character:getPositionY()
local cBottom = character:getPositionY() + character:getBoundingRectHeight()
local tLeft = tile:getPositionX()
local tRight = tile:getPositionX() + tile:getBoundingRectWidth()
local tTop = tile:getPositionY()
local tBottom = tile:getPositionY() + tile:getBoundingRectHeight()
local deltaX = tile:getPositionX() - character:getPositionX()
local deltaY = tile:getPositionY() - character:getPositionY()
local intersectX = math.abs(deltaX)
- (character:getBoundingRectWidth() / 2 - tile:getBoundingRectWidth() / 2)
local intersectY = math.abs(deltaY)
- (character:getBoundingRectHeight() / 2 - tile:getBoundingRectHeight() / 2)
--bottom collision
if cTop < tTop and cBottom < tBottom and cLeft < tRight and cRight > tLeft
then
character:setEntityPosition(character:getPositionX(),tTop - character:getBoundingRectHeight())
character:setVelocityY(0)
character:setOnGround(true)
--top collision
elseif cTop > tTop and cBottom > tBottom and cLeft < tRight and cRight > tLeft
then
character:setEntityPosition(character:getPositionX(),tBottom)
character:setVelocityY(0)
end
--right collision
if cLeft < tLeft and cRight < tRight and cTop < tBottom and cBottom > tTop
then
character:setEntityPosition(tLeft - character:getBoundingRectWidth(),character:getPositionY())
character:setVelocityX(0)
--left collision
elseif cLeft > tLeft and cRight > tRight and cTop < tBottom and cBottom > tTop
then
character:setEntityPosition(tRight,character:getPositionY())
character:setVelocityX(0)
end
Teoretycznie kolizja działa we wszystkie strony, jednak pojawia się problem kiedy postać nachodzi na róg kalfeka, wtedy sprawdzane są warunki dla osi x i y jednocześnie, i dzieje się takie coś:
I w tym momencie idę w lewo, ale postać nie zatrzymuje się ze względu na kolizję tylko przeskakuje na górę:
Dodałem więc taką modyfikację do kodu:
local intersectX = math.abs(deltaX)
- (character:getBoundingRectWidth() / 2 - tile:getBoundingRectWidth() / 2)
local intersectY = math.abs(deltaY)
- (character:getBoundingRectHeight() / 2 - tile:getBoundingRectHeight() / 2)
if(intersectY > intersectX)
then
--bottom collision
if cTop < tTop and cBottom < tBottom and cLeft < tRight and cRight > tLeft
then
character:setEntityPosition(character:getPositionX(),tTop - character:getBoundingRectHeight())
character:setVelocityY(0)
character:setOnGround(true)
--top collision
elseif cTop > tTop and cBottom > tBottom and cLeft < tRight and cRight > tLeft
then
character:setEntityPosition(character:getPositionX(),tBottom)
character:setVelocityY(0)
end
end
if(intersectX > intersectY)
then
--right collision
if cLeft < tLeft and cRight < tRight and cTop < tBottom and cBottom > tTop
then
character:setEntityPosition(tLeft - character:getBoundingRectWidth(),character:getPositionY())
character:setVelocityX(0)
--left collision
elseif cLeft > tLeft and cRight > tRight and cTop < tBottom and cBottom > tTop
then
character:setEntityPosition(tRight,character:getPositionY())
character:setVelocityX(0)
end
end
I faktycznie prawie zadziałało, kolizja działa dla niektórych przypadków ale dla niektórych nie, konkretnie dla 2 przypadków, jak postać od dołu wchodzi na dolny prawy róg oraz jak od prawej strony wchodzi na górny lewy róg. Nie mam pomysłu jak to rozwiązać.