2
\$\begingroup\$

Here is what’s in my HandleKeyboard() method that is called from the Game1 Update method.

        MouseState mState = Mouse.GetState();
        // the Vector2 that will hold the angle from the player to the mouse pointer.
        Vector2 mDirection = new Vector2(0, 0);

            // Get the current mouse position from the state update in the beginning of this method.
            Vector2 mPosition = new Vector2(mState.X, mState.Y);
            // Subtract the potsition of the player fromthe mouse pointer to get the exact angle in a vector2
            mDirection = mPosition - arrow.Position;

            // Control Rotation
            arrow.FixedRotation = true;
            // display the arrow in the rotation gathered above.
            arrow.Rotation = (float)Math.Atan2(mDirection.Y, mDirection.X);

From what I have read, this seems like the exact right thing to have the arrow look at my pointer. However when I rotate the mouse around the pointer it really doesn’t work properly.

It's hard to explain so here is a youtube video displaying what’s happening

I really hope you can tell me what’s going wrong.

\$\endgroup\$
3
  • \$\begingroup\$ Your mDirection isn't strictly a direction, as there's no guarantee it will be of length 1. Try normalizing it before applying atan2. \$\endgroup\$
    – user13213
    Commented Dec 24, 2013 at 0:57
  • \$\begingroup\$ tried normalizing, there is no difference unfortunately :( \$\endgroup\$
    – Qas Piano
    Commented Dec 24, 2013 at 10:54
  • \$\begingroup\$ The mouse position is relative to the upper left corner of the window, is your arrow's position relative to the center of it? If so, try doing mPosition - Vector2(width/2.0, height/2.0) - arrow.Position (where those would be width and height of the client area). \$\endgroup\$
    – user13213
    Commented Dec 24, 2013 at 12:27

1 Answer 1

1
\$\begingroup\$

This happens because Farseer (now named VelcroPhysics) works with the KMS (Kilo, Meter, Second) system (as explained in the section "Drawing the World" of this slightly outdated documentation). Because of that, the arrow's position is a really "small" vector (something close to (0, 0)) if you interpret it directly in pixels (which is what you're doing).

In order to get the correct position in pixels, you have to obtain a new Vector2 by calling this function provided by Farseer:

Vector2 arrowPositionInPixels = ConvertUnits.ToDisplayUnits(arrow.Position);

Only then, you can continue with your code of obtaining mDirection and calculating the rotation.

Alternatively, you can obtain the position of the mouse in the unit system used by Farseer with:

Vector2 mousePositionKMS = ConvertUnits.ToSimUnits(mPosition);

And work in the KMS system. Both approaches should give the same rotation result. Just make sure you're always working in the same metric system (Farseer's KMS or pixels).

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .