Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I know, I know, on the internet there are a lot of tutorial on how to get the angle between the center of two objects or "make x face y".

I have this code:

//  (180 / PI = 57.3065)
float AngleBetweenVectors(sf::Vector2f, sf::Vector2f);
float AngleBetweenVectors(sf::Vector2f a, sf::Vector2f b){
   return 57.3065f * atan2(b.y - a.y, b.x - a.x);

that get the angle, and then this code that I use to set the rotation:

float angle = AngleBetweenVectors(player_p, cursor.getPosition());

where player_p is the player center position (a 50x50 square sprite), cursor is the cursor sf::Sprite I use and player is the player sf::Sprite.

But when I run it it gets this kind of problems: video here

As you can see on the border of the terrain it gets a little bit tricky. Why is that? I'm using two views, and this is the code of the main loop regarding views and drawing:

window.clear(sf::Color(0, 0, 0, 255));
window.setView(camera); // camera view 
// start drawing
    terrain.draw(); // terrain blocks
    window.draw(player); // player sprite
    window.setView(cursor_camera); // cursor view
        window.draw(cursor); // cursor sprite (the circular one)
// end drawing logic
window.setMouseCursorVisible(false); // no mouse pointer please

The player sprite in the video is the orange one, the black circle is the cursor sprite. The player sprite is moved via WASD and the cursor sprite via mouse movement. Thanks.

share|improve this question
up vote 2 down vote accepted

Looks like you're mixing coordinate systems. Your cursor is in screen space; your player is in world space. So, when you move a couple of screens down, the player has a Y value of something like 2000, but the cursor position will be between 0 and 1000, so the angle will always end up looking back up the screen.

Either transform the position of cursor into world space or the position of the player into screen space before you calculate the angle between them. You don't actually change the underlying value, just calculate the transformed value in order to perform the comparison.

Usually in 2D top-down games the difference between screen space and world space is just that screen space is offset from world space, to represent where the camera has moved to. So the coordinate space transformation would look like this:

sf::Vector2f screenToWorldSpace(sf::Vector2f screenPoint)
    // Take a copy
    sf::Vector2f worldPoint(screenPoint);
    // Translate it based on the camera/screen's current offset
    worldPoint.x += camera.GetRect().Left;
    worldPoint.y += camera.GetRect().Top;
    // All done!
    return worldPoint;
share|improve this answer
How can I "transform" them? I need them in separate spaces for a reason. The camera (or world space) moves while the cursor_camera (or screen space) must stay still. – Shoe Jul 28 '12 at 13:30
You can't compare values in different spaces because it's meaningless. One set of values will vary depending on your screen position but the other won't, so the result is arbitrarily based on where you've scrolled to. So you must copy one, transform it, and then compare. I'll edit the answer to give an example. – Kylotan Jul 28 '12 at 14:03
I'm using SFML 2.0 which doesn't have anything similar to GetRect() as a method for sf::View(). – Shoe Jul 29 '12 at 1:18
In that case, assuming a 1:1 zoom level, the view offset will be equal to the center of the view (which is the middle of the view in world coordinates), minus half the size of the view (giving the top left of the view in world coordinates). – Kylotan Jul 29 '12 at 2:27
Also, note that I changed the minus signs to plus signs in the code above: to go from screen to world you'd add on the view offset, and to go from world to screen you'd subtract the view offset. – Kylotan Jul 29 '12 at 2:29

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.