[Solved] Help with AABB 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
Kaister93
Prole
Posts: 5
Joined: Wed Jan 31, 2018 11:34 am

[Solved] Help with AABB collision

Post by Kaister93 » Sun Nov 18, 2018 7:13 pm

I've made my own AABB collision successfully, well sort of, it is pixel perfect. The only thing is, when I am holding down diagonally, I stop moving when I get to the wall.

Let's say I am approaching a wall horizontally. I stop moving when I collide with the wall. But, I can't move up if I am holding the right key, it only has to be the up and down key, which in many games that doesn't happen. I can't figure out how to fix it. Same thing with vertical collision

The player can move in 8 directions (WASD) , and only moves in integer increments. Here is my collision code:

Code: Select all

function collision:checkAABB(x, x2, ox, ox2)
	if (x > ox and x < ox2) then
		return true
	end

	if (x2 > ox and x2 < ox2) then
		return true
	end

	return false
end

function sign(num)
	local sign = 0
	if (num > 0) then
		sign = 1
	end

	if (num < 0) then
		sign = -1
	end

	return sign
end
***Sign is just returning 1 if a number is positive, or -1 if a number is negative, 0 if it is zero.****

Code: Select all

function Player:collisions()
	local xMeet = false
	local yMeet = false
	for _, o in pairs(objects) do
		if (o ~= player) then
			xMeet = collision:checkAABB(player.x + player.hsp, player.x + player.w + player.hsp, o.x, o.x + o.w)
			yMeet = collision:checkAABB(player.y + player.vsp, player.y + player.h + player.vsp, o.y, o.y + o.h)

			if (xMeet and yMeet) then
				xMeet, yMeet = false, false

				while (true) do
					xMeet = collision:checkAABB(player.x + sign(player.hsp), player.x + player.w + sign(player.hsp), o.x, o.x + o.w)
					if (xMeet == false) then
						player.x = player.x + sign(player.hsp)
					else
						player.hsp = 0
						break;
					end
				end

				while (true) do
					yMeet = collision:checkAABB(player.y + sign(player.vsp), player.y + player.h + sign(player.vsp), o.y, o.y + o.h)
					if (yMeet == false) then
						player.y = player.y + sign(player.vsp)
					else
						player.vsp = 0
						break;
					end
				end
			end
		end
	end
end
Integer Hsp is how many horizontal pixels the player is going to move that frame, same with vsp
***The player's x is incremented my the hsp every frame, same with y and vsp****
Last edited by Kaister93 on Wed Nov 21, 2018 2:37 pm, edited 1 time in total.

User avatar
pgimeno
Party member
Posts: 1685
Joined: Sun Oct 18, 2015 2:58 pm

Re: Help with AABB collison

Post by pgimeno » Mon Nov 19, 2018 2:56 am

Can you include some functioning code that demonstrates the problem? Not just a snippet of where you think the problem is, but a whole program.

Note that your checkAABB function has a problem. It will check whether each corner of the player's rectangle is inside another rectangle, but it will let the player penetrate rectangles that are smaller than the player itself in one axis. Consider this case, for example:

Code: Select all

     Player
    +-----+
    |     |      Obstacle
    |   +---------------+
    |   |               |
    |   +---------------+
    |     |
    +-----+
The player will happily go through the obstacle, because none of its corners is inside the obstacle's AABB.

You need a proper box intersection function to deal with that case. That's easy for AABBs. For two boxes B1 and B2:
  • If the right side of B1 is to the left of the left side of B2, they can't touch.
  • If the left side of B1 is to the right of the right side of B2, they can't touch.
  • If the bottom side of B1 is above the top side of B2, they can't touch.
  • If the top side of B1 is below the bottom side of B2, they can't touch.
  • In all other cases, they are touching.
This is usually implemented using DeMorgan's laws to convert the above to a positive assertion about whether they touch. The result is a function similar to this: BoundingBox.lua

That doesn't seem to be the problem here, though. I just noticed that.

Kaister93
Prole
Posts: 5
Joined: Wed Jan 31, 2018 11:34 am

Re: Help with AABB collison

Post by Kaister93 » Tue Nov 20, 2018 11:07 pm

I am sorry, I just read the rules and I should have provided my .love file. Here it is.

Up and down arrow keys to select. Z basically is enter.

I only have a simple scene loader with one giant cube and the player.

I kind of knew that would be a problem, yeah if the object is smaller it goes right through because it only checks the four corners.

But besides that for now, I have some pretty awkward collisions and movement, just try it out.
Attachments
TestGame.love
(2.87 MiB) Downloaded 24 times

User avatar
pgimeno
Party member
Posts: 1685
Joined: Sun Oct 18, 2015 2:58 pm

Re: Help with AABB collison

Post by pgimeno » Wed Nov 21, 2018 12:31 am

Thanks for the love file. It's not just because of the rules, it also enables more people to help you, as it lets us add debug printouts or checks to better understand what's going on without having to just decipher the code, when we have something that we can actually run ourselves.

Now, back to the issue. For the case when the player approaches the obstacle from the left and hits it frontally, whenever the player is at the level of the box, yMeet will be true all the time. This causes the vertical speed to be always zeroed in that circumstance in case of a collision, hence no vertical movement. Something similar happens when approaching the box from the top: xMeet will be true all the time.

The problem is that your per-corner collision check can only work when both the x check and the y check are performed, and both return true. But In the loops you're checking only x in the first loop and only y in the second. You're leaving half the condition for interpenetration out. And even when that is fixed, those loops are not well conceived: you should loop in an axis only when there's a collision *in that axis* guaranteed in a single movement, otherwise you may loop to an obstacle that is far away, or to infinity if there are no more obstacles.

I don't recommend you to continue with this approach. I'd switch to full rectangle checks, things will be easier that way.

Kaister93
Prole
Posts: 5
Joined: Wed Jan 31, 2018 11:34 am

Re: Help with AABB collison

Post by Kaister93 » Wed Nov 21, 2018 1:05 am

I totally agree, I figured it would be nearly impossible to fix with out making it way more complicated. I'll try to figure out your method of collision checking, and see if that works. I thought I was doing something after it took me an hour to figure the collisions out by myself by debugging and failure...

User avatar
pgimeno
Party member
Posts: 1685
Joined: Sun Oct 18, 2015 2:58 pm

Re: Help with AABB collison

Post by pgimeno » Wed Nov 21, 2018 6:13 am

I wonder if using a dedicated collision library like bump.lua is out of the question? I understand if you want to implement them by yourself to learn, but my impression is that you need to gain some more experience before you focus your energies on problems of the magnitude of collisions. Collisions are hard.

Kaister93
Prole
Posts: 5
Joined: Wed Jan 31, 2018 11:34 am

Re: Help with AABB collison

Post by Kaister93 » Wed Nov 21, 2018 2:14 pm

I did it! Not by myself, thanks for the help, the bump module made it a lot easier. No way I could have did that. Anyways, here it is, thanks!
Attachments
TestGame.love
(3.28 MiB) Downloaded 30 times

User avatar
pgimeno
Party member
Posts: 1685
Joined: Sun Oct 18, 2015 2:58 pm

Re: [Solved] Help with AABB collision

Post by pgimeno » Wed Nov 21, 2018 3:09 pm

It looks really smooth, congrats! Thanks for the mention! :ultraglee: And yeah, collisions are disproportionately complex in relation to the apparent simplicity of the concepts. It's good to have libraries like Bump or HC or Box2D in your toolbox.

Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests