Kraken Posted February 21, 2017 Share Posted February 21, 2017 I'm trying to make a flappy bird game and I'm getting an error Uncaught TypeError: Cannot read property 'x' of undefined Game.js:76 I'm not sure if its the constructor or something else giving me this error...I have attached the code for reference var FlappyBoard = FlappyBoard || {}; FlappyBoard.GameState = { init: function() { // bird gravity, will make bird fall if you don't flap this.birdGravity = 800; // horizontal bird speed this.birdSpeed = 125; // flap thrust this.birdFlapPower = 300; // milliseconds between the creation of two pipes this.pipeInterval = 2000; // hole between pipes, in puxels this.pipeHole = 120; this.score=0; this.pipeGroup = this.add.group(); }, create:function(){ this.topScore = localStorage.getItem("topFlappyScore")==null?0:localStorage.getItem("topFlappyScore"); scoreText = this.add.text(10,10,"-",{ font:"bold 16px Arial" }); this.updateScore(); this.stage.backgroundColor = "#87CEEB"; this.stage.disableVisibilityChange = true; //game.physics.startSystem(Phaser.Physics.ARCADE); this.bird = this.add.sprite(80,240,'bird'); this.bird.anchor.set(0.5); this.game.physics.arcade.enable(this.bird); this.bird.body.gravity.y = this.birdGravity; this.game.input.onDown.add(this.flap, this); this.game.time.events.loop(this.pipeInterval, this.addPipe); this.addPipe(); }, update:function(){ this.game.physics.arcade.collide(this.bird, this.pipeGroup, this.die, null, this); }, //this.game.state.start('GameState'); updateScore: function(){ scoreText.text = "Score: "+this.score+"\nBest: "+this.topScore; }, flap: function(){ this.bird.body.velocity.y = -this.birdFlapPower; }, addPipe: function(){ var pipeHolePosition = this.rnd.between(50,430-this.pipeHole); var upperPipe = new FlappyBoard.Pipe(this.game,320,pipeHolePosition-480,-this.birdSpeed, 'pipe'); this.game.add.existing(upperPipe); this.pipeGroup.add(upperPipe); var lowerPipe = new FlappyBoard.Pipe(this.game,320,pipeHolePosition+this.pipeHole,-this.birdSpeed); this.game.add.existing(lowerPipe); this.pipeGroup.add(lowerPipe); }, die: function(){ localStorage.setItem("topFlappyScore",Math.max(this.score,topScore)); } }; FlappyBoard.Pipe = function (game, x, y, speed) { Phaser.Sprite.call(this, game, x, y, 'pipe'); game.physics.enable(this, Phaser.Physics.ARCADE); this.body.velocity.x = speed; this.giveScore = true; }; FlappyBoard.Pipe.prototype = Object.create(Phaser.Sprite.prototype); FlappyBoard.Pipe.prototype.constructor = FlappyBoard.Pipe; FlappyBoard.Pipe.prototype.update = function() { if(this.x+this.width < this.bird.x && this.giveScore){ this.score+=0.5; this.updateScore(); this.giveScore = false; } if(this.x<-this.width){ this.destroy(); } }; Link to comment Share on other sites More sharing options...
samme Posted February 22, 2017 Share Posted February 22, 2017 1 hour ago, Kraken said: Uncaught TypeError: Cannot read property 'x' of undefined Game.js:76 What's on line 76? Link to comment Share on other sites More sharing options...
Kraken Posted February 22, 2017 Author Share Posted February 22, 2017 12 minutes ago, samme said: What's on line 76? if(this.x+this.width < this.bird.x && this.giveScore){ Link to comment Share on other sites More sharing options...
kcrabtree Posted February 22, 2017 Share Posted February 22, 2017 So, JS is telling you that you're trying to access a property on an object that is undefined. Since the property you're trying to access is x, take a look at the code on line 76 and see what objects are supposed to have an x property. Try logging these to the console or commenting things out until the error goes away. This will tell you what the problem is, then you can go about seeing why the object is undefined. Kraken and scheffgames 2 Link to comment Share on other sites More sharing options...
m7_b5 Posted February 22, 2017 Share Posted February 22, 2017 I wish it was easier to put these into a JSFiddle so I could play around with it. The only thing I can see by looking at your code is that you're calling the constructor for Pipe with 'Pipe' as a parameter, but your constructor doesn't have that parameter. I don't think it would give you the error that you're getting though. Link to comment Share on other sites More sharing options...
Kraken Posted February 22, 2017 Author Share Posted February 22, 2017 30 minutes ago, m7_b5 said: I wish it was easier to put these into a JSFiddle so I could play around with it. The only thing I can see by looking at your code is that you're calling the constructor for Pipe with 'Pipe' as a parameter, but your constructor doesn't have that parameter. I don't think it would give you the error that you're getting though. Yes I noticed that as well but you're right it did not fix the issue Link to comment Share on other sites More sharing options...
mattstyles Posted February 22, 2017 Share Posted February 22, 2017 Add a line before 76 and log out both `this` and `this.bird`, I'd expect `this` to be an instance of FlappyBoard.Pipe and `this.bird` to be undefined. Now add a new line before line 29 that logs out `this`, I'd expect it to be an instance of FlappyBoard.GameState. I'm hoping that you're guessing where I'm going with this. Looks to me like you've created `bird` on the GameState and you're trying to reference from Pipe, hence explosion. Kraken 1 Link to comment Share on other sites More sharing options...
scheffgames Posted February 22, 2017 Share Posted February 22, 2017 Argument checking it's often disregarded and so it leads to these kind of beauties. It's even worse when you get this after your game is launched. So you're lucky that you caught it on time - next time do arg checks for at least essential pieces of the code, ideally for everything and issue an console.warning when encountered so you'll know what to fix. Kraken 1 Link to comment Share on other sites More sharing options...
samme Posted February 22, 2017 Share Posted February 22, 2017 It's often easier to have the state exercise control, since it already has references to the game objects. It also helps avoid context (this) conflicts. FlappyBoard.GameState = { // […] update: function () { this.game.physics.arcade.collide(this.bird, this.pipeGroup, this.die, null, this) this.pipeGroup.forEachAlive(this.updatePipe, this) }, updatePipe: function (pipe) { if (pipe.x + pipe.width < this.bird.x && pipe.giveScore) { this.score += 0.5 this.updateScore() pipe.giveScore = false } }, // […] } FlappyBoard.Pipe = function (game, x, y, speed) {} // […] FlappyBoard.Pipe.prototype.update = function () { if (this.x < -this.width) { this.destroy() } } Kraken 1 Link to comment Share on other sites More sharing options...
Kraken Posted February 22, 2017 Author Share Posted February 22, 2017 17 minutes ago, samme said: It's often easier to have the state exercise control, since it already has references to the game objects. It also helps avoid context (this) conflicts. FlappyBoard.GameState = { // […] update: function () { this.game.physics.arcade.collide(this.bird, this.pipeGroup, this.die, null, this) this.pipeGroup.forEachAlive(this.updatePipe, this) }, updatePipe: function (pipe) { if (pipe.x + pipe.width < this.bird.x && pipe.giveScore) { this.score += 0.5 this.updateScore() pipe.giveScore = false } }, // […] } FlappyBoard.Pipe = function (game, x, y, speed) {} // […] FlappyBoard.Pipe.prototype.update = function () { if (this.x < -this.width) { this.destroy() } } This did the trick thanks alot Samme! Link to comment Share on other sites More sharing options...
Recommended Posts