{"id":1112,"date":"2019-02-16T09:53:15","date_gmt":"2019-02-16T09:53:15","guid":{"rendered":"http:\/\/www.netexl.com\/blog\/?p=1112"},"modified":"2019-02-16T16:35:47","modified_gmt":"2019-02-16T16:35:47","slug":"fullscreen-in-phase-3","status":"publish","type":"post","link":"https:\/\/www.netexl.com\/blog\/fullscreen-in-phase-3\/","title":{"rendered":"Fullscreen in Phase 3"},"content":{"rendered":"<p>Phaser 3 also has the full support for fullscreen mode.\u00a0Resizing a game to fullscreen is quite simple as shown in the code below. We are going to add a button to resize the game to fullscreen and then switch\u00a0the button\u00a0which will revert fullscreen mode to normal screen mode.<\/p>\n<p>We have updated icons sprite as following<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1113\" src=\"https:\/\/www.netexl.com\/blog\/wp-content\/uploads\/2019\/02\/icons-300x50.png\" alt=\"\" width=\"300\" height=\"50\" srcset=\"https:\/\/www.netexl.com\/blog\/wp-content\/uploads\/2019\/02\/icons-300x50.png 300w, https:\/\/www.netexl.com\/blog\/wp-content\/uploads\/2019\/02\/icons.png 768w, https:\/\/www.netexl.com\/blog\/wp-content\/uploads\/2019\/02\/icons-280x47.png 280w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Changes from <a href=\"https:\/\/www.netexl.com\/blog\/phaser-3-scale-manager-is-here-exploring-phaser-3-with-3-16-1-version-now\/\" target=\"_blank\">previous code<\/a> is marked below<\/p>\n<pre class=\"lang:default mark:93-97,132-133,136-144 decode:true\">let loadGame = function () {\r\n    let config = {\r\n        type: Phaser.AUTO,\r\n        scale: {\r\n            parent: 'mygame',\r\n            mode: Phaser.Scale.FIT,\r\n            autoCenter: Phaser.Scale.CENTER_BOTH,\r\n            width: window.innerWidth,\r\n            height: window.innerHeight\r\n        },\r\n        backgroundColor: 0xFF0000,\r\n        scene: TheGame\r\n    }\r\n\r\n    let game = new Phaser.Game(config);\r\n};\r\n\r\nif (document.readyState === \"complete\" || (document.readyState !== \"loading\" &amp;&amp; !document.documentElement.doScroll)) {\r\n    loadGame();\r\n} else {\r\n    document.addEventListener(\"DOMContentLoaded\", loadGame);\r\n}\r\n\r\nclass TheGame extends Phaser.Scene {\r\n\r\n    constructor() {\r\n        super(\"TheGame\");\r\n    }\r\n\r\n    preload() {\r\n        this.load.spritesheet(\"pegs\", \"images\/pegs.png\", {\r\n            frameWidth: 60,\r\n            frameHeight: 60\r\n        });\r\n        this.load.spritesheet(\"icons\", \"images\/icons.png\", {\r\n            frameWidth: 128,\r\n            frameHeight: 128\r\n        });\r\n    }\r\n\r\n    create() {\r\n        this.boardDef = [\r\n            [-1, -1, 1, 1, 1, -1, -1],\r\n            [-1, -1, 1, 1, 1, -1, -1],\r\n            [1, 1, 1, 1, 1, 1, 1],\r\n            [1, 1, 1, 0, 1, 1, 1],\r\n            [1, 1, 1, 1, 1, 1, 1],\r\n            [-1, -1, 1, 1, 1, -1, -1],\r\n            [-1, -1, 1, 1, 1, -1, -1]\r\n        ];\r\n\r\n        \/\/  If a Game Object is clicked on, this event is fired.\r\n        \/\/  We can use it to emit the 'clicked' event on the game object itself.\r\n        this.input.on('gameobjectup', function (pointer, gameObject) {\r\n            gameObject.emit('clicked', gameObject);\r\n        }, this);\r\n\r\n        \/\/ add our sprites\r\n        this.board = [];\r\n        this.selectedPeg = null;\r\n        this.movesCount = 0;\r\n        this.isMoving = false;\r\n\r\n        for (let i = 0, len = this.boardDef.length; i &lt; len; i++) {\r\n            let r = this.boardDef[i];\r\n            let row = [];\r\n            this.board.push(row);\r\n            for (let j = 0, cnt = r.length; j &lt; cnt; j++) {\r\n                let c = r[j];\r\n                if (c &gt;= 0) {\r\n                    let cell = this.add.image(-900, -900, \"pegs\");\r\n                    cell.setFrame(c &gt; 0 ? 1 : 0);\r\n                    cell.setOrigin(0);\r\n\r\n                    \/\/ enable input events\r\n                    cell.setInteractive();\r\n                    cell.on('clicked', this.clickPeg, this);\r\n                    cell.gridX = i;\r\n                    cell.gridY = j;\r\n                    row.push(cell);\r\n                } else {\r\n                    row.push(null);\r\n                }\r\n            }\r\n        }\r\n        this.movesLabel = this.add.text(-900, -900, 'Moves: ' + this.movesCount, { fontFamily: \"Arial Black\", fontSize: 40, color: \"#fff\" });\r\n        this.movesLabel.setShadow(2, 2, 'rgba(0, 0, 0, 0.5)', 2);\r\n\r\n        this.tempPeg = this.add.sprite(-200, -200, \"pegs\");\r\n        this.tempPeg.setFrame(1);\r\n        this.tempPeg.setOrigin(0);\r\n\r\n        this.fullScreenButton = this.add.image(-900, -900, 'icons');\r\n        this.fullScreenButton.setFrame(4);\r\n        this.fullScreenButton.setInteractive();\r\n        this.fullScreenButton.setOrigin(0);\r\n        this.fullScreenButton.on('pointerup', this.handleFullScreen, this);\r\n\r\n        let gameWidth = this.cameras.main.width;\r\n        let gameHeight = this.cameras.main.height;\r\n        this.positionControls(gameWidth, gameHeight);\r\n    }\r\n\r\n    positionControls(width, height) {\r\n        if (this.pegTween &amp;&amp; this.pegTween.isPlaying()) {\r\n            \/\/this.pegTween.stop();\r\n            \/\/this.pegTween = null;\r\n        }\r\n\r\n        \/\/ 7 pegs + leave space equivalent for 1 peg on each side\r\n        let pegSize = Math.min(width \/ 9, height \/ 9);\r\n        let pegScale = localScaleManager.scaleSprite(this.tempPeg, pegSize, pegSize, 0, 1, true);\r\n        let horizontalMargin = (width - 7 * pegSize) \/ 2;\r\n        let verticalMargin = (height - 7 * pegSize) \/ 2;\r\n\r\n        let colsCount = this.board.length;\r\n        for (let i = 0; i &lt; colsCount; i++) {\r\n            let col = this.board[i];\r\n            for (let j = 0, cnt = col.length; j &lt; cnt; j++) {\r\n                let c = col[j];\r\n                if (c) {\r\n                    localScaleManager.scaleSpriteTo(c, pegScale);\r\n                    c.setPosition(horizontalMargin + i * pegSize, verticalMargin + j * pegSize);\r\n                }\r\n            }\r\n        }\r\n\r\n        localScaleManager.scaleText(this.movesLabel, width, pegSize, Math.min(width, pegSize * 0.2), 1, true);\r\n        this.movesLabel.setPosition(width \/ 2 - this.movesLabel.displayWidth \/ 2, 0);\r\n        this.pegSize = pegSize;\r\n\r\n        localScaleManager.scaleSprite(this.fullScreenButton, pegSize, pegSize, pegSize * 0.2, 1, true);\r\n        this.fullScreenButton.setPosition(width - this.fullScreenButton.displayWidth - 5, height - this.fullScreenButton.displayWidth - 5);\r\n    }\r\n\r\n    handleFullScreen() {\r\n        if (this.scale.isFullscreen) {\r\n            this.scale.stopFullscreen();\r\n            this.fullScreenButton.setFrame(4);\r\n        } else {\r\n            this.scale.startFullscreen();\r\n            this.fullScreenButton.setFrame(5);\r\n        }\r\n    }\r\n\r\n    updateMoves(movesCount) {\r\n        let width = this.cameras.main.width;\r\n        this.movesLabel.setText('Moves: ' + movesCount);\r\n        this.movesLabel.setPosition(width \/ 2 - this.movesLabel.displayWidth \/ 2, 0);\r\n    }\r\n\r\n    gameOver() {\r\n        this.registry.set('gamedata', { movesCount: this.movesCount, remainingPegs: this.remainingPegs() });\r\n        this.cameras.main.fade(500);\r\n        this.time.delayedCall(500, function () {\r\n            let gameOver = new GameOver('GameOver');\r\n            this.scene.add('GameOver', gameOver, true);\r\n            this.scene.remove('TheGame');\r\n        }, [], this)\r\n    }\r\n\r\n    isAnyValidMove() {\r\n        let colsCount = this.board.length;\r\n        for (let i = 0; i &lt; colsCount; i++) {\r\n            let col = this.board[i];\r\n            for (let j = 0, endIndex = col.length - 3; j &lt;= endIndex; j++) {\r\n                let c1 = col[j];\r\n                let c2 = col[j + 1];\r\n                let c3 = col[j + 2];\r\n\r\n                if (c1 &amp;&amp; c2 &amp;&amp; c3) {\r\n                    if (c1.frame.name !== 0 &amp;&amp; c2.frame.name !== 0 &amp;&amp; c3.frame.name === 0) return true;\r\n                    if (c1.frame.name === 0 &amp;&amp; c2.frame.name !== 0 &amp;&amp; c3.frame.name !== 0) return true;\r\n                }\r\n            }\r\n        }\r\n\r\n        let rowsCount = this.board[0].length;\r\n        for (let i = 0, len = colsCount - 3; i &lt;= len; i++) {\r\n            let r1 = this.board[i];\r\n            let r2 = this.board[i + 1];\r\n            let r3 = this.board[i + 2];\r\n            for (let j = 0; j &lt; rowsCount; j++) {\r\n                let c1 = r1[j];\r\n                let c2 = r2[j];\r\n                let c3 = r3[j];\r\n\r\n                if (c1 &amp;&amp; c2 &amp;&amp; c3) {\r\n                    if (c1.frame.name !== 0 &amp;&amp; c2.frame.name !== 0 &amp;&amp; c3.frame.name === 0) return true;\r\n                    if (c1.frame.name === 0 &amp;&amp; c2.frame.name !== 0 &amp;&amp; c3.frame.name !== 0) return true;\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n    remainingPegs() {\r\n        let pegs = 0;\r\n        for (let i = 0, len = this.board.length; i &lt; len; i++) {\r\n            let row = this.board[i];\r\n            for (let j = 0, cnt = row.length; j &lt; cnt; j++) {\r\n                let cell = row[j];\r\n                if (cell &amp;&amp; cell.frame.name !== 0) {\r\n                    pegs++\r\n                }\r\n            }\r\n        }\r\n        return pegs;\r\n    }\r\n\r\n    clickPeg(peg) {\r\n        if (this.isMoving) return;\r\n\r\n        if (peg.frame.name === 0) {\r\n            \/\/ if we have not selected a peg to jump then no need to move any further\r\n            if (!this.selectedPeg)\r\n                return;\r\n\r\n            let clickedX = peg.gridX;\r\n            let clickedY = peg.gridY;\r\n            let selectedX = this.selectedPeg.gridX;\r\n            let selectedY = this.selectedPeg.gridY;\r\n\r\n            if ((clickedX + 2 === selectedX || clickedX - 2 === selectedX) &amp;&amp; clickedY === selectedY) {\r\n                \/\/ move horizontal\r\n                let pegToRemove = this.board[(selectedX + clickedX) \/ 2][clickedY];\r\n                if (pegToRemove.frame.name === 0)\r\n                    return;\r\n\r\n                this.updateMoves(++this.movesCount);\r\n                this.removePeg(this.tempPeg, this.selectedPeg, peg, pegToRemove);\r\n\r\n                this.selectedPeg.setFrame(0);\r\n                this.selectedPeg = null;\r\n\r\n            } else if ((clickedY + 2 === selectedY || clickedY - 2 === selectedY) &amp;&amp; clickedX === selectedX) {\r\n                \/\/ move vertical\r\n                let pegToRemove = this.board[clickedX][(selectedY + clickedY) \/ 2];\r\n                if (pegToRemove.frame.name === 0)\r\n                    return;\r\n\r\n                this.updateMoves(++this.movesCount);\r\n                this.removePeg(this.tempPeg, this.selectedPeg, peg, pegToRemove);\r\n\r\n                this.selectedPeg.setFrame(0);\r\n                this.selectedPeg = null;\r\n            }\r\n\r\n        } else {\r\n            if (this.selectedPeg) {\r\n                if (peg === this.selectedPeg) {\r\n                    peg.setFrame(1);\r\n                    this.selectedPeg = null;\r\n                } else {\r\n                    this.selectedPeg.setFrame(1);\r\n                    this.selectedPeg = peg;\r\n                    peg.setFrame(2);\r\n                }\r\n            } else {\r\n                this.selectedPeg = peg;\r\n                peg.setFrame(2);\r\n            }\r\n        }\r\n    }\r\n\r\n    removePeg(tempPeg, selectedPeg, targetPeg, pegToRemove) {\r\n        tempPeg.setPosition(selectedPeg.x, selectedPeg.y);\r\n        tempPeg.targetPeg = targetPeg;\r\n        tempPeg.removePeg = pegToRemove;\r\n        tempPeg.visible = true;\r\n        var self = this;\r\n        this.isMoving = true;\r\n        this.pegTween = this.tweens.add({\r\n            targets: tempPeg,\r\n            x: targetPeg.x,\r\n            y: targetPeg.y,\r\n            duration: 200,\r\n            delay: 50,\r\n            onStart: function (tween) {\r\n                let sprite = tween.targets[0];\r\n                sprite.removePeg.setFrame(0);\r\n            },\r\n            onComplete: function (tween) {\r\n                self.isMoving = false;\r\n                let sprite = tween.targets[0];\r\n                sprite.targetPeg.setFrame(1);\r\n                sprite.visible = false;\r\n                self.pegTween = null;\r\n                if (!self.isAnyValidMove()) {\r\n                    self.cameras.main.shake(2000, 0.005); \/\/ second parameter is just the shake intensity\r\n                    let timedEvent = self.time.addEvent({\r\n                        delay: 2000,\r\n                        callbackScope: this,\r\n                        callback: function () {\r\n                            self.gameOver();\r\n                        }\r\n                    });\r\n                }\r\n            }\r\n        });\r\n    }\r\n}\r\n\r\n<\/pre>\n<p>Check out the game in your browser window\u00a0<a href=\"https:\/\/www.netexl.com\/blog\/demo\/19\/index.html\" target=\"_blank\">here<\/a>. Try resizing it in your browser window to see scaling at work.<\/p>\n<p>You can\u00a0play the game here<\/p>\n\n<!-- iframe plugin v.5.2 wordpress.org\/plugins\/iframe\/ -->\n<iframe loading=\"lazy\" src=\"https:\/\/www.netexl.com\/blog\/demo\/19\/index.html\" width=\"600px\" height=\"600px\" allowfullscreen=\"true\" allow=\"fullscreen\" scrolling=\"yes\" class=\"iframe-class\" frameborder=\"0\"><\/iframe>\n\n","protected":false},"excerpt":{"rendered":"<p>Phaser 3 also has the full support for fullscreen mode.\u00a0Resizing a game to fullscreen is quite simple as shown in the code below. We are going to add a button to resize the game to fullscreen and then switch\u00a0the button\u00a0which will revert fullscreen mode to normal screen mode. We have updated icons sprite as following Changes from previous code is marked below let loadGame = function () { let config = { type: Phaser.AUTO, scale: { parent: &#8216;mygame&#8217;, mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH, width: window.innerWidth, height: window.innerHeight }, backgroundColor: 0xFF0000, scene: TheGame } let game = new Phaser.Game(config); }; if (document.readyState === &#8220;complete&#8221; || (document.readyState !== &#8220;loading&#8221; &amp;&amp; !document.documentElement.doScroll)) { loadGame(); } else { document.addEventListener(&#8220;DOMContentLoaded&#8221;, loadGame); } class TheGame extends Phaser.Scene { constructor() { super(&#8220;TheGame&#8221;); } preload() { this.load.spritesheet(&#8220;pegs&#8221;, &#8220;images\/pegs.png&#8221;, { frameWidth: 60, frameHeight: 60 }); this.load.spritesheet(&#8220;icons&#8221;, &#8220;images\/icons.png&#8221;, { frameWidth: 128, frameHeight: 128 }); } create() { this.boardDef = [ [-1,[&#8230;]<\/p>\n","protected":false},"author":5,"featured_media":293,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,24,4],"tags":[],"class_list":["post-1112","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-html5","category-javascript","category-phaser"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/posts\/1112","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/comments?post=1112"}],"version-history":[{"count":4,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/posts\/1112\/revisions"}],"predecessor-version":[{"id":1119,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/posts\/1112\/revisions\/1119"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/media\/293"}],"wp:attachment":[{"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/media?parent=1112"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/categories?post=1112"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.netexl.com\/blog\/wp-json\/wp\/v2\/tags?post=1112"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}