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...