The The Phaser 3 Game Engine has its own in-built scale manager, but what if you want to write your own simple custom Phaser 3 game scaling plugin with breakpoints etc? The code below will enable you to achieve a scaling effect demonstrated in the following screens:
Mobile

Tablet

Desktop

The first step is to extend the Phaser 3 Scene class with your own custom class as follows:
export default class SceneBase extends Phaser.Scene
{
constructor(config) {
super(config);
this.gameContainer = document.getElementById('game-container');
this.eventEmitter = new Phaser.Events.EventEmitter();
}
preload() {
}
create() {
}
update() {
}
resizeGameContainer() {
let winW = window.innerWidth / window.devicePixelRatio;
let winH = window.innerHeight / window.devicePixelRatio;
let breakpoints = [{ scrW: 0, gamW: 400 }, { scrW: 600, gamW: 450 }, { scrW: 900, gamW: 550 }, { scrW: 1200, gamW: 750 }, { scrW: 1500, gamW: 1000 }, { scrW: 1800, gamW: 1300 }];
let currentBreakpoint = null;
let newViewPortW = 0;
let newViewPortH = 0;
for (let i = 0; i < breakpoints.length; i++)
{
currentBreakpoint = breakpoints[i];
if (winW < currentBreakpoint.scrW)
{
break;
}
}
newViewPortW = currentBreakpoint.gamW;
newViewPortH = currentBreakpoint.gamW * (winH / winW);
this.game.scale.resize(newViewPortW, newViewPortH);
this.gameContainer.style.width = `${window.innerWidth}px`;
this.gameContainer.style.height = `${window.innerHeight}px`;
this.game.canvas.style.width = `${window.innerWidth}px`;
this.game.canvas.style.height = `${window.innerHeight}px`;
this.eventEmitter.emit('screenResized');
}
}
In the constructor we need to get a reference to your top level game container div - in my example I have given it an id of game-container. The next step is to create a base EventEmitter - this will be used to emit a screenResized event that you can hook into throughout your game to re-position objects in your scene if required.
The code above basically takes the window dimensions, does a lookup in a breakpoints array to find the nearest matching game width before scaling the Phaser 3 game to a new size. Notice I take into account the devicePixelRatio, as without it your game wont scale as you expect on screens with denser pixel ratios (than 1).
All your Phaser 3 game scenes should then inherit from the base scene you have just created:
class SceneMain extends SceneBase {
Any scenes that inherit from your baseScene class can now listen out for the screenResized event and re-position elements on screen, for example joystick buttons, text etc.
createEventListeners()
{
this.eventEmitter.on('screenResized', () => { this.onScreenResize(); });
}
The final step is to create a standard javascript event listener to listen for the browser window being resized. On window resize, the above logic loops through all the scenes in your Phaser 3 game and calls the resizeGameContainer event on the baseScene class.
var game = new Phaser.Game(config);
window.addEventListener('load', () => { window.addEventListener('resize', event => { for (let i = 0; i < game.scene.scenes.length; i++) { game.scene.scenes[i].resizeGameContainer(); } }); });
And there you have it - a simple, easy example of how to implement a Phaser 3 screen scaling plugin that gives you full control over your game size on portrait and landscape orientations across mobile, tablet and desktop screens!
Leave Your Comments...