You can't just cancel out the last movement of the player when he collides - that is why your player is freezing/getting stuck.
What you need to do in the event of a collision is move the colliding object out of the shape by the shortest distance possible.
For a circle, this means move the colliding object out along the direction of the circle's radius projected towards the collision point.
For a rectangle, this means move the object out by either x or y amount, up/down, whichever distance is shortest.
There's several ways you can do collision, but the simplest I can think of is a mathematical representation of point vs circle and point vs rectangle shape.
In rough pseudo-code (I'm assuming point is a vector (porbably sf::Vector2f) and circle has properties like center (Vector2f) and radius (float))
CollidePointVsCircle( point, circle )
{
float dist = distance(point, circle.center);
if ( dist < circle.radius )
{ // point is inside circle, i.e. colliding
vector2f direction = normalize(point - circle.center); // figure out the shortest direction 'out' of the circle
float amountToMove = radius - dist; // the minimum distance to get out of the circle
point = point + directoin * amountToMove; // move the point along the direction by the smallest necessary amount
}
}
For a rectangle, you need to figure out if the point is inside the rectangle, and then which side its closest to, then move it out along that amount.
Rough pseudo code:
CollidePointVsRectangle(point, rect)
{
float distToLeft = point.x - rect.left;
float distToRight = (rect.left + rect.width) - point.x;
float distToTop = point.y - rect.top;
float distToBottom = (rect.top + rect.height) - point.y
if ( distToLeft > 0 && distToRight > 0 && distToTop > 0 && distToBottom > 0 )
{ // point is inside rectangle
// determine which distance of the above is smallest - done by a lengthy if/else combination
// then move the point along the direction depending on which side the point was closest -
// if distToLeft is smallest, move point.x by amount (-distToLeft)
// if distToRight is smallest, move point.x by amount (distToRight)
// if distToTop is smallest, move point.y by amount (-distToTop)
// if distToBottom is smallest, move point.y by amount (distToBottom)
}
}
When I say move the point, you can actually compose your player of multiple points, and collide each point with whatever is nearby (you'll have to figure out a way to make sure you don't do collision with all objects)
This is very simple point-circle and point-rectangle collision. If your player is small enough relative to the objects he's colliding with (i.e. there's no wall with a size smaller than the player's size), this will work relatively well.
Alternatively, there's some more complicated, but also more versatile collision methods described here: http://www.metanetsoftware.com/technique/tutorialA.html - as I mentioned on another similar post, they provide source, which should be fairly easy to adapt to your purpose - i did so for the 2d platformer I'm making right now.
Or you could use a library like Box2D - though since I've never used it, i don't know if it has everything you need.