我正在使用socket.io进行一个简单的Pong游戏,它将state.player设置为0以使用户成为屏幕左侧的paddle,并将state.player设置为1以显示屏幕的右侧。
最终玩家将切换位置,因此需要移除并重新添加让鼠标控制屏幕右侧/左侧拨片的事件监听器,以便他们在屏幕的正确一侧控制正确的拨片。
我在某处读到你必须将函数存储在变量中然后在变量上调用removeEventListener,但这似乎并没有起作用。我在添加一个事件监听器之前将其删除,以便鼠标只能在屏幕的正确一侧控制正确的拨片。但当它们切换侧面时,鼠标控制两侧。
const choosePlayerSide = (player) =>{
function getLeftMouse(e){
let mousePos = calcMousePos(e);
lpaddle.y = mousePos.y - PADDLE_HEIGHT / 2;
socket.emit('mousePos', mousePos);
}
function getRightMouse(e){
let mousePos = calcMousePos(e);
rpaddle.y = mousePos.y - PADDLE_HEIGHT / 2;
socket.emit('mousePos', mousePos);
}
const gr = getRightMouse;
const gl = getLeftMouse;
if(player === 0){
console.log('choosing player 0')
this.setPlayer(0);
// Reset Event Listeners
canvas.removeEventListener('mousemove', gr);
canvas.removeEventListener('mousemove', gl);
canvas.addEventListener('mousemove', gl);
this.setInPlay();
}
else if(player === 1){
console.log('choosing player 1')
this.setPlayer(1);
canvas.removeEventListener('mousemove', gr);
canvas.removeEventListener('mousemove', gl);
canvas.addEventListener('mousemove', gr);
this.setInPlay();
socket.emit('newplayer');
}
}
答案 0 :(得分:1)
每次调用外部函数并执行时,嵌套在另一个函数体中的函数声明会创建新的函数对象。
每次调用getLeftMouse
时都会创建getRightMouse
和choosePlayerSide
的新实例,并且无法用于删除之前调用中添加的事件侦听器。< / p>
相关错误是在调用addEventListener
时使用函数表达式。每次添加事件监听器时都会创建一个新函数,通过在稍后调用removeEventListener
的语句中重复相同的函数表达式来删除它(评估每个函数表达式创建一个新的不同的函数对象) 。这是将处理函数存储在变量&#34;中的建议的来源。解决涉及函数表达式的这个版本的问题。
请注意,const
在编译时不会初始化变量并将其存储以便在多个调用中使用。它保护变量值在初始化后不被修改,但每次在函数代码中执行语句时都执行初始化。
要解决此问题,请在比getLeftMouse
更全局的级别声明getRightMouse
和choosePlayerSide
。根据游戏应用程序的组合方式,这可能在用于创建游戏的IEFE中或实际上在全局名称空间内(不推荐)。执行此操作后,您可以在添加/删除事件侦听器调用中使用其名称,而无需在局部变量gl
和gr
中复制它们的值。
答案 1 :(得分:0)
试试这个:
var _this = this;
addEventListener('click', this.clickhandler);
removeEventListener('click', this.clickhandler);
clickhander = (function () { _this. ; }); //use _this inside