Saturday, May 11, 2019

xna - Collision Detection Problems


So I'm making a 2D tile based game but I can't quite get the collisions working properly. I've taken the code from the Platformer Sample and implemented it into my game as seen below.


One problem I'm having is when I'm on the ground for some strange reason I can't move to the left. Now I'm pretty sure this problem is from the HandleCollisions() method because when I stop running it I can smoothly move around with no problems. Another problem I'm having is when I'm close to a tile the character jitters very strangely.


I will try to post a video if necessary. Here is the HandleCollisions() method:


void HandleCollisions() {
Rectangle bounds = BoundingRectangle;

int topTile = (int)Math.Floor((float)bounds.Top / World.PixelTileSize);
int bottomTile = (int)Math.Ceiling((float)bounds.Bottom / World.PixelTileSize) - 1;
int leftTile = (int)Math.Floor((float)bounds.Left / World.PixelTileSize);

int rightTile = (int)Math.Ceiling((float)bounds.Right / World.PixelTileSize) - 1;

isOnGround = false;

for(int x = leftTile; x <= rightTile; x++) {
for(int y = topTile; y <= bottomTile; y++) {
if(world.Map[y, x].Collidable == true) {
Rectangle tileBounds =
new Rectangle(x * World.PixelTileSize, y * World.PixelTileSize,
World.PixelTileSize, World.PixelTileSize);

Vector2 depth = RectangleExtensions.GetIntersectionDepth(bounds,
tileBounds);

if(depth != Vector2.Zero) {
if(Math.Abs(depth.Y) < Math.Abs(depth.X)) {
isOnGround = true;
position = new Vector2(position.X, position.Y + depth.Y);
}
else {
position = new Vector2(position.X + depth.X, position.Y);

}

bounds = BoundingRectangle;
}
}
}
}
...
}

Answer




I saw something like this before in the platformer that I'm developing.


One possibility is that there's a rounding or precision error. If you're using the Rectangle class (in Microsoft.Xna.Framework), you're limited to the precision of integers. Try something equivalent that uses floats.


Also, if you're updating both and x and y positions, then checking for collisions, you might have problems. If that's the case, try moving on one axis at a time, check for collisions, then move on the other axis.


I suggested the same thing in another thread: How to determine collision direction between two rectangles?


Edit: Now that I think about it again, I'm pretty sure doing one axis at a time should solve this problem. But it's still a good idea to use higher precision for your geometries. (You should only be rounding geometry coordinates to integers when it's time to draw graphics.)


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...