如何在游戏循环中使用 addEventListener
Posted
技术标签:
【中文标题】如何在游戏循环中使用 addEventListener【英文标题】:How to use addEventListener in a game loop 【发布时间】:2021-05-17 06:46:57 【问题描述】:我对 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。但是,使用上面的代码,每当我按箭头键时,都会收到以下错误消息:
未捕获的类型错误:无法读取 playerMovement 处未定义的属性“X”
所以我的问题是,为什么它不能读取函数 playerMovement 中的 this.gamePlayer.X?我应该如何更改代码以使其正常工作?
【问题讨论】:
这能回答你的问题吗? How to access the correct `this` inside a callback? 你在编写井字游戏吗? 【参考方案1】:您只需要注册一次事件监听器,在构造函数中这样做不会有什么坏处。当您在其他地方执行此操作时,您似乎已经知道这一点,但是您收到错误的原因是当您使用 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();
;
【讨论】:
You only need to register the event listener once
虽然这是真的,但您没有解释您还更改了什么以及为什么要删除错误消息。
@t.niese 好点,将添加更多解释。以上是关于如何在游戏循环中使用 addEventListener的主要内容,如果未能解决你的问题,请参考以下文章