Page 1 of 1

[Solved]Collision

Posted: Sun Jun 21, 2015 11:09 am
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.

Re: Collision

Posted: Sun Jun 21, 2015 11:44 am
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.

Re: Collision

Posted: Sun Jun 21, 2015 12:02 pm
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.

Re: Collision

Posted: Sun Jun 21, 2015 12:28 pm
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.

Re: [Solved]Collision

Posted: Sun Jun 21, 2015 9:28 pm
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.