Jump to content
This forum will be closing down. Please move to the respective dedicated project forums.

Uncaught TypeError: Cannot read property 'x' of undefined


Kraken
 Share

Recommended Posts

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

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. 

Link to comment
Share on other sites

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

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

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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()
  }
}

 

Link to comment
Share on other sites

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

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...