I've just worked out an AABB collision algorithm for my 2D game and I was very satisfied until I found out it only works properly with movements of 1 in X and 1 in Y... here it is:
public bool Intersects(Rectanglef rectangle)
{
return this.Left < rectangle.Right && this.Right > rectangle.Left && this.Top < rectangle.Bottom && this.Bottom > rectangle.Top;
}
public bool IntersectsAny(params Rectanglef[] rectangles)
{
for (int i = 0; i < rectangles.Length; i++)
{
if (this.Left < rectangles[i].Right && this.Right > rectangles[i].Left && this.Top < rectangles[i].Bottom && this.Bottom > rectangles[i].Top)
return true;
}
return false;
}
and here is how I use it in the update function of my player :
public void Update(GameTime gameTime)
{
Rectanglef nextPosX = new Rectanglef(AABB.X, AABB.Y, AABB.Width, AABB.Height);
Rectanglef nextPosY;
if (Input.Key(Key.Left))
nextPosX.X--;
if (Input.Key(Key.Right))
nextPosX.X++;
bool xFree = !nextPosX.IntersectsAny(Boxes.ToArray());
if (xFree)
nextPosY = new Rectanglef(nextPosX.X, nextPosX.Y, nextPosX.Width, nextPosX.Height);
else
nextPosY = new Rectanglef(AABB.X, AABB.Y, AABB.Width, AABB.Height);
if (Input.Key(Key.Up))
nextPosY.Y--;
if (Input.Key(Key.Down))
nextPosY.Y++;
bool yFree = !nextPosY.IntersectsAny(Boxes.ToArray());
if (yFree)
AABB = nextPosY;
else if (xFree)
AABB = nextPosX;
}
What I'm having trouble with, is a system where I can give float values to my movement and make it so there's a smooth acceleration. Do I have to retrieve the collision rectangle (the rectangle created by the other two colliding)? or should I do some sort of vector and go along this axis until I reach the collision?
Thanks a lot!