2
votes

I'm building an isometric game with LibGDX. I'm trying to figure out pan limits, so the user can't pan off of the isometric map on the screen. The limits need to be dependent on zoom as well.

I found the following code for a orthogonal top-down game for pan limits:

    float pxWidth =((TiledMapTileLayer) tiledMap.getLayers().get("Background")).getWidth() * ((TiledMapTileLayer) tiledMap.getLayers().get("Background")).getTileWidth();
    float pxHeight = ((TiledMapTileLayer) tiledMap.getLayers().get("Background")).getHeight() * ((TiledMapTileLayer) tiledMap.getLayers().get("Background")).getTileHeight();

    float scaledViewportWidthHalfExtent = cam.viewportWidth * cam.zoom * 0.5f;
    float scaledViewportHeightHalfExtent = cam.viewportHeight * cam.zoom * 0.5f;

    float xmax = pxWidth;
    float ymax = pxHeight;

    // Horizontal
    if (cam.position.x < scaledViewportWidthHalfExtent)
        cam.position.x = scaledViewportWidthHalfExtent;
    else if (cam.position.x > xmax - scaledViewportWidthHalfExtent)
        cam.position.x = xmax - scaledViewportWidthHalfExtent;

    // Vertical
    if (cam.position.y < scaledViewportHeightHalfExtent) {
        cam.position.y = scaledViewportHeightHalfExtent;
    }
    else if (cam.position.y > ymax - scaledViewportHeightHalfExtent)
        cam.position.y = ymax - scaledViewportHeightHalfExtent;

    cam.update();

It works perfectly for the horizontal direction, but not for the vertical direction. The vertical direction seems to be offset by a half map size. Here's a gif that outlines the issue:

enter image description here

How do I convert the orthogonal vertical limit to an isometric vertical limit?

Also, it appears as though the y=0 position for the camera is in the center of the screen.

Other possibly relevant info:

  • Tiles are 512 x 256 pixels
  • Tiles rendered using IsometricTiledMapRenderer
  • ExtendViewport used with viewport set to screen pixels
  • OrthographicCamera used for panning, zooming, etc.
1

1 Answers

2
votes

The problem with the y limits is that y=0 is the center of the screen. This means that the vertical map edges are not 0 and ymax, but they are -ymax / 2 and ymax / 2. So your final code would be this:

if (cam.position.y < -ymax + scaledViewportHeightHalfExtent) cam.position.y = -ymax + scaledViewportHeightHalfExtent;
else if (cam.position.y > ymax - scaledViewportHeightHalfExtent) cam.position.y = ymax - scaledViewportHeightHalfExtent;