Public Group

# Collision detection SDL (yes, another thread) (

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

## Recommended Posts

I believe i am going insane. I have been trying to get my 2D platform engine to work with collisions for the past two weeks now, and i get all theese strange bugs, and I think i have re-written my code about 7000-somthing times. I am on the brink of insanity. While walking the streets i practically expect to suddenly start clipping into the sidewalk. Jokes aside. I need help. Bad. I have the shell of my engine with a CEntityManager (containing CEntities ofcourse), using an onRender()-function. onRender() iterates through my entityMap, and checks for each CEntity if that entity is inside the screen ( I use scrolling). If that CEntity is in fact inside the screen, i have a second iteration through the CEntity-map and looks if "it" in some way overlaps with "jt". If so i call the function onCollision() in it->second(the current CEntity). So far I've been testing out the collision only with entities, in a desperate atempt to keep my sanity. My test has been between the player character, and a CEntity called "platform" wich is just that. A red platform. I have faked gravity so my controlling works nice, and i have even managed to collide with the platform from the sides, but whenever I jump onto the platform the player character just starts to "bounce" back and forth. (probably because whenever a CEntity collides with another(from above) I set the colliding CEntitys Yposition -= m_Yvel, and the same for X-collisions. I can feel that I am doing everything completely wrong, so would someone please point me in the right direction?? I can provide code i necessary, but right now it is located on my working pc, and not on the one i'm currently thrusting my fists upon. Thank you. merry X-mas.

##### Share on other sites
What you should do, me speaking as a relatively inexperienced programmer, is figure out what direction the player is coming from, and if he collides, instead of 'undoing' that collision, make the player be equal to the platform.

Here's some code that illustrates what I mean:
HandleCollisionsWithPlatform(int playerX, int playerY, int velocityX, int velocityY){    //Check if the player's new location is colliding with the platform.    if( CheckIfInsidePlatform(playerX + velocityX, playerY + velocityY) == false )    {         //The player is not colliding, so set the current location to the new location.         playerX = playerX + velocityX;         playerY = playerY + velocityY;    }    else    {        //If the player IS colliding, set the player to be flat against the platform.                //Check what direction the player is coming from.        if( CheckIfInsidePlatform(playerX, playerY + velocityY) == true )        {            if( velocityY > 0)            {                //Player if falling downward.                                //Make the player stand flat ontop of the platform.                playerY = (platformY - playerHeight);            }            else if( velocityY < 0)            {                //Player is heading up.                                //Make the player hit his head on the platform.                playerY = (platformY + platformHeight);            }        }        if( CheckIfInsidePlatform(playerX + velocityX, playerY) == true )        {            if( velocityX > 0)            {                //Player is heading to the right.                                //Make the player collide with the left side of the platform.                playerX = (platformX - playerWidth);            }            else if( velocityX < 0)            {                //Player is heading to the left.                                //Make the player collide with the right side of the platform.                playerX = (platformX + platformWidth);            }        }    }}
(Code has not been compiled or tested for bugs: It's psuedo-code, not copy+paste code)

Now you'll want to integrate it a bit more cleanly than just tossing it all into a function like that; the function was just to show you how colliding was done, and should not be taken as a example of how you'd integrate it into your engine.

##### Share on other sites
You have to check that the colliding object is actual moving towards the collision, and not just touching it (if you're just going to negate the velocity). Otherwise, if he doesnt stop touching the platform in the next frame, then he's going to negate his velocity again, and end up ping ponging on the surface of the platform.

if (player is touching platform && player is moving towards platform) set player to move away from platform;

I usually like to mention this sniplet of code, i have no idea if it works or not :P
foreach (Contact c in player.Contacts) if (Dot(player.Velocity, c.Normal) <= 0)   player.Velocity = Project(player.Velocity, c.Plane);

Ultimately you just dont want to negate the velocity, there are a lot more proper ways.
For ex:
foreach (Contact c in player.Contacts) if (Dot(player.Velocity, c.Normal) <= 0)   player.Velocity -= Project(player.Velocity, c.Normal) * (1+player.Restitution);

##### Share on other sites
Yes, i have understood that THAT is way way to do it, or at least some kind of version of it, and it is by that method I have tried several thousands of times, but for some reason it just isnt that easy. But i could be me that simply is missing something. Another weird error arises while doing so.
I can recall that i one time succeded with this, and my new bug was that, while standing on the platform everything worked out nice, but if I walked of the platform, i jsut stayed on that same Y-value, when the Player were supposed to fall.

##### Share on other sites
Quote:
 Original post by nomonkeybusinessAnother weird error arises while doing so. I can recall that i one time succeded with this, and my new bug was that, while standing on the platform everything worked out nice, but if I walked of the platform, i jsut stayed on that same Y-value, when the Player were supposed to fall.

Check the player's position at the beginning of each tick. If nothing is under the player, then apply gravity. If gravity is already being applied, increase it so the player falls faster. (But have a maximum gravity so you don't fall too fast)

Note that this gravity will affect your jumping as well. Don't do this:
if( nothingIsUnderPlayer() )    yVel = someValue;
Because when you jump, nothing would be under the player, and the player's jump would automaticly be canceled.

if( nothingIsUnderPlayer() )    yVel = yVel + someValue;

That way, it adds to the player's downward motion, fighting against the player's upward motion, mimic-ing real life; instead of automaticly overriding the player's upward motion.

To make a player jump, you first check if he's not falling or jumping already. (Should be easy, just check if yVel is 0)
Then, when the player presses a button, you set yVel to some (negative) high number pushing the player upward. Let's just say, -50, but it'd require tweaking for you to get it to feel how you want it.

The player shoots into the air, because of the upward velocity, but because nothing is under him and we keep on increasing his downward velocity, his upward velocity is continually slowing down, until he starts to fall back to the ground.

Here's a walkthrough scenario of a player jumping:
Player presses 'space' to jumpif yVel is 0, it means the player isn't falling or jumpingSince yVel is 0, we set yVel to a high negative number like -50Each tick, the player moves higher into the air because of yVel's negative valueEach tick, because nothing is under the player, we add a small positive value to yVel (like +5)Therefore, the player's ascent starts to slow downAfter a few ticks, the player's yVel (automaticly) goes from yVel < 0 to yVel == 0 and then to yVel > 0Once yVel goes above 0, the player starts to fall back to the groundAs yVel goes higher above 0, the player starts falling fasterWhen the player collides with the platform or another object, set yVel to 0Because yVel is 0, the player has stopped, and is standing on the ground or a platform again.

• 9
• 23
• 10
• 19