Camera2D LookAt problem after resizing window

It’s me again :sweat_smile:

I have a Camera2D with a DefaultViewportAdapter.

It works flawlessly until I resize the window.

When I resize the window HORIZONTALLY and I call the “LookAt” method on the Camera.BoundingRectangle.Center it will start scrolling UP - the Y coordinate will decrease (the camera will go up).
When I resize the window VERTICALLY and call the “LookAt”, it will start scrolling LEFT in a similar fashion.
When I resize both, it will go up-left, diagonally.

I tried everything I could find online. Subscribing to Window_ClientSizeChanged event, setting the PreferredBackBufferWidth/Height manually, calling reset on the GraphicsDevice, creating a new ViewPort rectangle.

I think the Camera.BoundingRectangle coordinates are correct after resizing, but still, somehow the LookAt method misbehaves.


So, for clarity’s sake, the problem is:

When I call Camera.LookAt(Camera.BoundingRectangle.Center); without resizing it works correctly (i.e. it does NOT move the camera).
When I call it AFTER resizing, it does move the camera.


This is how the method looks internally:

public void LookAt(Vector2 position)
{
    Position = position - new Vector2(_viewportAdapter.VirtualWidth/2f, _viewportAdapter.VirtualHeight/2f);
}

Example

The behaviour before resize:

So let’s say I have a window 1280x720.
_viewportAdapter.VirtualWidth/2f will be 640,
_viewportAdapter.VirtualHeight/2f will be 360

The default, starting Position of the Camera is (0, 0). The Position indicates the position from the Origin, which is, by default is
Origin = new Vector2(viewportAdapter.VirtualWidth/2f, viewportAdapter.VirtualHeight/2f);.
It is the measured from the center of the camera, not the top-left corner (I think).

So, at (0, 0), the Camera.BoundingRectangle.Center will be (640, 360). (and at (-640, -360) the Center will be (0, 0))

When I call the LookAt with this, the calculated Position will be (0, 0), so it remains unchanged, and it will work with other values too, not just with (0, 0). It works as expected.

The behaviour after resize

Let’s say I resized the window to 1280x730.
_viewportAdapter.VirtualWidth/2f will be unchanged, 640,
_viewportAdapter.VirtualHeight/2f will be 365

Position will remain unchanged (0, 0).
The Camera.BoundingRectangle.Center will get changed to (640, 361,6666).

Position = (640, 361,6666) - new Vector2(640, 365) = (0, -3,4444);

The Camera will move upwards.

I think a resolved it.
I need to supplement Camera.BoundingRectangle.Center with stuff, so the Position will remain unchanged when calling LookAt.

public Vector2 GetCenter()
{
    Vector2 center = Camera.BoundingRectangle.Center;
    center += Camera.Position - (center - new Vector2(viewportAdapter.VirtualWidth / 2f, viewportAdapter.VirtualHeight / 2f));
    return center;
}

Camera.LookAt(GetCenter());

This is good for keeping the camera in one place, and moving it around (with arrows or the mouse for example).
I’m still not sure how am I supposed to LookAt at an absolute coordinate after resizing.

So, for example I have a map/image, and when I resize the window I would like to keep the map/image in the middle.
Camera.LookAt(new Vector2(mapWidth / 2, mapHeight / 2))
only works until I resize the window. After resizing the map will be offset.

I’m still stuck, help me please. :innocent:

All I want to do is to have a Camera2D (with a DefaultViewportAdapter), draw an image in the center, and when I resize the window I want it to be in the center. I would also like to use the Zooming capabilites of the class.

I resolved it too. :slight_smile:

This method will look at the center of the map, and you can use zoom too.

private void LookatMapCenter()
{
    Vector2 sizeOffset = (new Vector2(viewportAdapter.VirtualWidth / 2f, viewportAdapter.VirtualHeight / 2f) -
        Camera.Origin) / 2;
    Camera.Position = new Vector2(0, 0) - Camera.Origin - sizeOffset;
    Camera.Position -= (Vector2)Camera.BoundingRectangle.Center;
    Camera.Position += new Vector2(mapWidth / 2, mapHeight / 2);
}

Hopefully this thread will help someone in the future.

Hey @bendi

Sorry nobody managed to get back to you about this before you resolved it yourself. I’ve had a huge pile of email notifications I’ve been trying to work through and I’ve only just now got to this one.

The good news is I really like what you’ve done here and I’m going to add an item to my to-do list to roll this into the main library somehow.

Thanks mate :slight_smile: