如何在游戏循环中使用 addEventListener
How to use addEventListener in a game loop
我是 Javascript 的新手,所以如果这是一个相当微不足道的问题,请多多包涵。
我正在尝试制作一款可以使用箭头键控制玩家的游戏。代码的简化版本(不起作用)如下所示:
class Player {
constructor(X) {
this.X = X;
}
}
class Game {
constructor() {
this.gamePlayer = new Player(0);
window.requestAnimationFrame(() => this.gameLoop());
}
playerMovement(event) {
switch (event.code) {
case "ArrowLeft":
console.log(this.gamePlayer.X);
this.gamePlayer.X -= 1;
break;
case "ArrowRight":
console.log(this.gamePlayer.X);
this.gamePlayer.X += 1;
break;
}
}
gameLoop() {
window.addEventListener("keydown", this.playerMovement);
setTimeout(() => {
window.requestAnimationFrame(() => this.gameLoop());
}, 50);
}
}
window.onload = () => {
let game = new Game();
};
所以,基本上,我想用左右箭头键控制 gamePlayer.X。但是,使用上面的代码,每当我按箭头键时,都会收到以下错误消息:
Uncaught TypeError: Cannot read property 'X' of undefined at playerMovement
所以我的问题是,为什么它不能在函数 playerMovement 中读取这个。gamePlayer.X?我应该如何更改代码才能使其正常工作?
您只需注册一次事件侦听器,在构造函数中注册不会有任何坏处。您似乎已经知道这一点,因为您在其他地方正在这样做,但是您收到错误的原因是当您使用 window.addEventListener("keydown", this.playerMovement);
而不是 window.addEventListener("keydown", (e) => this.playerMovement(e));
时范围发生了变化。当您直接传递函数时,作用域变为调用者的作用域 - 在本例中为 window
。 lambda 维护作用域。
我也不确定 setTimeout
在 gameloop
中做了什么,我怀疑它以后会给你带来麻烦。
class Player {
constructor(X) {
this.X = X;
}
}
class Game {
constructor() {
this.gamePlayer = new Player(0);
window.requestAnimationFrame(() => this.gameLoop());
window.addEventListener("keydown", (e) => this.playerMovement(e));
}
playerMovement(event) {
switch (event.code) {
case "ArrowLeft":
console.log(this.gamePlayer.X);
this.gamePlayer.X -= 1;
break;
case "ArrowRight":
console.log(this.gamePlayer.X);
this.gamePlayer.X += 1;
break;
}
}
gameLoop() {
window.requestAnimationFrame(() => this.gameLoop());
}
}
window.onload = () => {
let game = new Game();
};
我是 Javascript 的新手,所以如果这是一个相当微不足道的问题,请多多包涵。
我正在尝试制作一款可以使用箭头键控制玩家的游戏。代码的简化版本(不起作用)如下所示:
class Player {
constructor(X) {
this.X = X;
}
}
class Game {
constructor() {
this.gamePlayer = new Player(0);
window.requestAnimationFrame(() => this.gameLoop());
}
playerMovement(event) {
switch (event.code) {
case "ArrowLeft":
console.log(this.gamePlayer.X);
this.gamePlayer.X -= 1;
break;
case "ArrowRight":
console.log(this.gamePlayer.X);
this.gamePlayer.X += 1;
break;
}
}
gameLoop() {
window.addEventListener("keydown", this.playerMovement);
setTimeout(() => {
window.requestAnimationFrame(() => this.gameLoop());
}, 50);
}
}
window.onload = () => {
let game = new Game();
};
所以,基本上,我想用左右箭头键控制 gamePlayer.X。但是,使用上面的代码,每当我按箭头键时,都会收到以下错误消息:
Uncaught TypeError: Cannot read property 'X' of undefined at playerMovement
所以我的问题是,为什么它不能在函数 playerMovement 中读取这个。gamePlayer.X?我应该如何更改代码才能使其正常工作?
您只需注册一次事件侦听器,在构造函数中注册不会有任何坏处。您似乎已经知道这一点,因为您在其他地方正在这样做,但是您收到错误的原因是当您使用 window.addEventListener("keydown", this.playerMovement);
而不是 window.addEventListener("keydown", (e) => this.playerMovement(e));
时范围发生了变化。当您直接传递函数时,作用域变为调用者的作用域 - 在本例中为 window
。 lambda 维护作用域。
我也不确定 setTimeout
在 gameloop
中做了什么,我怀疑它以后会给你带来麻烦。
class Player {
constructor(X) {
this.X = X;
}
}
class Game {
constructor() {
this.gamePlayer = new Player(0);
window.requestAnimationFrame(() => this.gameLoop());
window.addEventListener("keydown", (e) => this.playerMovement(e));
}
playerMovement(event) {
switch (event.code) {
case "ArrowLeft":
console.log(this.gamePlayer.X);
this.gamePlayer.X -= 1;
break;
case "ArrowRight":
console.log(this.gamePlayer.X);
this.gamePlayer.X += 1;
break;
}
}
gameLoop() {
window.requestAnimationFrame(() => this.gameLoop());
}
}
window.onload = () => {
let game = new Game();
};