• 13
• 15
• 27
• 9
• 9

# 2D topdown player always look at mouse position

This topic is 3367 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I know this is a bit of a flogged horse, but I've got a bit of a problem with vector angles. I've trawled over the forums and tried every acos / atan2 combination I've dug up but no luck so far. The problem I'm having is that the player can move within a camera bounding area (without the camera following) and I need the player to always look at the mouse position. When the player is at the origin I can get the angle correctly using the atan2 method, but as soon as the player moves from the centre of the screen then the player's aim goes off, as shown in the screenshot. Does anyone know how I can always have the player pointing towards the mouse_aim position? I've been using the following code to calculate the angle but the values returned are off.... Halp? [help]
// Form the Position-Focus vector and Aim-Camera_Focus Vector
Vector3D a =  mPosition - camera_focus;
Vector3D b =  mAim - camera_focus;

// Normalize
//a = a.Normalize();
//b = b.Normalize();

float dot = a.x * b.x + a.y * b.y;

// Determine the angle between the two vectors.
angle_inc_r = acos( dot / (a.Length() * b.Length()) );

if( dot < 0 )
{
angle_inc_d = -angle_inc_d;
}



##### Share on other sites
At the first quick glance over your code I think the problem is that you include the camera_focus vector into the equations, although there should'nt be any reason to do so. The character's angle is derived from character position and mouse position alone.

cheers,
Mike

##### Share on other sites
Quote:
 Original post by h4tt3n The character's angle is derived from character position and mouse position alone.

I think that's what led me to this problem in the first place. If I use the below code to calculate the angle, then the player will be facing the correct direction when in the centre of the screen however if the player strays from the centre then the problem begins.

current_mouse = mAim - mpPosition;angle_r = atan2(current_mouse.y, current_mouse.x);angle_d =  RAD2DEG(angle_r);angle_d = int(angle_d) %360;

I think the problem stems from atan2 returning an angle about the origin. Any idea on how to cater for the player when they are not positioned at the origin?

##### Share on other sites
You're getting side-tracked by where the player is standing. Just make a function

float get_angle ( vec2 v );

Then to get the player's angle
player.angle = get_angle ( mouse.pos - player.pos )

All that remains is to fill in the get_angle function.

One tip, don't just use atan since it will return poor results at certain angles. What you need to do is divide into cases (probably each representing 90 deg).

Something like
if ( v.y >= 0 )
{
if ( v.x >= 0 )
{
return atan(...);
}
else
{
return ...
}
}
else
{
...
}

And then use the best trig function for that domain.

If you don't like vectors, just make a function
get_angle ( float dx, float dy );

Oh, and you'll also want to test against the case when norm(v) is small (ie, the points are close together).

##### Share on other sites
Quote:
 One tip, don't just use atan since it will return poor results at certain angles. What you need to do is divide into cases (probably each representing 90 deg).

That's what atan2 is for. It handles this problem internally so you don't have to divide into cases.

##### Share on other sites
Quote:
 Original post by jdindiaOne tip, don't just use atan since it will return poor results at certain angles.

No, not if you use it right. No need for loads of if-then calls. If you feed the atan2 function with sine and cosine to the angle, it returns the angle in radians withing the range -pi, pi flawlessly. It might look something like:

Distance_vector = mouse.pos - character.posDistance_Scalar = sqr(Distance_vector.x*Distance_vector.x+Distance_vector.y* Distance_vector.y)Normalised_distance_vector = Distance_Vector/Distance_ScalarCosine_angle = Normalised_distance_vector.XSine_angle = Normalised_distance_vector.YAngle = Atan2(Sine_Angle, Cosine_Angle)

Cheers,
Mike

##### Share on other sites
@h4tt3n Apart from the normalization part that's what I'm already doing which indeed gives the correct angle if the player is at the camera_focus however it is when the player is away from the camera focus where the angle gets screwy (check the first post pic for a screenshot).

It looks to me like I need some kind of translation vector derived from the player position and camera_focus but I just can't wrap my head around it. [depressed]

##### Share on other sites
There's information missing within your code. What space are the different positions expressed in?

atan2 will not work if your mouse position and your character position are not within the same space. However, I suspect that your character position is expressed in world space but your mouse position is expressed in screen space. Have you converted one of the positions to the space of the other?

##### Share on other sites
Quote:
 Original post by ToohrVykHave you converted one of the positions to the space of the other?

Thanks for the reply and yes i had converted the mouse coords into object coords however it jogged me into looking over it again. Looks like i had a bug in there when converting which was screwing with the vector angle calculations.

For those interested I had to interpolate between the near and far clipping plane using gluUnProject to get correct mouse coords in object space. This link helped:

http://stackoverflow.com/questions/113352/opengl-projecting-mouse-click-onto-geometry

Cheers everyone!