EDIT: this code if from SFML2, but the functions all still exist in 1.6, just with a different capitalisation, ie. sf::Rect<T>::Intersects().
So why aren't you just using Rect1.intersects(Rect2)?
You can compare the positions or origins of the two rects to find out which side was responsible for the collision.
Here's one of the collision functions from my project. I do the x movement and y movement separately(for a different reason).
We use the built in intersection function to detect the collision. And pass the collision area into another rect called gap using
this version of the intersect function(which turns out to be one of my favorite functions).
Then we can deduct the gap rect from our position in order to undo the move, until we are pushed right up against the object we collided with, but not overlapping.
The goal of this function was to remove the jitter associated with movement collision, it resulted in a really smooth movement, where objects can push against and slide along other objects, without going through or without any noticeable jitter.
sf::Vector2f Area::TryMoveY(sf::Vector2f move, sf::FloatRect rect)
{
for(std::list<Tile*>::iterator iter = MapData.begin(); iter != MapData.end(); iter++)
{
sf::FloatRect gap, collider = (*iter)->GetRect();
if(rect.intersects(collider, gap))
{
if(rect.top < collider.top) //we are above collider
{
move.y -= gap.height; //right on the money
rect.top -= gap.height; //update our collision rect to represent out new pos.
}
else // we are beneath the collider
{
move.y += gap.height;
rect.top += gap.height;
}
//rect.top += move.y;
}
}
return move;
}
With a little modification we can create this psudocode function, which would easily replace your "if(BoxCollision(FirstRect, SecondRect))" code. You would have to modify the rects with your HSLS variable before reaching this code however.
This code is much simpler, and easier to step through if there turns out to be a bug.
Direction FindColDir(sf::FloatRect rect, sf::FloatRect collider)
{
sf::FloatRect gap;
if(rect.intersects(collider, gap))
{
sf::Vector2f dir = collider.GetPosition() - gap.GetPosition(); // we use the gap to ensure that the position is around the same row and column as our object
float x = abs(dir.x), y = abs(dir.y);
if(x > y)
{
if(dir.x < 0) return WEST; else return EAST;
}
else
{
if(dir.y < 0) return NORTH; else return SOUTH;
}
}
return NOCOLLIDE;
}
I generally avoid writing the rect collision code myself, because it's ugly and can easily hide errors. I prefer to refractor my code so that I can rely on the functions in the rect class. It make my code easier to read, and generally has less annoying bugs.
Hope this helps!