I have been trying to get my collision code working for hours now but with every resource I have tried my character still jitters. First I tried using the platformer sample but my character still jittered up and down really quickly, even when standing still. Then I took to these forums and found this post and I used his code and eventually found out that in order for his to work you have to:
- Move the character's position along the x-axis only.
- Check if the character collided with something along the x-axis
Then do the same thing for the y axis. In other words, the character could only move one direction at a time and with my game there are a lot of different forces, velocities, accelerations, et cetera. all pulling on the target at once and this kind of solution didn't really work.
I heavily simplified the code in the sample and ended up with this:
Rectangle playerBounds = GetPlayerBounds(motion.Position.X, motion.Position.Y, characterWidth, characterHeight);
// Get the player's bounding rectangle and find neighboring tiles.
Rectangle bounds = playerBounds;
int leftTile = (int)Math.Floor((float)bounds.Left / TileSize);
int rightTile = (int)Math.Ceiling(((float)bounds.Right / TileSize)) - 1;
int topTile = (int)Math.Floor((float)bounds.Top / TileSize);
int bottomTile = (int)Math.Ceiling(((float)bounds.Bottom / TileSize)) - 1;
for (int y = topTile; y <= bottomTile; ++y) // For each potentially colliding tile,
{
for (int x = leftTile; x <= rightTile; ++x)
{
Tile collision = stage.CustomLayer.GetTile(x, y);
if (collision.Value == Tile.CollisionTile)
{
Vector2 depth = Extensions.GetIntersectionDepth(bounds, collision.Bounds); // Determine collision depth (with direction) and magnitude.
if (depth != Vector2.Zero)
{
if (Math.Abs(depth.Y) < Math.Abs(depth.X)) // Resolve the collision along the shallow axis.
{
motion.Position = new Vector2(motion.Position.X, motion.Position.Y + depth.Y); // Resolve the collision along the Y axis.
}
else // Ignore platforms.
{
motion.Position = new Vector2(motion.Position.X + depth.X, motion.Position.Y); // Resolve the collision along the X axis.
}
bounds = playerBounds; // Perform further collisions with the new bounds.
}
}
}
}
The code produces the jittering effect as well. I have debugged it for hours and I think I found the cause but I do not know how to fix it.
For example, if the character's Y position is 500
and is found to be colliding with a tile with a depth of 5 pixels
, he will be pushed to Y position 495
. At this time, though, the loop will continue based off of old topTile and bottomTile
values and he may still be found to be colliding with those tiles, and will be pushed up to Y position of 490
. Next time this function is called though when the character has moved back down to Y position of 495
due to gravity, he won't be colliding because of different initial topTile and bottomTile
values and will continue moving downwards.
I believe this is what causes the jittering effect but I do not understand why it is happening to me. As far as I know, I am using the same algorithm as everyone else and their code doesn't produce any jittering. All my tiles are of equal size (32x32) and I am using the same GetIntersectionDepth
method found in the platformer sample.
Thanks to anyone who can help me solve this problem.
bounds = playerBounds;
tobounds = GetPlayerBounds(motion.Position.X, motion.Position.Y, characterWidth, characterHeight);
solved the problem. Thank you. \$\endgroup\$