Skip to main content
GameDev.net gamedev.net
🔒 Locked

Erratic 2D Platform Collision

Started by Whorse Aug 25, 2011 at 10:00 PM 13 replies 1.8k views
Original Post
Whorse
Whorse
The collision detection in my 2D platformer seems very erratic. At times when I run it, the collision is perfect, and the player is kept off the floor, other times the player overlaps the floor by a small margin. Has anyone had any experience with something similar before? It appears something is wrong with the hit detection.
Wooh
Wooh
I don't know how you handle your collisions but I guess you first move the player and then you test for collision. Depending on the speed and distance to the floor the move will get the player deeper into the floor. How do you handle that? Do you place the player above the floor on collision?
Whorse
Whorse
Yes, the movement gets incremented after the results of the collision which is the reason why this is happening. I'm more interested to know why it only happens only 50% of the time as opposed to every time! Is this a result of inaccurate collision detection?
wildbunny
wildbunny

Yes, the movement gets incremented after the results of the collision which is the reason why this is happening. I'm more interested to know why it only happens only 50% of the time as opposed to every time! Is this a result of inaccurate collision detection?


This sounds like a result of discrete collision detection. If you only check to see if two objects *have* collided on the current frame, the amount they have collided will vary depending on their speed and starting position. One time they might be just touching (by luck), the next time you'll find one inside the other.

In order to get around this, you need to use continuous collision detection, rather than discrete.

Check my blog for more details

http://www.wildbunny.co.uk/blog/2011/04/20/collision-detection-for-dummies/

Cheers, Paul.
Whorse
Whorse

[quote name='UraniumSlug' timestamp='1314349342' post='4853969']
Yes, the movement gets incremented after the results of the collision which is the reason why this is happening. I'm more interested to know why it only happens only 50% of the time as opposed to every time! Is this a result of inaccurate collision detection?


This sounds like a result of discrete collision detection. If you only check to see if two objects *have* collided on the current frame, the amount they have collided will vary depending on their speed and starting position. One time they might be just touching (by luck), the next time you'll find one inside the other.

In order to get around this, you need to use continuous collision detection, rather than discrete.
[/quote]


Cheers Paul, I had a look at your blog, very informative. I was doing some reading last night after I realised my current method of collision detection more than likely wasn't sufficient enough. Am I correct in assuming that the AABB vs AABB example uses a distance based calculation to determine whether the bounding boxes have intersected?

wildbunny
wildbunny

Cheers Paul, I had a look at your blog, very informative. I was doing some reading last night after I realised my current method of collision detection more than likely wasn't sufficient enough. Am I correct in assuming that the AABB vs AABB example uses a distance based calculation to determine whether the bounding boxes have intersected?



The AABB vs AABB check in the article is just a binary operation and doesn't give you the distance between AABBs that you would need for a continuous check.

Distance between two AABBs can be found by shrinking on down to a point and expanding the other by the orignal extents of the shrunken one. Then it simplifies to finding the distance between a point and an AABB, which is the same technique I describe in the article for circle vs AABB

Cheers, Paul.

Whorse
Whorse

[quote name='UraniumSlug' timestamp='1314351967' post='4853979']
Cheers Paul, I had a look at your blog, very informative. I was doing some reading last night after I realised my current method of collision detection more than likely wasn't sufficient enough. Am I correct in assuming that the AABB vs AABB example uses a distance based calculation to determine whether the bounding boxes have intersected?

Distance between two AABBs can be found by shrinking on down to a point and expanding the other by the orignal extents of the shrunken one. Then it simplifies to finding the distance between a point and an AABB, which is the same technique I describe in the article for circle vs AABB

Cheers, Paul.
[/quote]

