2
\$\begingroup\$

I'm writing a 2D game engine. I need to add a camera to my world that can zoom in and out as well as move away from its initial position at (0,0) at the center of the world.

The main issue can be seen in this video. When the camera hasn't yet moved (still at 0,0), I can click anywhere in the visible world and the click is mapped to the correct world position. I can even zoom and everything including the mouse position is scaled correctly. However, the moment I move the camera, the position becomes offset by a percentage of the camera movement. (This is clearer in the video.)

I have tried calculating the draw position and world mouse position in many different ways, but I always get the same issue.

What might be wrong?

Here's the code for both object position to screen position and mouse position to world position conversion:

public Vector2 GetDrawCoord(Vector2 position)
{
    return new Vector2(((position.X - cameraCenter.X)) * zoom + graphics.Viewport.Width / 2, 
        graphics.Viewport.Height - ((position.Y - cameraCenter.Y) * zoom + graphics.Viewport.Height / 2));
}

public Vector2 GetClickCoord(Vector2 position)
{
    return new Vector2((position.X - graphics.Viewport.Width / 2 + cameraCenter.X) / zoom, 
        (graphics.Viewport.Height / 2 - position.Y + cameraCenter.Y) / zoom);
}

Update:

New code:

Vector3 vec = graphics.Viewport.Unproject(new Vector3(position.X, position.Y, 0f), 
            Matrix.CreateOrthographic((float)graphics.Viewport.Width, (float)graphics.Viewport.Height, 0f, 0f), 
            cameraMatrix, 
            Matrix.Identity);
\$\endgroup\$
1
\$\begingroup\$

You can use Viewport.Unproject method exactly for this.

  • For the source which is a vector3 you should specify your screenspace position into the xy members. The z member of the vector corresponds to the view frustum near and far planes. 0 means you are on the near plane, 1 means that you are on the far plane and in between means you are between by that value.
  • The projection matrix should be an orthographics matrix if you are doing a 2D game. You can create an ortho projection by calling Matrix.CreateOrthographic and specifying your screen dimensions and some near-far frustum values which could be irrelevant in a 2D game.
  • The view matrix is your camera transformation matrix.
  • The world matrix is a world transform matrix. It should be Matrix.Identity if you are not transforming you world.
\$\endgroup\$
  • \$\begingroup\$ Thanks, i had a look into this, but the vector3 coming out of CreateOrthographic is coming out NaN,NaN,NaN. I've added my code to my question. \$\endgroup\$ – Lex Webb May 24 '14 at 17:35
  • \$\begingroup\$ So, ive fixed it now. but when my mouse pointer is positioned at the center of the screen. I'm getting a vector the equals the center of the screen but negative(-400, -240), that cant be right can it? \$\endgroup\$ – Lex Webb May 24 '14 at 17:59
  • \$\begingroup\$ I can't say why are you getting those values without seeing your position and matrix values. Also try to create ortho matrix with 0 for nearplane and 1 for farplane values if you are having problems. \$\endgroup\$ – János Turánszki May 24 '14 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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