I was writing a snake game in JavaScript but whenever I press any WASD keys it returns this error:
Uncaught TypeError: Cannot read properties of undefined (reading 'set_direction')
at HTMLDocument.on_key_press (snake.js:66:28)
Here is my code, the constructor and draw functions work fine, the only problem is when pressing keys. The code continues running after the error is called but the snake does not change direction.:
class Snake {
constructor() {
this.position = [[2, 2], [1, 2]];
this.direction = 2;
}
draw(){
var canvas = document.getElementById("game_display_canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#FFFFFF";
for(let i = 0; i < this.position.length - 1; i++) {
ctx.fillRect(this.position[i][0] * 10, this.position[i][1] * 10, 10, 10);
}
}
move() {
const directions = [[0, -1], [1, 0], [0, 1], [-1, 0]];
let next_cell = this.position[this.position.length - 1];
next_cell = [next_cell[0] + directions[this.direction][0], next_cell[1] + directions[this.direction][1]];
this.position.push(next_cell);
}
set_direction(direction) {
this.direction = direction;
}
}
class GameManager {
constructor(snake) {
this.snake = snake;
}
on_key_press(event) {
const W_KEY = 87;
const A_KEY = 65;
const S_KEY = 83;
const D_KEY = 68;
let keyPressed = event.keyCode;
switch(keyPressed) {
case W_KEY:
this.snake.direction = 0;
break;
case A_KEY:
this.snake.set_direction(3);
break;
case S_KEY:
this.snake.set_direction(2);
break;
case D_KEY:
this.snake.set_direction(1);
break;
}
}
}
function main() {
const snake = new Snake()
const manager = new GameManager(snake);
running = true;
document.addEventListener("keydown", manager.on_key_press);
gameLoop(manager, running)
}
function gameLoop(manager, running) {
setTimeout(function onTick() {
manager.snake.move();
manager.snake.draw();
if (running) {
gameLoop(manager, running);
}
}, 100)
}
I tried both setting the attribute directly and using a set function within the snake class, but both cause the same error.
Edit: I can't figure out how to mark this as answered, but this answer from Titus what worked for me:
"Use something like this: document.addEventListener("keydown", manager.on_key_press.bind(manager)) – Titus"