# 2D Collision detection issues frustrating me

This topic is 3007 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Okay here's the deal, I've been working on this 2-D platform game in my spare time for about the past month. I've just implemented 'gravity' and attempted to polish up the collision detection in the past day. I'm running primarily on caffeine and as I'm sure a lot of you know you lose quite a bit of your clarity of thought when you hit the 35 hour mark with no sleep. :P I'm sure this isn't a difficult problem I think I've just been staring at my own code for so long that I can't seem to find the problem. I've got a few theories about where the problem is but I just can't put it together in my sleep deprived brain. The exact issue is hard to describe as there's quite a few bugs I've noticed. 1) The if statement that checks to see if the left side of the main character has collided with a solid object seems to always evaluate to true when the character is standing on an object. (eg. Currently the character starts off well above the floor of the screen (I was testing gravity) and so he falls off the start until he hits the floor....as soon as he hits the floor my character starts sliding right). He's supposed to move right 5 pixels upon colliding with an object to his left (to push him out of the object). However, he just keeps going right until he hits another solid object....at which point he teleports to the top of the solid object....which is far from desirable. Left and right collision detection worked fine until I implemented gravity and top and bottom collision detection. Okay...it's going to be difficult to describe these...it'd be easier to just show you. Here's a link to the Windows executable: http://highowl.freetzi.com/rje/bin/rje_win.zip and it's source code: http://highowl.freetzi.com/rje/src/rje_src.zip I'm fairly sure the problem lies in 'game.cpp' in the function 'check_collisions()'. (This function is near the bottom [3rd from bottom I'm pretty sure]). If someone could take a look at it I'd be very grateful. I warn you though - I'm not very experienced in either C++ or programming games, so If you look at my code and you think "Why the f*ck did he do that this way" or "Wow, way to over-complicate things dipsh*t" the answer is going to be ignorance. I am very open to criticism and I fully welcome you to be as brutal as you'd like - Hell tell me I approached the entire game the wrong way or whatever you'd like, as long as you tell me why lol. This game is more or less a learning experience for me so anything I could've done better will only help future projects. NOTE: In 'game.cpp' in the function 'check_collisions()' under the section commented "LEFT" - comment out the line that says
rastamon.pos_x = rastamon.pos_x + 5;


to prevent the character from sliding right after he hits the ground. If it's not already commented out....if it is, uncomment it and re-compile and see what I'm talking about. Oh and one more thing, this program uses the allegro game library with jpgalleg and alfont - so you're going to need those libraries if you want to compile.

##### Share on other sites
Just a wild guess (after 5 hours of tetris coding, I'm a bit sleepy):

According to Separating Axis Theorem, you can determine the collision axis by determining the minimal penetration axis, so the axis where the collision is most likely to happen is the axis, where the collision depth is the smallest.

You see, if two objects collide, there will be always two colliding sides (for example up and left).

I hope that has something to do with your problem.
-------|     ||   -------|   ! !   ||   ! !   ||   ! !   |----!--   |    |     |    -------
You can see, that the '!' is the colliding side, and the axis is the horizon. And in this case you know, that the character needs to be moved back to the left, instead of moving on top of the box.

##### Share on other sites
I know I've read about that before but I decided to just do it simple. Pretty much the same concept though.

The way I do it is if the left side of the character enters the right side of a solid object he is ejected to the right by the same distance that he moves and the opposite for the other side. Same goes for when the character is falling except when the character lands on a solid surface it sets his position to put his feet on the solid object......which I just realized is somewhat problematic and explains the bug where when my character hits a left or right collision he teleports to the top of it....DOH Maybe I should move the downward collision detection to be after the left/right collision detection.

On the other hand I still have no f*cking clue why he floats right when he lands. Anyone have any idea?

I think I'm done coding for right now....time to vent my frustrations in COD4...so on a side-note if anyone has a PS3 and a copy of COD4 lying around add me...PSN ID: HighOwl and we can kick some ass and chew bubblegum lol

##### Share on other sites
But how do you know which side is colliding?
You see there will always be 2 sides colliding.

You don't decide this nowhere.

box-box collision:
//x: horizon, y: upbool check_collision(*depth_x,*depth_y){    bool is_collision = true;    // along x axis    if( static_box.right < moving_box.left || static_box.left > moving_box.right )        is_collision = false;  // no collision in 'x'    // along x axis    if( static_box.top < moving_box.bottom || static_box.bottom > moving_box.top )        is_collision = false;  // no collision in 'y'                        //if there's collision, it will be on both axis                        //if no collision, no collision on either of the axis        if( is_collision == false )        return false;   //no collision    if( static_box.right < moving_box.right ) // moving box comes from the right        *depth_x = static_box.right - moving_box.left; //will be>0    else        *depth_x = static_box.left - moving_box.right; //will be<0    if( static_box.top < moving_box.top )   // moving box comes from the top        *depth_y = static_box.top - moving_box.bottom; //will be>0    else        *depth_y = static_box.bottom - moving_box.top; //will be<0    return true;}if( check_collision(depth_x,depth_y) == true ){    if( abs(depth_x) > abs(depth_y) )        moving_box.position_y += depth_y;    else        moving_box.position_x += depth_x;}
Haven't tested it, it may have sign problems.