# How to make top-down AABB collision response work properly in MonoGame?

I have a problem with top-down racing game I'm working on. I need to implement AABB collision with other cars and objects. But when going fast enough, the car can go through thin objects when hitting top and left sides or bottom right corner if the surface is limited with colliders on each side. Here's da codez of collision response:

private void OnCollision(BoundsCollider sender, BoundsCollider collider)
{
// TODO: question stackexchange gamedev what's wrong with left and top
// maybe i should compare the center point...
if (sender.Rect.Left < collider.Rect.Right) // right
{
sender.GameObject.Transform.Position += new Vector2(1, 0);
if (GameObject.IsAI)
{
if (collider.GameObject != null)
{
Velocity = new Vector2(-collider.GameObject.Rigidbody.Velocity.X, Velocity.Y);
}
else
{
Velocity = new Vector2(-Velocity.X, Velocity.Y);
}
AngularVelocity = 0.01f;
}
else
{
Velocity = new Vector2(-Velocity.X, Velocity.Y);
}
}
else if (sender.Rect.Right >= collider.Rect.Left) // left (working wrong)
{
sender.GameObject.Transform.Position += new Vector2(-1, 0);
if (GameObject.IsAI)
{
if (collider.GameObject != null)
{
Velocity = new Vector2(-collider.GameObject.Rigidbody.Velocity.X, Velocity.Y);
}
else
{
Velocity = new Vector2(-Velocity.X, Velocity.Y);
}
AngularVelocity = -0.01f;
}
else
{
Velocity = new Vector2(-Velocity.X, Velocity.Y);
}
}
if (sender.Rect.Top < collider.Rect.Bottom) // bottom
{
sender.GameObject.Transform.Position += new Vector2(0, 1);
if (GameObject.IsAI)
{
if (collider.GameObject != null)
{
Velocity = new Vector2(Velocity.X, -collider.GameObject.Rigidbody.Velocity.Y);
}
else
{
Velocity = new Vector2(Velocity.X, -Velocity.Y);
}
}
else
{
Velocity = new Vector2(Velocity.X, -Velocity.Y);
}
}
else if (sender.Rect.Bottom >= collider.Rect.Top) // top (working wrong)
{
sender.GameObject.Transform.Position += new Vector2(0, -1);
if (GameObject.IsAI)
{
if (collider.GameObject != null)
{
Velocity = new Vector2(Velocity.X, -collider.GameObject.Rigidbody.Velocity.Y);
}
else
{
Velocity = new Vector2(Velocity.X, -Velocity.Y);
}
}
else
{
Velocity = new Vector2(Velocity.X, -Velocity.Y);
}
}
}


How do I do it right? If you'll need the whole project, I'll share one with you.

BTW I also use MonoGame.Extended for RectangleF and other stuff

UPD: I've partually fixed it but now you can get out from the corners. How do I fix this? Don't suggest intersection, it doesn't work right (when colliding the wall from left/right, it sends you up and down)

    private void OnCollision(BoundsCollider sender, BoundsCollider collider)
{
if (sender.Rect.Center.X > collider.Rect.Center.X) // right
{
sender.GameObject.Transform.Position += new Vector2(1, 0);
if (GameObject.IsAI)
{
if (collider.GameObject != null)
{
Velocity = new Vector2(-collider.GameObject.Rigidbody.Velocity.X, Velocity.Y);
}
else
{
Velocity = new Vector2(-Velocity.X, Velocity.Y);
}
AngularVelocity = 0.01f;
}
else
{
Velocity = new Vector2(-Velocity.X, Velocity.Y);
}
}
else if (sender.Rect.Center.X < collider.Rect.Center.X) // left
{
sender.GameObject.Transform.Position += new Vector2(-1, 0);
if (GameObject.IsAI)
{
if (collider.GameObject != null)
{
Velocity = new Vector2(-collider.GameObject.Rigidbody.Velocity.X, Velocity.Y);
}
else
{
Velocity = new Vector2(-Velocity.X, Velocity.Y);
}
AngularVelocity = -0.01f;
}
else
{
Velocity = new Vector2(-Velocity.X, Velocity.Y);
}
}
if (sender.Rect.Center.Y > collider.Rect.Center.Y) // bottom
{
sender.GameObject.Transform.Position += new Vector2(0, 1);
if (GameObject.IsAI)
{
if (collider.GameObject != null)
{
Velocity = new Vector2(Velocity.X, -collider.GameObject.Rigidbody.Velocity.Y);
}
else
{
Velocity = new Vector2(Velocity.X, -Velocity.Y);
}
}
else
{
Velocity = new Vector2(Velocity.X, -Velocity.Y);
}
}
else if (sender.Rect.Center.Y < collider.Rect.Center.Y) // top
{
sender.GameObject.Transform.Position += new Vector2(0, -1);
if (GameObject.IsAI)
{
if (collider.GameObject != null)
{
Velocity = new Vector2(Velocity.X, -collider.GameObject.Rigidbody.Velocity.Y);
}
else
{
Velocity = new Vector2(Velocity.X, -Velocity.Y);
}
}
else
{
Velocity = new Vector2(Velocity.X, -Velocity.Y);
}
}
}


But the problem is left and right still work wrong. After a bit of testing various cases (I'd create two 10x10 RectangleFs, one of them is at (0;0) while another one is at (5;0) and write in the VS debug output console. It wrote {X: 0, Y: 0, Width: 0, Height: 10! The width is 0 when it supposed to be 5! It was clearly a Monogame.Extended bug. I've reported it: https://github.com/craftworkgames/MonoGame.Extended/issues/414