Okay so, i have a tiled map (obviously) and implemented a collision detection system which is working really well for me. It has trouble with those pesky corners though. I do know why that is, since i don't even check the corners. And that's the point, i don't know how to do that. So, first of all here is my current code:
Body body = currentObject.Body; // Body is a class storing position, velocity, bounds and so on.
int tileDimensions = level.TileWidth; // Since the tiles are squares...
int leftTile = body.Bounds.Left / tileDimensions;
int topTile = body.Bounds.Top / tileDimensions;
int rightTile = (int)Math.Ceiling((float)body.Bounds.Right / tileDimensions - 1);
int bottomTile = (int)Math.Ceiling(((float)body.Bounds.Bottom / tileDimensions) - 1);
if (body.Velocity.Y > 0) // Moving down.
{
for (int x = leftTile; x <= rightTile; x++)
{
for (int y = bottomTile + 1; y <= (bottomTile + 1) + (body.Velocity.Y / tileDimensions); y++)
{
if (tiles[x, y] != null && !tiles[x, y].IsPassable)
{
newVelocity = new Vector2(body.Velocity.X, MathHelper.Clamp(body.Velocity.Y, 0, tiles[x, y].Body.Bounds.Top - body.Bounds.Bottom));
body.Velocity = newVelocity;
break;
}
}
}
}
So thats just for moving down. There are 3 other constructs like that for up, left and right. The only real difference is the loop and the way i clamp the velocity.
As you can see i just loop through all tiles i could potentially collide with. Then i clamp the velocity, which will slow it down in case there is indeed a tile in it's way.
Now, i'm afraid it's hard to explain my problem with just words, so i'll have to post a picture too.

In this screenshot yellow means unpassable tile, black are the tiles the above code is currently checking for collision and red is the player.
To show you what the problem is, imagine i were to accelerate up and right in this frame. As you can see, there would be a collision with the tile on the upper right of my player but the player will just move into the tile since i don't check it for collision. And i will not check it in the next frame either, since i don't check for blocks i'm in because ... i don't even know, that would betray the whole idea behind my code, wouldn't it ? :P
Of course, i could just extend my "searching" range, but then i would collide with tiles, i shouldn't collide with. Currently, i'm fixing this with an extra check for all the tiles my bounds are overlapping with and... you know, just moving the player back if i find any. But this is really messy and it doesn't preserve the initial velocity. If the player hits a corner he will move into it, i will detect that, move him back and null his velocity. That just doesn't feel right, it's clunky.
I just can't seem to figure out a good way of dealing with such cases. I doesn't happen too often (since it's really hard to reproduce) but once in a while it happens and that is of course unacceptable.
I'd really like to not even have a bugfix-type thing for it but to integrate it in my other code as nicely as possible. This is not mandatory, but it would be cool to be able to do that. So i'd really appreciate if anyone of you guys could throw something at me.
Anyway, i hope you were able to follow what i was trying to say. Since english isn't my native language it's a little hard to explain such things at times. Also i'm just really bad at explaining things :/