Get the full commented source code of

HTML5 Suika Watermelon Game

Talking about Game development, HTML5, Javascript, Phaser and TypeScript.

When you develop cross platform HTML5 games, you have to keep in mind that a lot of people will play them using different systems: computers, tablets and smartphones, each one with is own control system.

Computer players will play with either keyboard or mouse, while mobile players will play using touch controls.

I am showing you how to handle, with only a single script, all possible input controls in a game controlled by left or right buttons, just like my Serious Scramblers prototype.

Look at the script in action:

You can control the “game”, which consinst in highlighting left and right halves of the canvas, with A or D keys, ARROW keys, Mouse or multitouch inputs.

If you have a mobile phone, you can access the result directly at this link or through this QRCode:

The example is built around one HTML and two TypeScript files, let’s see them in detail:

index.html

The webpage which hosts the game, just the bare bones of HTML.

Also look at the thegame div, this is where the game runs.

<!DOCTYPE html>
<html>
    <head>
        <script src = "main.js"></script>
    </head>
<body>
    <div id = "thegame"></div>
</body>
</html>

main.ts

The main TypeScript file, the one called by index.html.

Here we import most of the game libraries and define Scale Manager object.

Here we also initialize the game itself.

// MAIN GAME FILE

// modules to import
import Phaser from 'phaser';
import { PlayGame} from './playGame';

// object to initialize the Scale Manager
const scaleObject: Phaser.Types.Core.ScaleConfig = {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
    parent: 'thegame',
    width: 500,
    height: 500
}

// game configuration object
const configObject: Phaser.Types.Core.GameConfig = {
    type: Phaser.AUTO,
    scale: scaleObject,
    scene: [PlayGame]
}

// the game itself
new Phaser.Game(configObject);

playGame.ts

The core of the examples, in playGame class we make all stuff work and handle various types of user input

// THE GAME ITSELF

// this class extends Scene class
export class PlayGame extends Phaser.Scene {

    // just a debug text to print some info
    debugText: Phaser.GameObjects.Text;

    arrowKeys: Phaser.Types.Input.Keyboard.CursorKeys;

    // variable to be assigned to keyboard key "A"
    keyA: Phaser.Input.Keyboard.Key;

    // variable to be assigned to keyboard key "B"
    keyD: Phaser.Input.Keyboard.Key;

    // flag to check if any left button has been pressed
    leftPressed: boolean;

    // flag to check if any right button has been pressed
    rightPressed: boolean;

    // flag to check if the mouse has been pressed
    mousePressed: boolean;

    // variable to store mouse X position
    mouseX: number;

    // left and right tilesprites to show highlighted directions
    leftHighlight: Phaser.GameObjects.TileSprite;
    rightHighlight: Phaser.GameObjects.TileSprite;

    // variable to quickly store game half width and height, as we are going to use them a lot of times
    halfGameWidth: number;
    gameHeight: number;

    // constructor
    constructor() {
        super({
            key: 'PlayGame'
        });
    }

    // method to be called once the class preloads
    preload(): void {

        // load the dotted line image
        this.load.image('line', 'assets/dotted.png');

        // load highlight image
        this.load.image('highlight', 'assets/highlight.png');
    }

    // method to be called once the class has been created
    create(): void {

        // get half game width and height
        this.halfGameWidth = this.game.config.width as number / 2;
        this.gameHeight = this.game.config.height as number;

        // at the beginning of the game the mouse is not pressed
        this.mousePressed = false;

        // place left highlight tile sprite
        this.leftHighlight = this.add.tileSprite(0, 0, this.halfGameWidth, this.gameHeight, 'highlight');
        this.leftHighlight.setOrigin(0, 0);

        // place right highlight tile sprite
        this.rightHighlight = this.add.tileSprite(this.halfGameWidth, 0, this.halfGameWidth, this.gameHeight, 'highlight');
        this.rightHighlight.setOrigin(0, 0);

        // add the dotted line tilesprite and set its registration point
        this.add.tileSprite(this.halfGameWidth, 0, 4, this.gameHeight, 'line').setOrigin(0.5, 0);

        // initialize arrow keys
        this.arrowKeys = this.input.keyboard.createCursorKeys();

        // add to keyA keyboard input with "A" key
        this.keyA = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A);

