ExcitedBeginner Posted March 25, 2018 Share Posted March 25, 2018 Hello! I'm a total beginner (both with this forum, and Phaser), so please forgive me for any mistakes. I am trying to combine two examples I found on the phaser.io website. This one, and this one. I want to pause the game when pressing the 'pause' button. I'm getting the error "Uncaught TypeError: Cannot read property 'onInputUp' of undefined" in the console. I'm using Phaser 3.2.0, and I understand that the examples I found are from an earlier version, so maybe that's why it's not working? Please help! This is my code: var config = { type: Phaser.AUTO, width: 800, height: 600, parent: 'game_2', physics: { default: 'arcade', arcade: { gravity: { y: 300 }, debug: false } }, scene: { preload: preload, create: create, update: update } }; var player; var stars; var bombs; var platforms; var cursors; var score = 0; var gameOver = false; var scoreText; var game = new Phaser.Game(config); function preload (){ this.load.image('sky', 'game_2/assets/sky.png'); this.load.image('ground', 'game_2/assets/platform.png'); this.load.image('star', 'game_2/assets/star.png'); this.load.image('bomb', 'game_2/assets/bomb.png'); this.load.spritesheet('dude', 'game_2/assets/dude.png', { frameWidth: 32, frameHeight: 48 }); } function create (){ // A simple background for our game this.add.image(400, 300, 'sky'); // The platforms group contains the ground and the 2 ledges we can jump on platforms = this.physics.add.staticGroup(); // Here we create the ground. // Scale it to fit the width of the game (the original sprite is 400x32 in size) platforms.create(400, 568, 'ground').setScale(2).refreshBody(); // Now let's create some ledges platforms.create(600, 400, 'ground'); platforms.create(50, 250, 'ground'); platforms.create(750, 220, 'ground'); // The player and its settings player = this.physics.add.sprite(100, 450, 'dude'); // Player physics properties. Give the little guy a slight bounce. player.setBounce(0.1); player.setCollideWorldBounds(true); // Our player animations, turning, walking left and walking right. this.anims.create({ key: 'left', frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }), frameRate: 10, repeat: -1 }); this.anims.create({ key: 'turn', frames: [ { key: 'dude', frame: 4 } ], frameRate: 20 }); this.anims.create({ key: 'right', frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }), frameRate: 10, repeat: -1 }); // Input Events cursors = this.input.keyboard.createCursorKeys(); // Some stars to collect, 12 in total, evenly spaced 70 pixels apart along the x axis stars = this.physics.add.group({ key: 'star', repeat: 11, setXY: { x: 12, y: 0, stepX: 70 } }); stars.children.iterate(function (child) { // Give each star a slightly different bounce child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8)); }); bombs = this.physics.add.group(); // The score scoreText = this.add.text(16, 16, 'score: 0', { font: '24px Arial', fill: '#fff' }); // Collide the player and the stars with the platforms this.physics.add.collider(player, platforms); this.physics.add.collider(stars, platforms); this.physics.add.collider(bombs, platforms); // Checks to see if the player overlaps with any of the stars, if he does call the collectStar function this.physics.add.overlap(player, stars, collectStar, null, this); this.physics.add.collider(player, bombs, hitBomb, null, this); /* Code for the pause menu */ var w = 800; var h = 600; // Create a label to use as a button pause_label = this.add.text(w - 100, 20, 'Pause', { font: '24px Arial', fill: '#fff' }); pause_label.inputEnabled = true; pause_label.events.onInputUp.add(function () { // When the pause button is pressed, we pause the game game.paused = true; // Then add the menu menu = game.add.sprite(w/2, h/2, 'menu'); menu.anchor.setTo(0.5, 0.5); // And a label to illustrate which menu item was chosen choiceLabel = game.add.text(w/2, h-150, 'Click outside menu to continue', { font: '30px Arial', fill: '#fff' }); choiceLabel.anchor.setTo(0.5, 0.5); }); // Add a input listener that can help us return from being paused game.input.onDown.add(unpause, self); // And finally the method that handels the pause menu function unpause(event){ // Only act if paused if(game.paused){ // Calculate the corners of the menu var x1 = w/2 - 270/2, x2 = w/2 + 270/2, y1 = h/2 - 180/2, y2 = h/2 + 180/2; // Check if the click was inside the menu if(event.x > x1 && event.x < x2 && event.y > y1 && event.y < y2 ){ // The choicemap is an array that will help us see which item was clicked var choicemap = ['one', 'two', 'three', 'four', 'five', 'six']; // Get menu local coordinates for the click var x = event.x - x1, y = event.y - y1; // Calculate the choice var choice = Math.floor(x / 90) + 3*Math.floor(y / 90); // Display the choice choiceLabel.text = 'You chose menu item: ' + choicemap[choice]; } else{ // Remove the menu and the label menu.destroy(); choiceLabel.destroy(); // Unpause the game game.paused = false; } } } } function update (){ if (gameOver) { return; } if (cursors.left.isDown) { player.setVelocityX(-160); player.anims.play('left', true); } else if (cursors.right.isDown) { player.setVelocityX(160); player.anims.play('right', true); } else { player.setVelocityX(0); player.anims.play('turn'); } if (cursors.up.isDown && player.body.touching.down) { player.setVelocityY(-330); } } function collectStar (player, star){ star.disableBody(true, true); // Add and update the score score += 10; scoreText.setText('Score: ' + score); if (stars.countActive(true) === 0) { // A new batch of stars to collect stars.children.iterate(function (child) { child.enableBody(true, child.x, 0, true, true); }); var x = (player.x < 400) ? Phaser.Math.Between(400, 800) : Phaser.Math.Between(0, 400); var bomb = bombs.create(x, 16, 'bomb'); bomb.setBounce(1); bomb.setCollideWorldBounds(true); bomb.setVelocity(Phaser.Math.Between(-200, 200), 20); bomb.allowGravity = false; } } function hitBomb (player, bomb){ this.physics.pause(); player.setTint(0xff0000); player.anims.play('turn'); gameOver = true; } Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 25, 2018 Share Posted March 25, 2018 There're no Signals in Phaser 3 any more. For input events you can do this: pause_label.on('pointerup', function(event) {}); And enable input listeners: pause_label.setInteractive(); ExcitedBeginner 1 Link to comment Share on other sites More sharing options...
ExcitedBeginner Posted March 25, 2018 Author Share Posted March 25, 2018 Thank you so much! I think I got it, kinda. I'm getting another error now. "Uncaught TypeError: Cannot read property 'sprite' of undefined" for the row that starts with menu = ... . I'm not sure why but I can't seem to access the game variable. // Create a label to use as a button pause_label = this.add.text(w - 100, 20, 'Pause', { font: '24px Arial', fill: '#fff' }); pause_label.setInteractive(); pause_label.on('pointerup', function(event) { // When the pause button is pressed, we pause the game game.paused = true; // Then add the menu menu = game.add.sprite(w/2, h/2, 'menu'); menu.anchor.setTo(0.5, 0.5); // And a label to illustrate which menu item was chosen choiceLabel = game.add.text(w/2, h-150, 'Click outside menu to continue', { font: '30px Arial', fill: '#fff' }); choiceLabel.anchor.setTo(0.5, 0.5); }); Also, how do I add the .add(unpause, self) part in this? (again, game.on doesn't seem to work. It's giving me a similar error to the one above) // Add a input listener that can help us return from being paused // game.input.onDown.add(unpause, self); game.on('pointerdown', function unpause(event) {}); Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 25, 2018 Share Posted March 25, 2018 Game instance should not be used for creating objects and input event handling, use the scene instead. // Create objects from a method of scene this.add.sprite(...) // Subscribe to input events of a scene this.input.on('pointerdown', function(event) {}, this) ExcitedBeginner 1 Link to comment Share on other sites More sharing options...
ExcitedBeginner Posted March 26, 2018 Author Share Posted March 26, 2018 20 hours ago, PixelPicoSean said: Game instance should not be used for creating objects and input event handling, use the scene instead. // Create objects from a method of scene this.add.sprite(...) // Subscribe to input events of a scene this.input.on('pointerdown', function(event) {}, this) I'm sorry, I don't understand how or where to use this in my code Link to comment Share on other sites More sharing options...
PixelPicoSean Posted March 26, 2018 Share Posted March 26, 2018 In methods of your scene class/object. `this` is exactly the scene instance. Link to comment Share on other sites More sharing options...
Recommended Posts