I have difficulties with the rectangle collision. My character can go through the right side and through the bottom of each platform rectangle. I guess their is a mathematical problem with the collision, but I don't know what is wrong.
What should I change? I want to do a little platformer, something like the old Mario games.
Backgrounds.LevelTilesList is a list of type RectangleF. Every tile in the level is saved in this list.
Vector2 Player_Gravity = new Vector2(0, 4.5f);
Vector2 Player_Movement = new Vector2();
Vector2 Player_Size = new Vector2(29, 80);
System.Drawing.RectangleF Player_RectF = new System.Drawing.RectangleF(100, 100, 29, 80);
System.Drawing.RectangleF Player_NewRect;
bool collisionTop, collisionBottom, collisionRight, collisionLeft;
protected override void Update(GameTime gameTime)
{
KeyboardState currentkeyState = Keyboard.GetState();
if (currentkeyState.IsKeyDown(Keys.Left))
Player_Movement.X -= 5;
if (currentkeyState.IsKeyDown(Keys.Right))
Player_Movement.X += 5;
if (currentkeyState.IsKeyDown(Keys.Up))
Player_Movement.Y -= 10;
if (currentkeyState.IsKeyDown(Keys.Down))
Player_Movement.Y += 10;
Player_Movement += Player_Gravity;
// Calculate new position
Player_NewRect = Player_RectF;
Player_NewRect.X += Player_Movement.X;
Player_NewRect.Y += Player_Movement.Y;
// check for collision
for (int j = 0; j <= Backgrounds.LevelTilesList.Count - 1; j++)
{
if (Player_NewRect.IntersectsWith(Backgrounds.LevelTilesList[j]))
{
float halfBoxWidth = Backgrounds.LevelTilesList[j].Width * 0.5f;
float halfBoxHeight = Backgrounds.LevelTilesList[j].Height * 0.5f;
float halfBoxPlayerWidth = Player_NewRect.Width * 0.5f;
float halfBoxPlayerHeight = Player_NewRect.Height * 0.5f;
Vector2 posDiff = new Vector2((int)((Backgrounds.LevelTilesList[j].X + halfBoxWidth) - (Player_NewRect.X + halfBoxPlayerWidth)), (int)((Backgrounds.LevelTilesList[j].Y + halfBoxHeight) - (Player_NewRect.Y + halfBoxPlayerHeight)));
float maxDiffX = halfBoxWidth + halfBoxPlayerWidth;
float maxDiffY = halfBoxHeight + halfBoxPlayerHeight;
collisionTop = posDiff.Y < -halfBoxHeight &&
posDiff.Y > (maxDiffY) * -1
&&
!collisionRight && !collisionLeft;
collisionBottom = posDiff.Y > halfBoxHeight &&
posDiff.Y < maxDiffY
&&
!collisionRight && !collisionLeft;
collisionLeft = posDiff.X < -halfBoxWidth &&
posDiff.X > maxDiffX * -1 &&
!collisionBottom && !collisionTop;
collisionRight = posDiff.X > halfBoxWidth &&
posDiff.X < maxDiffX &&
!collisionBottom && !collisionTop;
if (collisionTop || collisionBottom)
Player_Movement.Y *= -0.5f;
if (collisionLeft || collisionRight)
Player_Movement.X *= -0.5f;
// Adjust the position
if (collisionBottom)
{
Player_NewRect.Y -= Player_NewRect.Bottom - Backgrounds.LevelTilesList[j].Top;
}
if (collisionTop)
{
Player_NewRect.Y += Player_NewRect.Top - Backgrounds.LevelTilesList[j].Bottom;
}
if (collisionLeft)
{
Player_NewRect.X += Player_NewRect.Left - Backgrounds.LevelTilesList[j].Right;
}
if (collisionRight)
{
Player_NewRect.X -= Player_NewRect.Right - Backgrounds.LevelTilesList[j].Left;
}
}
}
Player_RectF = Player_NewRect;
Player_Movement = new Vector2(0, 0);
base.Update(gameTime);
}