How to add on-screen keyboard (on mobile) to an already-made Phaser game
First, understand the concept of ‘focus’ in HTML and how Phaser detects user clicks.When you click on any elements in a HTML webpage, the element becomes the ‘focus’. You can also forcefully change the focus to an element in JavaScript by calling ‘HTMLElement.focus()’.
The way Phaser detects user clicks is usually through the events ‘onInputDown’ or ‘onInputUp’. The official Phaser documentation for ‘onInputDown’ states that:
“This signal is dispatched if the Game Object has inputEnabled set to true, and receives a down event from a Phaser.Pointer. This effectively means the Pointer has been pressed down (but not yet released) on the Game Object.”
The context of ‘onInputDown’ and ‘onInputUp’ inside JavaScript is somewhere along the lines of:
‘variable.onInputDown.add(function, this)’
How we make the on-screen keyboard appear.
As browsers automatically open the on-screen keyboard on mobile when you focus on an input box. We will make use of an invisible input box on the webpage that will help us open the on-screen keyboard automatically when we need it to.With the basic concepts out of the way, let’s move on to the coding.
- First, open ‘index.html’ , the viewport need to maximize for better mobile experience, type this into the <head> . Read about it here https://www.w3schools.com/css/css_rwd_viewport.asp
<meta name="viewport" content="width=device-width, initial-scale=1.0">
- <input id="inputDummy" type="number" style="opacity: 0"/> <!--inputDummy was added, type can change if need to text opacity:0 is to hide the inputDummy from view --> You should change the type to whichever type that you need accordingly.

- *To find out more on input types check out either one of the following links https://www.w3schools.com/html/html_form_input_types.asp https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
- Next, we may also need to type in <script></script><!--to fullscreen to prevent mobile keyboard from leaving and the interactive begin in the zoom position -->//Double click to enter/exit fullscreendocument.ondblclick = function (event) {var canvas = document.getElementsByTagName("canvas");if (document.fullscreenElement) {document.exitFullscreen().then(() => console.log("Document Exited form Full screen mode")).catch((err) => console.error(err))} else {document.documentElement.requestFullscreen()// canvas[0].requestFullscreen().catch(err => {// alert(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);// })}}// screen.orientation.lock("landscape");
- Next, go to scripts folder and open ‘game.js’, then press Ctrl + F and type ‘onInputDown’. Press ‘enter’ to navigate through all instances of ‘onInputDown’ in the script and identify the variables representing the input boxes that are calling ‘onInputDown’.
- Example:
- Read through the script and figure out how the input system is handled in the game, we will need the corresponding functions later.Example: this is already inside the old codes
- In the above example, the inputs were directly read from ‘onDown’ events fired by the Phaser input system when a key is pressed on the keyboard. The ‘onDown’ events then call the ‘press[n]’ function that handles the corresponding keypress event.
- Go to the start of the createQuestion function that contains the ‘onInputDown’ that you have identified and enter the following:
- //lookang startvar showKeyboard = true;var inputBox = document.getElementById("inputDummy");//console.log("Test");
inputBox.style = "position: absolute; top: 50%; left: 50%; opacity: 0;";
function onInputFocus(e) {if (inputBox.value != "") {inputBox.value = "";}e.preventDefault();//console.log("focus");document.inputEnabled = false;}
inputBox.onfocus = onInputFocus;
inputBox.oninput = handleInput.bind(this);inputBox.onblur = onBlur;function onBlur() {//console.log("WUT");//console.log(document.activeElement);document.inputEnabled = true;if (showKeyboard) {inputBox.focus();showKeyboard = false;}}
function handleInput() {//console.log(inputBox.value);inputBox.value = inputBox.value.slice(-1); //to only accept one digitvar number = parseInt(inputBox.value);switch (number) {case 0:this.press0();break;case 1:this.press1();break;case 2:this.press2();break;case 3:this.press3();break;case 4:this.press4();break;case 5:this.press5();break;case 6:this.press6();break;case 7:this.press7();break;case 8:this.press8();break;case 9:this.press9();break;}} // lookang end - *Note that the codes in ‘onInputFocus’ and especially ‘handleinput’, will most definitely have to change according to how the specific script you are working with is coded.
- In the above example, the input box in the game only contains one number at any given time. Hence, in ‘handleInput’ the value of the input box is always cut until only the last entered character is left - “inputBox.value = inputBox.value.slice(-1);”
- The way the input is handled in the above example as shown in Step 12, is by calling “this.press[n]();” directly from keypress events, hence the value in the input box is converted to integer then checked before calling the corresponding function (mimicking a keypress). If you want to debug and see what is currently in the invisible input box, simply remove ‘opacity: 0;’ from ‘inputBox.style = " position: absolute; top: 50%; left: 50%; opacity: 0;";’
- Finally, go back to all the relevant ‘onInputDown’ instances that you have found in Step 10 and enter:
- inputBox.focus();
- console.log("Test1"); // change the log for each box number to debug more easily
- showKeyboard = true;
- at the end of the ‘onInputDown’ functions inside positit2Btn each box1 to box7

- it seems box5 and box6 not do have there own onInputDown.add(function) type these lines just after box 4
- //added by lookang box5 startbox5.onInputDown.add(function () {inputBox.focus();console.log("Test5");showKeyboard = true;}, this);//added by lookang box5 end
- similarly for box6
- //added by lookang box6 startbox6.onInputDown.add(function () {inputBox.focus();console.log("Test6");showKeyboard = true;}, this);//added by lookang box6 end
- Sometimes, the original script may have disabled the box5 and box6, so need to look into the scripts say if (questionStage == 3) {} add
- box5.inputEnabled=true; // lookang to force box5 to be inputEnabledbox6.inputEnabled=true; // lookang to force box6 to be inputEnabled
- similarly, in if (questionStage == 5) {} add this line
- And you are done! Run and test the Phaser game again to see if it works according to how you want it to. If not, check and change your ‘handleInput’ and ‘onInputFocus’ accordingly.




Many thanks to Z C for his tutorial.









No comments:
Post a Comment