Camera and Viewports

  Edit on GitHub

The Camera class and Viewport class will seem very familiar if one has every used libGDX. They work the same in LittleKt. The camera can be use to manipluate the game world without having to manually handle any matrices. The viewport is used in tandem with the camera which supports dealing with different screen sizes / resolutions and aspect ratios.

Using a Camera

The Camera class is an abstract base that can be extended to create our own implementation of a camera. Luckily, we can use the OrthographicCamera implementation that is already offered.

The camera allows us to:

  • Move and rotate around the game world
  • Zoom in and out
  • Manage and update the viewport
  • project and unproject to and from screen and world spaces

Orthographic Camera

By default, a Camera doesn’t contain or use a Viewport. It contains two properties that can be used to calculate the projection matrix: virtualWidth and virtualHeight.

val camera = OrthographicCamera(graphics.width, graphics.height)

When using a camera we want to make sure we call the update() method on it before doing any rendering to ensure it updates that its matrices are up to date. We then can use the viewProjection matrix in the Camera class to render to a SpriteBatch.

val camera = OrthographicCamera(graphics.width, graphics.height)

onUpdate {
    val renderPass = ... // render pass releated setup
    camera.update()
    batch.use(renderPass, camera.viewProjection) {
        // we are using the cameras view projection matrix to render
    }
}

We can also update the virtualWidth and virtualHeight of the Camera when the game window resizes:

onResize { width, height ->
    camera.virtualWidth = width
    camera.virtualHeight = height
}

Using a Viewport

Instead of managing the size of the camera ourselves, we can use a Viewport instead to handle the sizing. When creating a new Viewport we can either pass in our own Camera instance or let the viewport create its own which we then can reference. WebGPU has certain limitations on viewports, when coming from OpenGL, may seem restrictive. For instance, viewports may not extend the size of the frame buffer it is drawing to. This makes things like a “FitViewport”, where certain sides are extended outward, a bit harder to calculate as WebGPU will throw a fatal error when it detects it.

val viewport = ExtendViewport(480, 270)
val camera: OrthographicCamera = viewport.camera

A viewport can be resized by using the update() method which will also update the Camera instance:

onResize { width, height ->
    viewport.update(width, height)
}

Types of Viewports

Stretch Viewport

A viewport that supports using a virtual size (via StretchViewport). The virtual viewport is strechted to fit the screen. There are no black bars and the aspect ratio can change after scaling.

Extend Viewport

A viewport that supports using a virtual size (via ExtendViewport). The virtual viewport maintains the aspect ratio by extending the game world horizontally or vertically. The world is scaled to fit within the viewport and then the shorter dimension is lengthened to fill the viewport.

Screen Viewport

A viewport that uses a virtual size that will always match the window size (via ScreenViewport). No scaling happens along with no black bars appearing.