Collision Response

Started by
12 comments, last by BeerNutts 12 years, 3 months ago
Hi, Again I am on collisions. Ok, so this is what I want to do:

If a collision occurs at the bottom of my player, I want to stop the Y increment.
If a collision occurs at either side of my player, I want to stop the X increment.

I have the code in place which will return a vector of the position at which a pixel collides. I have been trying for quite a while now to do this seemingly simple task. I have access to the point of collision, and both colliding objects' position and size.

I should point out, that the resulting vector for the collision point is based on a projected matrix which tests for pixel collision.

I have tried nearly every variation that comes to me.
Making sure the players Xbounds are outside the other objects, meaning a side collision had occured.
Making sure the players Xbounds were in the same range as the objects, and that its Yvalue was less(Top collision)


I tried numerous ways with the collision point. Tried to code it to find out if the point of collision was at the bottom/top/left/right of the player (this is what I want to achieve, it seems the best approach)

But everything I have done just seemed to fail, It would work on top,bottom and 1 side. It would work on both sides,bottom and not top etc.

Any help appreciated.
Advertisement
Any tips?
You can store the previous position of the object you are testing for and in the result of a collision set the new position to the old one.

so something like this:

oldPosition = Position;

MovePlayer

if a collision occurs()
{
Position = oldPosition;
}


You can store the previous position of the object you are testing for and in the result of a collision set the new position to the old one.

so something like this:

oldPosition = Position;

MovePlayer

if a collision occurs()
{
Position = oldPosition;
}




I don't see how that will work for me, Each update I implement gravity by increasing the yincrement over time. I need the Y to be set to 0 when a collision occurs, otherwise it will keep falling through the floor. But, I cant really just set y to 0 when I find a collision because then if the player collides with the side of a platform for example, he will stick to it.

This is currently my update method of a base CollidableObject class:

increment.y += gravity * acceleration * deltaTime

check collision using projected matrix(based on x and y increments)


if(no collision will occur)
move it


So what way will I structure it so I can use the oldPosition way to resolve collisions, so the gravity stops incrementing when I am on a platform?
I'll give this one last bump too see if anyone can give me more advice.
Break the oldPosition into x and y components, and go back to oldX if an X collision occurs, and go back to oldY if a Y collision occurs:



// move our object
OldPosition = OurObjectPos;
OurObjectPos.X += Velocity.X * deltaTime;
OurObjectPos.Y += Velocity.Y * deltaTime;

// check for collision in X direction
if (CheckXCollision(OurObjectPos) == true) {
// go back to old place, and stop X velocity
OurObjectPos.X = OldPosition.X;
Velocity.X = 0;
}


// check for collision in Y direction
if (CheckYCollision(OurObjectPos) == true) {
// go back to old place, and Set Y velocity to Gravity
// This way, if jumping, and we hit our head, velocity will go back to gravity and we fall
// and it will handle us walking off end of platform
OurObjectPos.Y = OldPosition.Y;
Velocity.Y = Gravity;
}


Something like that.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)


Break the oldPosition into x and y components, and go back to oldX if an X collision occurs, and go back to oldY if a Y collision occurs:



// move our object
OldPosition = OurObjectPos;
OurObjectPos.X += Velocity.X * deltaTime;
OurObjectPos.Y += Velocity.Y * deltaTime;

// check for collision in X direction
if (CheckXCollision(OurObjectPos) == true) {
// go back to old place, and stop X velocity
OurObjectPos.X = OldPosition.X;
Velocity.X = 0;
}


// check for collision in Y direction
if (CheckYCollision(OurObjectPos) == true) {
// go back to old place, and Set Y velocity to Gravity
// This way, if jumping, and we hit our head, velocity will go back to gravity and we fall
// and it will handle us walking off end of platform
OurObjectPos.Y = OldPosition.Y;
Velocity.Y = Gravity;
}


Something like that.



