SFML community forums
Help => Graphics => Topic started by: rojan_neo on September 12, 2011, 02:33:37 am
-
I have a simple problem... I am working on the movement of player for a game(top down 2d view)... Basically the player is a sprite filled with other physics such as mass and velocity. Now, I can move the player all over the screen but I want to use angles to make the sprite face in the direction the player is moving. I am having problem on using the concepts of angles for this purpose... Can anyone help??
Let's say a player is in a position (x,y), now when one click on some part of the screen, I want the player to face in that direction and move to it. How would I do that??
-
sin() and cos(), and probably atan2() is what you seek, my dear friend. Read up on those functions.
-
its kind of dense reading if you aren't up to snuff on your highschool geometry. The use of atan2 is to get an angle in radians from the difference of 2 points. So to use atan2 you'd subtract the origin x, from the dest x, then the origin y from the dest y, and then atan2(diffx,diffy), to get the angle in radians.
sf::Drawable::setRotation doesn't accept angle in radians though, so if you tried just using the raw output of atan2, you'd get some goofy results; degrees from radians is = radians * (180/PI).
Now for movement you need sine and cosine. to calculate where you would land on the line, at some speed, you
newx = speed * cos(radians); //cosine calculates the x movement from speed
newy = speed * sin(radians); // sine calculates y movement from speed
repeat until the sprite is approximately at the coordinates of the mouse click.
-
Of course if you want to move the player to the clicked coords, you already have both beginning and endpoints, so you don't need angles.
The movement vector is newpoint - oldpoint. So in this case, newpoint would be the place the user clicked, and oldpoint would be the player's current position.
You then want to translate that into a "unit vector", which is a just a vector with a length of 1. You do this by dividing x and y by the length of the movement vector.
The length can be found with good old pythagorean's theroum:
c*c = a*a + b*b
// or in this case:
c = sqrt( a*a + b*b );
So... in review, all of the above can be accomplished simply:
Vector2f newpoint; // the clicked position
Vector2f oldpoint; // the player's current position
Vector2f motion = newpoint - oldpoint; // the movement vector
float len = sqrt(motion.x * motion.x + motion.y * motion.y); // length of the movement vector
Vector2f unit = motion / len;
// that's it! Now to move the player in that direction, you just apply the speed:
playerposition += unit * speed;
-
yeah, thats way easier to understand, probably faster too.
so to keep from repeating work, since he does need the angle
float angle = atan2(motion.x,motion.y)*180/M_PI;
will get you there.