[Solved]Collision

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
Dr.Tyler O.
Citizen
Posts: 58
Joined: Tue Jul 29, 2014 9:17 am
Location: United States

[Solved]Collision

Post by Dr.Tyler O. »

I am using a collision detection method that I found through the use of a tutorial made by HugoBDesigner.

I have found an issue and I can't seem to figure out how to fix it.
Image
As you can see, when the player falls it gets stuck on the side of the blocks. I have further debugged this and it seems that, somehow, it is registering that it is touching the top of a block to form bottom collision for the player. I don't understand how this is possible. The player's collision box is eighteen pixels wide while the space between two blocks is twenty pixels wide so I don't believe it could be an issue of the player getting stuck. Here is the code which checks collision as well as the code that applies it.

The code which checks collisions between two objects:

Code: Select all

function checkCollision(object1, object2)
	local right = (object1.x + object1.w) - object2.x
	local left = (object2.x + object2.w) - object1.x
	local bottom = (object1.y + object1.h) - object2.y
	local top = (object2.y + object2.h) - object1.y

	if right < left and right < top and right < bottom then
		return "right"
	elseif left < top and left < bottom then
		return "left"
	elseif top < bottom then
		return "top"
	else
		return "bottom"
	end
end
The code which applies the collisions:

Code: Select all

for k, v in ipairs(objects) do
	if player.x + player.w >= v.x and player.x <= v.x + v.w and player.y + player.h >= v.y and player.y <= v.y + v.h then
		local collision = checkCollision(player, v)
		if collision == "bottom" then
			player.y = v.y - player.h
			player.collisions.bottom = true
		end
		if collision == "right" then
			player.x = v.x - player.w
		end
		if collision == "left" then
			player.x = v.x + v.w
		end
		if collision == "top" then
			player.y = v.y + v.h
		end
	end
end
I have seen games where this happens occasionally but this happens nearly every time the player falls. Also there is no issue with the placement of the blocks I assure you. Thanks in advance.
Last edited by Dr.Tyler O. on Sun Jun 21, 2015 12:43 pm, edited 1 time in total.
Any topic I have ever posted that I felt did not require a .love file, although they were requested, never required one so I would appreciate if you did not ask me to supply one unless you think that I am ignorant for not doing so.
User avatar
Kingdaro
Party member
Posts: 395
Joined: Sun Jul 18, 2010 3:08 am

Re: Collision

Post by Kingdaro »

Try changing your equality expressions on this line to inequality:

Code: Select all

   if player.x + player.w > v.x and player.x < v.x + v.w and player.y + player.h > v.y and player.y < v.y + v.h then
When checking if the player is against the wall, the collision detection satisfies still after the collision is resolved, because their position is equal to the resolution position, and not exceeding it.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Collision

Post by ivan »

This looks likes a problem I've dealt with before.

Code: Select all

        __
   <---/  \
__ ____\__/___
  |    |    |
  | a  | b  |
In the diagram above the moving shape is colliding with 2 blocks in 1 frame.
If you solve the collision for block a first then the moving shape gets stuck.
So it's caused by the order the collisions are solved.
I'm afraid that with non-continuous collision detection there is no simple fix.

I would recommend something like Bump.lua, HardonCollider or
if you're really adventurous you can try FizzX (by Taehl and myself):
https://github.com/2dengine/fizzx
a library which tries to address this problem in a couple of ways.

Code: Select all

function checkCollision(object1, object2)
	local right = (object1.x + object1.w) - object2.x
	local left = (object2.x + object2.w) - object1.x
	local bottom = (object1.y + object1.h) - object2.y
	local top = (object2.y + object2.h) - object1.y

	if right < left and right < top and right < bottom then
		return "right"
	elseif left < top and left < bottom then
		return "left"
	elseif top < bottom then
		return "top"
	else
		return "bottom"
	end
end
My issue with the code above is that with collision detection you want to return 'false' as early as possible
and this example is good for demo purposes but has a lot of extra checks.
Last edited by ivan on Sat Dec 11, 2021 8:29 am, edited 1 time in total.
User avatar
Dr.Tyler O.
Citizen
Posts: 58
Joined: Tue Jul 29, 2014 9:17 am
Location: United States

Re: Collision

Post by Dr.Tyler O. »

Kingdaro wrote:Try changing your equality expressions on this line to inequality:

Code: Select all

   if player.x + player.w > v.x and player.x < v.x + v.w and player.y + player.h > v.y and player.y < v.y + v.h then
When checking if the player is against the wall, the collision detection satisfies still after the collision is resolved, because their position is equal to the resolution position, and not exceeding it.
Your solution works but now my jumping animation freaks out. xD Oh well, I can find a fix I suppose. It's worth it for fixed collision detection.
Any topic I have ever posted that I felt did not require a .love file, although they were requested, never required one so I would appreciate if you did not ask me to supply one unless you think that I am ignorant for not doing so.
User avatar
Kingdaro
Party member
Posts: 395
Joined: Sun Jul 18, 2010 3:08 am

Re: [Solved]Collision

Post by Kingdaro »

That's probably because your jumping animation relies on equality as well. Try using a boolean, onGround for example that checks and sets it to false at the beginning of every frame, then true if there was a ground collision that frame.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 5 guests