Yes, Thats what I was attempting in the first place, But I cant seem to find a good way of determining if it was an X or Y collision. I tried determining it using the rectangle test before the pixel test etc. But it doesn't seem to work flawlessly. And I also was trying to think of a way to do it using the exact point of collision. I guess my main question is what is the best way of determining if its an X or Y collision


// move our object
OldPosition = OurObjectPos;
OurObjectPos.X += Velocity.X * deltaTime;

// check for collision in X direction
if (CheckCollision(OurObjectPos) == true) {
// go back to old place, and stop X velocity
OurObjectPos.X = OldPosition.X;
Velocity.X = 0;
}

OurObjectPos.Y += Velocity.Y * deltaTime;

// check for collision in Y direction
if (CheckCollision(OurObjectPos) == true) {
// go back to old place, and Set Y velocity to Gravity
// This way, if jumping, and we hit our head, velocity will go back to gravity and we fall
// and it will handle us walking off end of platform
OurObjectPos.Y = OldPosition.Y;
Velocity.Y = Gravity;
}



Move the object in the X direction 1st, then check for collision.
Move the object in Y direction, then Check for collision.
Would that not work?

I obviously screwed up when I put my pseudo-code. I modified it above in the quoted section

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)




// move our object
OldPosition = OurObjectPos;
OurObjectPos.X += Velocity.X * deltaTime;

// check for collision in X direction
if (CheckCollision(OurObjectPos) == true) {
// go back to old place, and stop X velocity
OurObjectPos.X = OldPosition.X;
Velocity.X = 0;
}

OurObjectPos.Y += Velocity.Y * deltaTime;

// check for collision in Y direction
if (CheckCollision(OurObjectPos) == true) {
// go back to old place, and Set Y velocity to Gravity
// This way, if jumping, and we hit our head, velocity will go back to gravity and we fall
// and it will handle us walking off end of platform
OurObjectPos.Y = OldPosition.Y;
Velocity.Y = Gravity;
}



Move the object in the X direction 1st, then check for collision.
Move the object in Y direction, then Check for collision.
Would that not work?

I obviously screwed up when I put my pseudo-code. I modified it above in the quoted section





Don't really want to be doing 2 pixel tests per update though. And if I do that for a bounding box test it will not work for complex shapes.

[quote name='BeerNutts' timestamp='1324583241' post='4896618']


// move our object
OldPosition = OurObjectPos;
OurObjectPos.X += Velocity.X * deltaTime;

// check for collision in X direction
if (CheckCollision(OurObjectPos) == true) {
// go back to old place, and stop X velocity
OurObjectPos.X = OldPosition.X;
Velocity.X = 0;
}

OurObjectPos.Y += Velocity.Y * deltaTime;

// check for collision in Y direction
if (CheckCollision(OurObjectPos) == true) {
// go back to old place, and Set Y velocity to Gravity
// This way, if jumping, and we hit our head, velocity will go back to gravity and we fall
// and it will handle us walking off end of platform
OurObjectPos.Y = OldPosition.Y;
Velocity.Y = Gravity;
}



Move the object in the X direction 1st, then check for collision.
Move the object in Y direction, then Check for collision.
Would that not work?

I obviously screwed up when I put my pseudo-code. I modified it above in the quoted section





Don't really want to be doing 2 pixel tests per update though. And if I do that for a bounding box test it will not work for complex shapes.
[/quote]

If you are doing any sort of spatial hashing, then a bounding-box test, then pixel-level collision, I SERIOUSLY doubt you'd see a performance hit.

If you're world (or level) isn't that large and/or you odn't have too many collideable objects, I bet you could even get by without spatial hashing.

Years ago (2001), I wrote a space-shooter, and it did a bounding box test, then a pixel-perfect test (using load-time bit-masks from the sprites), and i never saw any performance hits. And, I was doing a lot of other stuff. AND, this was over 10 years ago.

So, if you find a better method (which, using a 2d-physics library is a better method, see my sig for an example), go for it, otherwise, I'd bet you don't ave performance issues.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

This topic is closed to new replies.

Advertisement