About a month ago I needed to find a way to implement a Phaser 3 input text field. This was due to needing to put a form into a Phaser 3 virtual world project I was working on. I had already placed an input element below the canvas for users to send chats to each other, but this needed much more space. <\/p>\n\n\n\n
Could I accomplish my project’s goals without having to totally rewrite a text field, dropdowns, and other form elements?
<\/p>\n\n\n\n
Then I remembered in Phaser 2 we did have an input field that was a plug-in. I recalled that the developer added an actual HTML form element over the existing HTML5 canvas. Could I use some of the experiments I’ve been doing with the AlignGrid for form elements as well? So far I had only been using it to align sprites, text, and images inside the canvas.<\/p>\n\n\n\n
I realized I could do it but with a limitation. That limit being that the canvas had to be in the top left-hand corner of the webpage. If I did need it to be in the middle of a webpage I could accomplish the task using an iframe. This did not pose too much trouble with my work because my games are either on mobile which means they’re in the top left-hand corner already or I use a pop-up window if the player is trying to use the game on a desktop or laptop. This post will focus on the Phaser 3 text input and I will follow up with additional posts covering buttons and dropdowns.
Here is the final result below:
<\/p>\n\n\n\n
Instead of adding a text field dynamically I decided to work with existing form elements placed into the index.html. I would then write a class that would allow me to keep writing in the Phaser code style I was accustomed to. It was important that I did all the scaling and aligning from a Phaser Scene. You can see what I mean in a sample of my sceneMain.<\/p>\n\n\n\n
class SceneMain extends Phaser.Scene {\n constructor() {\n super('SceneMain');\n }\n preload() {}\n create() {\n this.formUtil = new FormUtil({\n scene: this,\n rows: 11,\n cols: 11\n });\n this.formUtil.showNumbers();\n \/\/\n \/\/\n \/\/\n this.formUtil.scaleToGameW(\"myText\", .3);\n this.formUtil.placeElementAt(16, 'myText', true);\n \/\/\n \/\/\n \/\/\n this.formUtil.scaleToGameW(\"area51\", .8);\n this.formUtil.scaleToGameH(\"area51\", .5);\n this.formUtil.placeElementAt(60, \"area51\", true, true);\n this.formUtil.addChangeCallback(\"area51\", this.textAreaChanged, this);\n \/\/\n \/\/\n \/\/\n }\n textAreaChanged() {\n var text = this.formUtil.getTextAreaValue(\"area51\");\n console.log(text);\n }\n update() {}\n}<\/code><\/pre>\n\n\n\nThe Html Code<\/h2>\n\n\n\n
For the HTML I used simple form elements after the game div tag with the id tags set to ‘myText’ for the text field and ‘area51’ for the text area.<\/p>\n\n\n\n
<!DOCTYPE html>\n<html>\n <head>\n <title>\n <\/title>\n <meta content=\"user-scalable=0, initial-scale=1,minimum-scale=1, maximum-scale=1, width=device-width, minimal-ui=1\" name=\"viewport\">\n <\/meta>\n <\/head>\n<\/html>\n<script src=\"js\/phaser.min.js\" type=\"text\/javascript\">\n<\/script>\n<script src=\"js\/sceneMain.js\" type=\"text\/javascript\">\n<\/script>\n<script src=\"js\/main.js\" type=\"text\/javascript\">\n<\/script>\n<script src=\"js\/util\/formUtil.js\" type=\"text\/javascript\">\n<\/script>\n<script src=\"js\/util\/alignGrid.js\" type=\"text\/javascript\">\n<\/script>\n<body>\n <div id=\"phaser-game\">\n <\/div>\n\n <input type=\"text\" id=\"myText\"\/>\n <textarea id=\"area51\">SOME TEXT HERE<\/textarea>\n<\/body><\/code><\/pre>\n\n\n\nThe FormUtil Class<\/h2>\n\n\n\n