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.