Set Controls не работает для одного экземпляра объекта, но работает для другого
Я пытаюсь создать многопользовательскую игру с использованием JS.
function EvilBall(player,color)
{
EvilCircle.call(this,this.size,this.velY,this.velX);
this.color=color;
this.score =0;
this.player=player;
}
EvilBall.prototype=Object.create(EvilCircle.prototype);
EvilBall.prototype.constructor =EvilBall;
EvilBall.prototype.setControls=function(left,right,down,up){
var _this = this;
window.onkeydown = function(e) {
console.log(e.keyCode);
if (e.keyCode === left) {
_this.x -= _this.velX;
} else if (e.keyCode === right) {
_this.x += _this.velX;
} else if (e.keyCode === down) {
_this.y -= _this.velY;
} else if (e.keyCode === up) {
_this.y += _this.velY;
}
}
}
После этого я создаю два экземпляра EvilBall и устанавливаю там элементы управления, используя функцию setControls, внутри которой есть функция обработчика событий.
var evilBall = new EvilBall('p1','white');
var evilBall2 = new EvilBall('p2','yellow');
evilBall2.setControls(65,68,87,83);
evilBall.setControls(37,39,38,40);
При нажатии клавиш работает только экземпляр evilBall с ключами 37,39,38 и 40. Я понял, что поскольку evilBall упоминается ниже evilBall2, он работает нормально. Если обработчик событий работает нормально в одном случае, почему не работает в другом? Как мы можем разрабатывать многопользовательские игры в JS, когда обработчик событий работает только в одном экземпляре? Может кто-нибудь, пожалуйста, объясните мне это. Я что-то здесь упускаю?
1 ответ
Окно onkeydown является собственностью:
window.onkeydown = ()=>alert("one");
window.onkeydown = ()=>alert("two");//will override the first
window.onkeydown();
Так что используйте вместо этого window.addEventListner:
window.addEventListener("keydown",function(event){
...
});
В целом может быть лучше иметь только одного слушателя событий:
var keylisteners=[];
window.onkeydown=function(e){
(keylisteners.find(el=>el.key==e.keyCode)||{callback:function(){}}).callback();
};
Используйте как это:
keylisteners.push({
key:42,
callback:function(){}
});
Кстати, ваша функция shape не принимает аргументов:
Shape.call(this); //will do the job too