A real-time, responsive/reflexive UI Library for the Phaser 3 game engine.
Works on most mobile and desktop resolutions.
Phaser 3 UI Library - 2020A responsive library I built for the Phaser 3 game engine. Makes UI work across PC and Mobile resolutions using anchor points.
While Phaser has some support for responsive interfaces and anchor points, overall I found it lacked the granularity we needed. We needed pixel-perfect and controllable scaling, anchor points, and real-time responsiveness (rotating a phone screen or resizing a desktop window), so this called for a custom JS plugin. I applied my web development/UI skills to create a bespoke UI library for Phaser, which allows you to align sets of UI elements to 9 anchor points on the screen: Top row, middle row, bottom row, and left edge, middle, or right edge for each.
I began testing the plugin before I touched game art at all. To us and our employer, it was a mutually shared priority that the game would play well on mobile and desktop equally.
This screenshot shows one of my earliest tests. I wanted to make sure interactable elements could anchor to edges of the screen and adjust in real-time as the window resized. It doesn't look like much yet, but soon my UI library would be crucial to the performance and playability of our game.
Because of the way Phaser handled different classes of objects (text, sprites, masks, etc.), writing an inclusive library wasn't trivial, and needed a pattern that could be extended to each class of object in order to be inherited. Take a look at the brief extension I wrote, enabling Phaser to anchor UI elements in real time (specifically for sprites):
class UI extends Phaser.GameObjects.Sprite { constructor(s, t, e, i, h, a, n, d, r, c) { super(s, t, e, i, h), (this.centered = a), (this.floatX = n), (this.floatY = d), (this.xOffset = r), (this.yOffset = c), s.sys.displayList.add(this), s.sys.updateList.add(this), s.add.existing(this), a || this.setOrigin(0, 0); } jiggleUI(s, t, e, i) { switch (s) { case 0: this.setX(0 + e); break; case 1: this.setX(window.innerWidth / 2 + e); break; case 2: this.setX(window.innerWidth + e); } switch (t) { case 0: this.setY(0 + i); break; case 1: this.setY(window.innerHeight / 2 + i); break; case 2: this.setY(window.innerHeight + i); } } }
The same extension was applied to any class of object we needed to have responsiveness (text, masks, etc.)
The library simply extends the Sprite constructor provided by Phaser 3, checks the values of the flags, and anchors the sprite according to the presented arguments. You can even adjust an offset if you want the sprite to be centered around a different origin point.
The flag labeled "a" centers the sprite at a specific point, or 0,0 by default. "s" and "t" determine how it's anchored horizontally and vertically. "n", "d", "r", and "c" determine offsets for all four dimensions. "e" and "i" refer to the sprite's width and height.
Overall, it did its job, making the game look great on desktop and mobile.