Collision Detection in 2D Side Scroller
I am working on a 2D side scroller which uses bounding boxes (left, top, right, bottom) for collisions on the map and players can move left, right, and jump. The code checks for a collision by using my own version of the IntersectRect() function to check if a player's movement caused him to move into a collision. This check is done after the player has been moved, such as right after moving left and right after falling. If the player was moving left, the player is moved outside of the collision's right side. If the player was falling, the player is moved on top of the collision, etc.
Due to time based modeling, a player's position may increase more or less then in the previous frame depending on how fast the previous frame was processed. I recently found out that this was causing the same set of inputs to produce different results, which is not a good thing.
The problem is that if you are falling at an angle towards the corner of a collision (this problem may happen in other circumstances as well), the player is moved to the left/right first and lets say it's enough to trigger a collision. This causes the player to hit the right/left side of the collision and then fall down the side. However, if the player is moved a shorter distance to the left/right because of time based modeling, it doesn't detect a collision. The player is then moved downwards and it detects that he collided with the collision. Since he was moving downwards, the player is put on top of the collision and walks on top of it.
Any help would be greatly appreciated.
perhaps you can maintain a simple x,y movement vector and then reverse it by just enough to get the object outside the collision zone when a contact is detected. Then you are dealing with both the x and y at the same time instead of chunky style IF ( moving down ) { move back up } kinds of things.
So if the player was falling to the right, the movement vector might be V = (2,5). If a collision is detected and it's determined that you are half-way into the object, you move back ward by half the vector
xpos += V.x * -0.5;
ypos += V.y * -0.5;
So if the player was falling to the right, the movement vector might be V = (2,5). If a collision is detected and it's determined that you are half-way into the object, you move back ward by half the vector
xpos += V.x * -0.5;
ypos += V.y * -0.5;
Thanks for the reply!
The idea sounds good, but I have a question: If the player is in the collision 4 pixels on the X axis and 2 pixels on the Y axis with a velocity of (10, 10), would you move backwards 4 pixels (40%) from both X and Y, or would you move 4 pixels (40%) backwards on the X axis and 2 pixels (20%) backwards on the Y axis? Basically, should both velocities backtrack by the same percentage?
The idea sounds good, but I have a question: If the player is in the collision 4 pixels on the X axis and 2 pixels on the Y axis with a velocity of (10, 10), would you move backwards 4 pixels (40%) from both X and Y, or would you move 4 pixels (40%) backwards on the X axis and 2 pixels (20%) backwards on the Y axis? Basically, should both velocities backtrack by the same percentage?
Quote:Original post by VBStrider
Due to time based modeling, a player's position may increase more or less then in the previous frame depending on how fast the previous frame was processed. I recently found out that this was causing the same set of inputs to produce different results, which is not a good thing.
Fix your timestep.
Otherwise you will never really get the same behaviour on two runs of the same simulation. With more complex physics sims this can become a major problem but in a simple 2D scroller, biggest issue with time based modelling is that it is almost impossible to get jumps to stay the same height.
Apparently one of the old Quake games suffered from this - you could jump slightly further at a higher refresh (or disabled vsync).
Thanks EasilyConfused, that should solve part of the problem :).
I want to use leiavoia's idea as well though, so my previous question still stands.
I want to use leiavoia's idea as well though, so my previous question still stands.
Quote:Original post by VBStrider
Thanks for the reply!
The idea sounds good, but I have a question: If the player is in the collision 4 pixels on the X axis and 2 pixels on the Y axis with a velocity of (10, 10), would you move backwards 4 pixels (40%) from both X and Y, or would you move 4 pixels (40%) backwards on the X axis and 2 pixels (20%) backwards on the Y axis? Basically, should both velocities backtrack by the same percentage?
Well, i would think you would want to backtrack by the minimum amount necessary to remove Object A from Object B. The key to remember is that if you are working with vectors, you move in a direction in space, not "so many pixels up, so many pixels left," even though that is what it finally boils down to.
So anyway, if A overlaps B by 4 pixels on the x-axis and 2 pixels on the y-axis and the velocity was 10,10 (perfectly diagonal), you would have to backtrack x -= 4, y -= 4, because x -= 2, y -= 2 would not entirely remove A from B.
If the movement vector was not proportional (10,10), you would have to scale one axis or the other to match the vector. If you were moving at 10,5 with the previous example, x -= 4, y -= 2 would work perfectly.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement