Get the full commented source code of

HTML5 Suika Watermelon Game

Talking about HTML5, Javascript and Phaser.

An interesting Phaser feature that isn’t used as it deserves is DOM support.

I already published a post about adding a Bootstrap component to a Phaser game, and now that I am going to use some Bootstrap stuff on my Wordle prototype, I needed to improve the script a bit.

But first, the main question: why should you use some Bootstrap components on your HTML5 game?

Well, because they make a lot easier to add options and menus to some kind of games. You can code them on your own from scratch, but I am firmly against reinventing the wheel, and you should be against it too, especially if you are a small studio or a one-man studio.

Using Bootstrap, or any other JavaScript UI framewordk, you can create in a couple of lines a dropdown like this one:

The problem is Phaser games often feature a Scale Manager, and as long as the game resolution matches with screen resolution, as in the above example which is a 500×500 window (in iframe) hosting a 500×500 game.

Let’s see what happens when we host a full HD game in a very smaller window, like in this example:

The dropdown menu is just too small to be properly used.

This is quite an issue because we can’t know the resolution our game is going to be played.

And now… the magic! Look at this small game:

Then at this full HD game:

And lastly at this game built to perfectly fit in a 750×1334 iPhone screen:

All Bootstrap dropdowns render perfectly, no matter the game or window resolution. How could it be possible?

Thanks to these three lines added to the original example:

let game;

window.onload = function() {
    let gameConfig = {
        type: Phaser.AUTO,
        backgroundColor: 0x444444,
        scale: {
            mode: Phaser.Scale.FIT,
            autoCenter: Phaser.Scale.CENTER_BOTH,
            parent: 'thegame',
            width: 750,
            height: 1334
        },

        // this is needed to work with DOM elements
        dom: {
            createContainer: true
        },
        scene: playGame
    }
    game = new Phaser.Game(gameConfig);
    window.focus();
}

class playGame extends Phaser.Scene {
    constructor() {
        super('PlayGame');
    }
    preload() {

        // this is how we load HTML content
        this.load.html('dropdown', 'bootstrap.html');
    }
    create() {

        // just a text to show the resolution
        this.add.text(0, 0, 'game: ' + game.config.width + 'x' + game.config.height + '\nwindow: ' + window.innerWidth + 'x' + window.innerHeight, {
            font: '32px arial' 
        })

        // a DOM elements is added pretty much like a sprite
        let dropdown = this.add.dom(game.config.width / 2, game.config.height / 2).createFromCache('dropdown');

        // set DOM element scale according to game / window width and height ratios
        let ratioX = game.config.width / window.innerWidth
        let ratioY = game.config.height / window.innerHeight
        dropdown.setScale(Math.max(ratioX, ratioY));

        // click listener
        dropdown.addListener('click');

        // on click callback function
        dropdown.on('click', function(e) {

            // different actions to do according to element 'id' property
            switch(e.target.id) {
                case 'up':
                this.tweens.add({
                    targets: dropdown,
                    x: game.config.width / 2,
                    y: 50,
                    duration: 200
                });
                    break;
                case 'right':
                    this.tweens.add({
                        targets: dropdown,
                        x: game.config.width - 150,
                        y: game.config.height / 2,
                        duration: 200
                    });
                    break;
                case 'down':
                    this.tweens.add({
                        targets: dropdown,
                        x: game.config.width / 2,
                        y: game.config.height - 50,
                        duration: 200
                    });
                    break;
                case 'left':
                    this.tweens.add({
                        targets: dropdown,
                        x: 150,
                        y: game.config.height / 2,
                        duration: 200
                    });
                    break;
                case 'center':
                    this.tweens.add({
                        targets: dropdown,
                        x: game.config.width / 2,
                        y: game.config.height / 2,
                        duration: 200
                    });
                    break;
            }

        }, this);
    }
}

And now we can finally use DOM elements in our Phaser games light-heartedly. Download the source code of the complete example.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.