Page 1 of 3

Hardon Collider - getting stuck between tiles

Posted: Mon Oct 01, 2012 12:09 am
by luaz
As someone has mentioned elsewhere (but didn't explain), I think I'm using HardonCollider wrong.

Here's what I get right now, it only detects the collision here:

Image

I'm giving up. At least for today. I have no idea what's wrong with it... :o:

EDIT: The problem seems to be that the update if the objects are colliding is done erratically. I don't know why this is, but since the collider is what is doing the calculations, I'm lead to believe that this may be a bug in Hardon Collider. Although, since nobody else has reported it, and I'm just a beginner, I have very little confidence in my claim.

Re: Using Hardon Collider

Posted: Mon Oct 01, 2012 6:43 am
by paritybit
I think the likeliest problem is that there is a non-constant amount of time between updates -- when collision detection catches up with real time, your rectangles have already collided and are overlapping. It's not enough just to stop movement, you need to set the position of one of the two rectangles (probably the 'player') so that the edges are touching but not overlapping.

Also, I don't think the order of the objects passed to the collider collision callback is deterministic; I'm not sure that your player will always be objA, sometimes it might be objB. I know this caused me some grief when I was using that module.

Also, if you press up or down in addition to a direction (or alternate pressing keys) you can move all the way through the blocking object. This happens because your code only allows the player to be blocked in one direction at a time. You might want to change this so that the player can be blocked in more than one direction. To do this, you could change your code in player.lua to look like this (though I'm not sure this is the best option, it's relatively simple):

Code: Select all

	if(this.xSpeed ~= 0) then
		if(this.xSpeed > 0 and not this.blockedRight) then
			this.x = this.x + this.xSpeed * dt
		end
		if(this.xSpeed < 0 and not this.blockedLeft) then
			this.x = this.x + this.xSpeed * dt
		end
	end
	if(this.ySpeed ~= 0 and not this.blockedUp) then
		if(this.ySpeed < 0) then
			this.y = this.y + this.ySpeed * dt
		end
		if(this.ySpeed > 0 and not this.blockedDown) then
			this.y = this.y + this.ySpeed * dt
		end
	end
and in level.lua to look like this:

Code: Select all

	if(objA == player.colRect and objB == gmap.allRect) 
		or (objB == gmap.allRect and objA == player.colRect) then
		if(player.xSpeed > 0) then
			player.blockedRight = true
		end
		if(player.xSpeed < 0) then
			player.blockedLeft = true
		end
		if(player.ySpeed > 0) then
			player.blockedDown = true
		end
		if(player.ySpeed < 0) then
			player.blockedUp = true
		end
	end
The problem is now the player can get 'wedged' into the object which is bad. I didn't spend enough time inspecting your code to figure out how to reset the player's position to outside the object -- you should probably do that in the gmap.colTrue function. You should be able to use the objects to determine the exact positions of the fixed objects to determine where to move the player.

Hope this helps.

Re: Using Hardon Collider

Posted: Mon Oct 01, 2012 9:52 am
by luaz
Yes, I mainly posted due to the overlapping problem, as stated in the OP. What you rewritten is just the same code but in different variables. It is better though, to use Boolean statements, so I agree on that.

But as you said as well, there still is the main problem - overlapping. I can't find anything in the documentation that would help me with that (that I'm aware of), nor can I find something around here. I have spend quite a few hours on it. I don't know how to solve it.

Re: Using Hardon Collider (maybe a bug?)

Posted: Mon Oct 01, 2012 3:28 pm
by paritybit
I guess I didn't explain it well enough.

The HC does not prevent objects from overlapping. It just tells you when they overlap. It's collision detection not collision prevention. The update time (dt) which is passed to the update callback is never small enough to prevent high-speed movement from overlapping your objects, so you have to fix the overlap yourself by resetting the position of the moving thing in addition to stopping the movement.

If your player object is moving at a rate of 500 (pixels?) per second, it will be moving approximately 10 - 15 pixels per update. If one update takes the object right next to the wall, then a subsequent update will take the object 15 pixels INTO the wall -- and then you stop movement, but by then it's too late. You need to prevent movement and reset the position by writing code that will manually move your object OUTSIDE of the wall. HC does not do that because it was not designed to do that.

It's probably important enough to note that if your player object was moving fast enough, it could get all the way through the wall without triggering collision detection because the update only happens at a discrete moment in time, not at all time. It's just that most movement is slow enough and the detection updates fast enough that it appears as if it happens all the time.

Also, the code I wrote is not the same. It's using four variables instead of one. I don't have any concern about your strings versus my booleans, either would work. But your code allows for the player to be blocked by up OR down OR left OR right, what I wrote allows the player to be blocked in the up AND down AND left AND right. This is a very important distinction when a player can move in more than one direction.

Re: Using Hardon Collider (maybe a bug?)

Posted: Mon Oct 01, 2012 3:52 pm
by luaz
Ah, I see. That makes sense, I overlooked that part. I'm too much in love with Love2D's strings. :awesome: I should cut the use of them...

Anyway, I wonder, how I could stop the guy from moving in time then? Perhaps wait until the collision update is done? But I doubt that this may be efficient OR if there is a way to do it. Since you've mentioned that you've worked with HC (and it's quite obvious), perhaps you could help me with that? That's an odd problem, I have never had it in any other code I've dealt with (not Love2d/Lua). :|

Re: Using Hardon Collider (maybe a bug?)

Posted: Mon Oct 01, 2012 6:33 pm
by vrld
paritybit is right: HC only detects collisions - i.e. overlapping shapes - but does not resolve them. It's your duty to handle the situation. However, since most of the time you want to separate the shapes, the collision callback receives the necessary information to do just that: the minimum translation vector. See the documentation for more details and an example.

Re: Using Hardon Collider (maybe a bug?)

Posted: Wed Oct 03, 2012 3:37 pm
by luaz
Finally had a chance to sit down and try a bit different approach. However, I'm getting stuck or "jumpy" after each tile if there's more than 1 tile. Just keep any two buttons down and you'll see what I'm talking about. You can also simply hold S to move down not precisely into one tile.

I'm attaching .love instead of posting a chunk of code, I'm not sure if the problem's in my tile iteration algorithm...

Re: Hardon Collider - getting stuck between tiles

Posted: Wed Oct 03, 2012 8:44 pm
by paritybit
That love file isn't working for me. When I rename it to a zip and try to open it, it doesn't work either.

Looks like you made a 7z file and then changed the name to love, which doesn't work (at least on my computer).

But to me it looks like your math might be wrong somewhere. Horizontal collision appears to be working great. Vertical collision is just wrong. Maybe it has to do with the player being a rectangular shape instead of a square? Maybe you assumed somewhere that he was a square?

Re: Hardon Collider - getting stuck between tiles

Posted: Wed Oct 03, 2012 9:18 pm
by pk
It's a RAR!

You can't use the RAR extension. Use the ZIP or 7z extensions. People will have much less trouble if you stick to ZIP.

Re: Hardon Collider - getting stuck between tiles

Posted: Wed Oct 03, 2012 9:20 pm
by Nixola
Only use the zip extension, avoid the others.