Basically you need to calculate a movement vector for your character based on the mouse position. So you need two things:
- Angle from the character to the cursor, which is also the rotation of the character/sprite
- The distance, so you can implement a "deadzone", i will explain later why this is needed
You get the angle by using simple geometry, as described here
Getting the distance is also not very difficult
With these two values we can move the character by calculating a movement vector. This can be easily derived from the angle
sf::Vector2f movement = sf::Vector2f(cos(angle), sin(angle)) * movementSpeed;
where angle is a float (in radiant) from (1) and movementSpeed is a float which you can set.
Now you have everything you need to move your character
yourCharacter.move(movement );
You need to take the frametime into account to get a nice and smooth result, as described here
Also there is another small problem, the character will start spinning around your cursor once it has reached it. Because it will move a bit to far "over" the cursor and in the next frame it will "bounce" back. To avoid this you need a deadzone, which should look like this (modify the part above with the deadzone):
const float DEAD_ZONE = some_amount_based_on_movementSpeed
if(distance > DEAD_ZONE)
{
yourCharacter.move(movement);
}
Where distance is described in (2)
I hope this gives you a basic idea how to tackle this problem.
AlexAUT
Thanks for the answer. But I wrote it, a little bit differently:
for the character to follow the cursor, I get the distance, like this and move it
if ( Mouse::isButtonPressed(Mouse::Right) )
{
Vector2f totalMovement;
totalMovement.x = Mouse::getPosition(window).x - hero_sprite.getPosition().x;
totalMovement.y = Mouse::getPosition(window).y - hero_sprite.getPosition().y;
hero_sprite.move(totalMovement * (1.f/1000.f));
}
then created a function for the sides
enum look
{
right, left, down, up, downright, upright, upleft, downleft
};
and then I get the angle of my distance from this function
float mtrAngle_f(float x, float y)
{
float dir;
dir = acosf( x / sqrtf(powf(-x, 2.0f) + powf(-y, 2.0f)) );
if (y > 0.0f) { dir = MTR_2PI_F - dir; }
return dir * MTR_RADIAN_F;
}
and finally create a function that determine in what side the character looks at..
look lookAtMouse(int x, int y)
{
float direction = mtrAngle_f(x, y);
if (direction > angle && direction <= angle) // here we define the range of the angle
{
return look::right; // or left, or down, etc.
}
}
in depending on the side in which he looks at, I drew the appropriate sprites
if (player.lookAtMouse(pos.x, pos.y) == look::up) // or left, or down, etc.
{
player.animation();
}
Can you tell me how correctly or incorrectly I implemented it?