I see what you mean . I just had a read through that too now and it really sheds light on the matter. You have a knack for explaining things in a simple yet very effective manner! I do have two last questions though, what calculations determine the vector that the magnitude is worked out from, and how would one achieve a similar result testing the X and Y axis separately?
wildbunny
wildbunny
I see what you mean . I just had a read through that too now and it really sheds light on the matter. You have a knack for explaining things in a simple yet very effective manner! I do have two last questions though, what calculations determine the vector that the magnitude is worked out from, and how would one achieve a similar result testing the X and Y axis separately?


The vector is simply the vector from the point to the closest point on the AABB, this gives you the direction and also the magnitude (its length)

I don't think you can achieve a similar thing just by considering the X/Y axis because there is a case where the shortest distance between two AABBs in not in an axis direction - consider two AABBs about to touch at one of their corners

Cheers, Paul.
Whorse
Whorse

[quote name='UraniumSlug' timestamp='1314353050' post='4853982']I see what you mean . I just had a read through that too now and it really sheds light on the matter. You have a knack for explaining things in a simple yet very effective manner! I do have two last questions though, what calculations determine the vector that the magnitude is worked out from, and how would one achieve a similar result testing the X and Y axis separately?


The vector is simply the vector from the point to the closest point on the AABB, this gives you the direction and also the magnitude (its length)

I don't think you can achieve a similar thing just by considering the X/Y axis because there is a case where the shortest distance between two AABBs in not in an axis direction - consider two AABBs about to touch at one of their corners

Cheers, Paul.
[/quote]

Understood, that is the ideal method. I don't see why I would check both, after more thought . I could just handle the results of the collision check by checking the speed of X and then Y and handling it accordingly...

Thanks again Paul, when I get a moment I'll be sure to start implementing the discrete method and post my results here!
wildbunny
wildbunny

Understood, that is the ideal method. I don't see why I would check both, after more thought . I could just handle the results of the collision check by checking the speed of X and then Y and handling it accordingly...

Thanks again Paul, when I get a moment I'll be sure to start implementing the discrete method and post my results here!



Np, and its the continuous method you want

Whorse
Whorse
I've been doing a little more reading after your initial comments Paul and have discovered a technique which could solve my issue without having to rewrite my entire system, and that's by performing a sweep test. Does anyone know any good links for performing a sweep test utilising AABB collision detection?
wildbunny
wildbunny

I've been doing a little more reading after your initial comments Paul and have discovered a technique which could solve my issue without having to rewrite my entire system, and that's by performing a sweep test. Does anyone know any good links for performing a sweep test utilising AABB collision detection?


Um... tha'ts kind of what continuous collision detection implies

To sweep one AABB against another you do the shrinking I described above, then instead of distance from point to AABB, you end up ray-casting against the AABB starting from the point and the intersection point and time are the first impact point and time between the two AABBs
Whorse
Whorse
Got home from work and finally had the chance to have a proper read and tackle this. Works a charm, thanks Chris. It wasn't difficult implementing your ideas in my collision code. I see now how continuous collision detection is in fact a sweep.

My issue now is how to handle with the ground. If I constantly exert a force like gravity the character seems to "blur" due to the constant opposing forces of the collision response (which places the character just outside the point of collision) and the downwards force of gravity. Are there any known methods to work around this sort of issue? It only really applies to the ground and other floating obstacles a player can jump on to.
wildbunny
wildbunny

Got home from work and finally had the chance to have a proper read and tackle this. Works a charm, thanks Chris. It wasn't difficult implementing your ideas in my collision code. I see now how continuous collision detection is in fact a sweep.

My issue now is how to handle with the ground. If I constantly exert a force like gravity the character seems to "blur" due to the constant opposing forces of the collision response (which places the character just outside the point of collision) and the downwards force of gravity. Are there any known methods to work around this sort of issue? It only really applies to the ground and other floating obstacles a player can jump on to.


Your collision response code should leave the character with 0 relative normal velocity after the collision has been resolved - check this is the case, and then go from there
Whorse
Whorse
It turns out it was a simple fix. Checking for collisions after moving the character fixed this issue.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.