1
\$\begingroup\$

I'm currently developing a monogame game with a tile engine.

I have been experimenting with different tiles and sprites sizes : 16px, 32px, 64px I have settled for 32x32 pixels tiles rendered at a 64x64px size on screen.

I have read that a good way to do so is to use a RenderTarget2D. I've done so. It works well. I'm using SamplerState.PointClamp to keep the pixel aspect clean.

So for a 1440x900 resolution I use

 renderTarget = new RenderTarget2D(graphics.GraphicsDevice, 720, 450);

My question : when using the RenderTarget2D to upscale the screen, it logically messes up the camera I had working, and even more so the conversion of mouse coordinates to world coordinates. How should I modify the camera and the "mouse coordinates" to world position function. Is it even possible to convert properly mouse coordinates when you are upscaling everything with a renderTarget ?

Screenshot

This answer hints that it may be problematic, can somebody explain to me why ?

From the link : so if your graphics aren't dependant on other graphical features like a mouse, then I would use a RenderTarget

I can't find any resources about this. I always find a solution by myself, but this one is too much for me. Linear algebra is not my strong suit. Thank to anybody who can help.

My transform Matrix and Worldposition conversion

public Matrix Transform(GraphicsDevice graphicsDevice)
{
    m_Transform =

      Matrix.CreateTranslation(new Vector3(-m_CameraPosition.X, -m_CameraPosition.Y, 0)) *
         Matrix.CreateRotationZ(Rotation) *
         Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
         Matrix.CreateTranslation(new Vector3(ViewportWidth * 0.5f, ViewportHeight * 0.5f, 0));

    return m_Transform;
}

public Vector2 Worldposition(GraphicsDevice graphicsDevice, Vector2 position)
{
    //Invert camera
    Matrix m_InvertTransform =
    Matrix.CreateTranslation(new Vector3(-(m_CameraPosition.X + ViewportWidth * 0.5f), 0, -(m_CameraPosition.Y + ViewportHeight * 0.5f))) *
    Matrix.CreateRotationZ(Rotation) *
    Matrix.CreateScale(new Vector3(Zoom, Zoom, Zoom)) *
    Matrix.CreateTranslation(new Vector3(ViewportWidth * 0.5f, 0, ViewportHeight * 0.5f));
    m_InvertTransform = Matrix.Invert(m_InvertTransform);
    //Transform the position
    Vector3 newPos3 = Vector3.Transform(new Vector3(position.X, 0, position.Y), m_InvertTransform);
    return new Vector2((newPos3.X - 720) , (newPos3.Z - 450) );
}

Edit :

In my Update() method :

Vector2 vector = new Vector2((int)player.X, (int)player.Y);
camera.ChangePosition(GraphicsDevice, vector);

The ChangePosition function in my Camera Class public void ChangePosition(GraphicsDevice graphicsDevice, Vector2 newposition) { m_CameraPosition = newposition; }

\$\endgroup\$
  • \$\begingroup\$ are you saying that your game resolution is 720x450 and you stretch that to fit a 1440x900 screen? if so, you scale your mouse position by 1/scale mouseposition = mouseposition / Scale; where scale = screenwidth / screenheight; \$\endgroup\$ – dimitris93 Mar 5 '15 at 9:18
  • \$\begingroup\$ Well I don't get how this would work with a moving Camera. I updated my post with a few info. If I comment //camera.ChangePosition(GraphicsDevice, vector); And change Worldposition like this : ` return new Vector2(newPos3.X - 720 , newPos3.Z - 450) / 2; ` I get the right world position with my mouse. But as soon as my camera is centered on the player, mouse coordinates are not in sync with the tile clicked anymore. \$\endgroup\$ – Giw Mar 5 '15 at 21:26
  • \$\begingroup\$ oh, so you also move the camera ? then if you moved the camera by (1500,0) for example, you will need to mouseposition = (mouseposition + (1500,0)) / Scale; \$\endgroup\$ – dimitris93 Mar 5 '15 at 21:30
  • \$\begingroup\$ The camera position is bound on the player. \$\endgroup\$ – Giw Mar 5 '15 at 22:54
  • \$\begingroup\$ so use player.X instead of 1500 ? \$\endgroup\$ – dimitris93 Mar 5 '15 at 23:01
0
\$\begingroup\$

So just to answer my own old question. I had already done what I was asking for in my prototype, and found my solution when looking back in my git repository. Only thing missing from the previous code was the division by 2 of the position in the transform Vector.

public Vector2 Worldposition(Vector2 position)
{

  float ViewportWidth = 720;
  float ViewportHeight = 450;

  //Invert camera
  Matrix m_InvertTransform =
  Matrix.CreateTranslation(new Vector3(-(m_CameraPosition.X + ViewportWidth * 0.5f), 0, -(m_CameraPosition.Y + ViewportHeight * 0.5f))) *
  Matrix.CreateRotationZ(Rotation) *
  Matrix.CreateScale(new Vector3(Zoom, Zoom, Zoom)) *
  Matrix.CreateTranslation(new Vector3(ViewportWidth * 0.5f, 0, ViewportHeight * 0.5f));
  m_InvertTransform = Matrix.Invert(m_InvertTransform);
  //Transform the position
  Vector3 newPos3 = Vector3.Transform(new Vector3(position.X / 2, 0, position.Y  2), m_InvertTransform);
>  return new Vector2(newPos3.X - ViewportWidth / 2, newPos3.Z - ViewportHeight  2);
}
\$\endgroup\$

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.