Right, so first you check for overlapping rectangles (which you've already done). When you find an overlap, then you need to refine the collision test. For each corner of the offending rectangle, compute the distance from the center of your character to the corner of the offending rectangle. If the distance from the center to any of the corners is less than the radius of the circle, then you have a collision. To optimize the code a little bit, compute (dx * dx + dy * dy) and compare that to the radius squared. That way you don't have to compute any square roots.
Upon further review, you also need to do an edge check in addition to the corner check. For example, if the top y
value is above the center of the circle and the bottom y
value is below the center of the circle, then compute the difference in x
between the rectangle left edge and the center of the circle, and if that distance is less than the radius, then a collision has occurred. Likewise for the other three edges of the rectangle.
Here's some pseudo-code for the corner checking
int dx, dy, radius, radiusSquared;
radiusSquared = radius * radius;
for ( each rectangle that overlaps the player rectangle )
{
for ( each corner of the rectangle )
{
dx = corner.x - center.x;
dy = corner.y - center.y;
if ( dx * dx + dy * dy < radiusSquared )
Collision!!!
}
}