Anthony Boyac
Anthony Boyac

Reputation: 17

Javascript cannot read property 'x' of undefined?

I am making a game, and I get this error when I assign my collision function to a variable. I want to call my function inside another function, but I get this error. How do I get rid of it? The error is the 'x' in the 'let collision' function below:

var playerScore = 0;
let addScore = () => {
playerScore += 10;
document.getElementById("playerScore").innerHTML = playerScore;
};
let collision = (player, faller) => {
return player.x < faller.x + faller.width && player.x + player.width > faller.x &&
  player.y < faller.y + faller.height && player.y + player.height > faller.y
};

let draw = (millisecondsElapsed) => {
    game.clearRect(0, 0, canvas.width, canvas.height);
    fallers.forEach((faller) => {
        faller.draw();
        collision();
        //COLLISION FUNCTION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          if (collision === true) {
              game.clearRect(0, 0, canvas.width, canvas.height);
              addScore();
            };
        console.log(collision);
        faller.move(millisecondsElapsed);
    });

    player.draw();

    // Remove fallers that have hit the ground. You might have other reasons to remove fallers.
    fallers = fallers.filter((faller) => {
        return faller.y < canvas.height;
    });
};

Upvotes: 0

Views: 41

Answers (2)

machineghost
machineghost

Reputation: 35730

You are calling a collision function that expects certain arguments:

let collision = (player, faller) => {

but you aren't passing it any arguments (most importantly, you aren't passing it a player argument):

collision();

As a result, player is undefined and you get your error when you try to do:

player.x

because there is no undefined.x.

EDIT

As zfrisch suggested in the comments, one way you could fix this would be to define a default value for the player argument. If you do this then even when you call collision without arguments the browser would still have a value to use for player.

You can specify a default value by adding an = and the default value. For instance, if you did the following:

let collision = (player={x: 1}, faller) => {
    // ...
};
collision();

It will be exactly the same as if you had done:

collision({x: 1});

Upvotes: 1

gyre
gyre

Reputation: 16769

collision(player, faller) is a function defined to accept two arguments. You pass it none in your draw function when you write:

collision();

The default value for arguments that are not passed to a function is undefined. Thus, when you try to access x or y on either player or faller, an error is thrown: there is no logical value to return from a property access on "absent" values like null or undefined.

(null).x //=> throws Error
(undefined).x //=> throws Error

You were probably intending to pass your player and faller variables defined earlier, and cache the result to determine whether or not the two collided:

let collided = collision(player, faller);
if (collided) {
    game.clearRect(0, 0, canvas.width, canvas.height);
    addScore();
}
console.log(collided);

Full Revised Code:

var playerScore = 0;
let addScore = () => {
playerScore += 10;
document.getElementById("playerScore").innerHTML = playerScore;
};
let collision = (player, faller) => {
return player.x < faller.x + faller.width && player.x + player.width > faller.x &&
  player.y < faller.y + faller.height && player.y + player.height > faller.y
};

let draw = (millisecondsElapsed) => {
    game.clearRect(0, 0, canvas.width, canvas.height);
    fallers.forEach((faller) => {
        faller.draw();
        //COLLISION FUNCTION!!!!!!!
        let collided = collision(player, faller);
        if (collided) {
            game.clearRect(0, 0, canvas.width, canvas.height);
            addScore();
        }
        console.log(collided);
        faller.move(millisecondsElapsed);
    });

    player.draw();

    // Remove fallers that have hit the ground. You might have other reasons to remove fallers.
    fallers = fallers.filter((faller) => {
        return faller.y < canvas.height;
    });
};

Upvotes: 0

Related Questions