libgdx Supporting Multiple Resolutions Viewports


Example

To support multiple resolutions and aspect ratios Libgdx uses the so called Viewports.
There are a few types of Viewports which use different strategies to handle multiple resolutions and aspect ratios.
A Viewport uses a Camera under the hood and manages it's viewportHeight and viewportWidth. You can optionally give the Viewport a Camera in it's constructor, otherwise it will use an OrthographicCamera by default:

private Viewport viewport;
private Camera camera;

public void create() {
   camera = new PerspectiveCamera();
   viewport = new FitViewport(8f, 4.8f, camera);
}  

Additionally, you must specify the worldWidth and worldHeight to the viewport's constructor. This space will represent the virtual coordinate system that you will use for specifying objects' position to be drawn and sizes. The viewport transformation, that can be applied to a SpriteBatch, for example, will automatically take care of transforming the logical coordinates to actual screen coordinates, with a way that conforms to the actual type of viewport you are using. For example, when using an orthographic projection (OrthographicCamera, which is the default): if your world size is 12.8 by 7.8 meters and your device screen is 2560x1560 pixels, then your world will be dynamically projected with 200 pixels per meter.

When the Viewports size changes (for example if the Screen Orientation of the Smartphone is changing), you need to inform the Viewport about that change. it will then automatically update the Cameras viewportHeight and viewportWidth:

public void resize(int width, int height) {
    viewport.update(width, height);
}

The Viewports also manage the OpenGL Viewport and modify the drawable area as needed.

The Viewports also take care about converting screen-coordinates to game-coordinates, which is needed especially for picking:

private Vector2 worldPos = new Vector2();
public boolean touchDown (int x, int y, int pointer, int button) {
    worldPos.set(x, y);
    viewport.unproject(worldPos);
    processPicking(worldPos);
}