        // add to keyD keyboard input with "D" key
        this.keyD = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D);

        // normally Phaser only handles one pointer, so we have to add one more pointer to handle multi touch
        this.input.addPointer(1);

        // mouse event listeners
        this.input.on('pointerdown', this.setMousePressed, this);
        this.input.on('pointerup', this.setMouseReleased, this);
        this.input.on('pointermove', this.getMousePosition, this);

        // just a debug text
        this.debugText = this.add.text(16, 16, '', {
            color: '#ffffff',
            fontFamily: 'monospace',
            fontSize: '18px'
        });
    }

    // method to be called when the mouse is pressed
    setMousePressed(pointer: Phaser.Input.Pointer): void {

        // mouse is pressed
        this.mousePressed = true;

        // save horizontal mouse position
        this.mouseX = pointer.x;
    }

    // method to be called when the mouse is released
    setMouseReleased(): void {

        // mouse is not pressed
        this.mousePressed = false;
    }

    // method to get mouse position
    getMousePosition(pointer: Phaser.Input.Pointer) {

        // save horizontal mouse position
        this.mouseX = pointer.x;
    }

    // method to be executed at each frame
    update(): void {

        // at the start of each frame, we assume both right and left buttons aren't pressed
        this.leftPressed = false;
        this.rightPressed = false;

        // report text to output at the end of the process
        let reportText: string = "";

        // is mouse pointer pressed
        if (this.mousePressed) {
            
            // is mouse pointer horizontal position greater than half the canvas width?
            if (this.mouseX > this.halfGameWidth) {

                // right button is being pressed
                this.rightPressed = true;

                // update report text
                reportText += "Mouse on right side\n";
            }
            else {

                // left button is being pressed
                this.leftPressed = true;

                // update report text
                reportText += "Mouse on left side\n";
            }
        }

        // is touch pointer1 down?
        if (this.input.pointer1.isDown) {

            // is pointer1 horizontal position greater than half the canvas width?
            if (this.input.pointer1.x > this.halfGameWidth) {

                // right button is being pressed
                this.rightPressed = true;

                // update report text
                reportText += "Pointer1 on right side\n";
            }
            else {

                // left button is being pressed
                this.leftPressed = true;

                // update report text
                reportText += "Pointer1 on left side\n";
            }
        }

        // is touch pointer2 down?
        if (this.input.pointer2.isDown) {

             // is pointer2 horizontal position greater than half the canvas width?
            if (this.input.pointer2.x > this.halfGameWidth) {

                // right button is being pressed
                this.rightPressed = true;

                // update report text
                reportText += "Pointer2 on right side\n";
            }
            else {

                // left button is being pressed
                this.leftPressed = true;

                // update report text
                reportText += "Pointer2 on left side\n";
            }
        }

        // is "A" key down?
        if (this.keyA.isDown) {

            // left button is being pressed
            this.leftPressed = true;

            // update report text
            reportText += "'A' key pressed\n";
        }

        // is "D" or key down?
        if (this.keyD.isDown) {
            
            // right button has been pressed
            this.rightPressed = true;

            // update report text
            reportText += "'D' key pressed\n";
        }

        // is left arrow key down?
        if (this.arrowKeys.left.isDown) {

            // left button is being pressed
            this.leftPressed = true;

            // update report text
            reportText += "'LEFT' key pressed\n";
        }

        // is right arrow key down?
        if (this.arrowKeys.right.isDown) {
            
            // right button has been pressed
            this.rightPressed = true;

            // update report text
            reportText += "'RIGHT' key pressed\n";
        }

        // make left highlight visible if left direction has been pressed
        this.leftHighlight.setVisible(this.leftPressed);

        // make right highlight visible if right direction has been pressed
        this.rightHighlight.setVisible(this.rightPressed);

        // prompt final result
        this.debugText.setText("Overall Left: " + this.leftPressed.toString() + "\nOverall Right: " + this.rightPressed.toString() + "\n-----------------\n" + reportText);
    }
}

This example only covers left and right input, with virtual buttons rather than virtual pads, but it’s quite easy to extend it and turn it into a virtual four movement multicontrol script. Download the source code.

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