Javascript 在对象属性上使用事件侦听器是否合适/好主意?
我正在用Javascript创建一个HTML5画布蛇游戏,在尝试使我的代码更面向对象时,我遇到了一种情况,我不确定我所做的是否有效Javascript 在对象属性上使用事件侦听器是否合适/好主意?,javascript,canvas,Javascript,Canvas,我正在用Javascript创建一个HTML5画布蛇游戏,在尝试使我的代码更面向对象时,我遇到了一种情况,我不确定我所做的是否有效 Game.prototype.gameOver = function() { game.isOver = true; clearInterval(intervalId); console.log("Game Over!"); window.addEventListener("keydown",
Game.prototype.gameOver = function() {
game.isOver = true;
clearInterval(intervalId);
console.log("Game Over!");
window.addEventListener("keydown", function(e) {
if (e.code === "Space") {
game.reset();
}
})
}
当蛇与墙或自身碰撞时,将调用game.gameOver()
只需在全局范围级别添加重置eventListener并检查游戏是否结束是更好的方法,还是完全可以
编辑:在发布这篇文章之后,我意识到每次调用gameOver时都会添加一个新的事件侦听器,这就是我的问题的根源。我已经修复了代码,因此事件侦听器的实例一次不会超过一次。只要在该侦听器启动后再次删除该侦听器,这应该没问题,唯一棘手的一点是,只有以与添加侦听器完全相同的方式删除它,才能删除该侦听器
在此处使用现代JS类语法而不是旧式原型语法:
class Game {
constructor(...args) {
// ...
this.reset();
}
reset() {
this.isOver = false;
// ...
// If reset() triggered from a window keydown event, remove
// that keydown listener so it will only kick in once:
if (this.resetHandler) {
window.removeEventListener(`keydown`, this.resetHandler);
this.resetHandler = false;
}
}
gameOver() {
this.isOver = true;
console.log(`Game Over!`);
// Create a function that can handle a keydown event
// and calls reset() if it's the right key, and bind
// it so we can remove it later:
this.resetHandler = (evt) => {
if (evt.code === `Space`) {
this.reset();
}
};
window.addEventListener(`keydown`, this.resetHandler);
console.log(`Press "space" on the page to continue...`);
}
}
请注意,arrow函数确保
此
保留为声明时的状态(即该函数运行的游戏
实例),而不是函数(evt){…}
,其中此
在运行时的作用域是什么(对于事件侦听器,它将是全局范围,即窗口
).这不是常见的做法,但也不是错误的做法。addEventListener用于随时随地添加事件。最好有一个密钥处理程序接口,该接口不做任何事情,只设置密钥的状态,然后从中构建逻辑。在这一天,您需要添加其他方式来重新启动游戏(移动?),您也必须更改该部分,但它不应是更改的一部分。最好在重置方法中删除侦听器,如果有其他调用重置,您的处理程序将保留,并且当用户按空格键时,游戏将无故重新启动。是的,这是一个公平点。更新后。