Возможный дубликат:
Кросс-браузерный способ автоматически повторять события нажатия клавиши, когда клавиша удерживается нажатой
Я пытаюсь создать простую игру на JavaScript/CSS/HTML и использую jQuery (и немного Underscore) для обработки нажатий клавиш. Игрок управляет блоком с помощью клавиш со стрелками. У меня возникла проблема с обработкой нескольких нажатий клавиш одновременно. У меня есть система, в которой закрытие отслеживает все нажатые клавиши со стрелками. Это хорошо работает, если игрок нажимает клавиши в следующей последовательности:
- Игрок нажимает Вниз (блок движется вниз)
- Игрок нажимает влево (блок движется по диагонали вниз-влево)
- Игрок отпускает вниз (блок движется влево)
- Игрок отпускает левый (блок останавливается
Однако блок останавливается, если шаги 3 и 4 меняются местами. Вот что на самом деле происходит в этом случае:
- Игрок нажимает Вниз (блок движется вниз)
- Игрок нажимает влево (блок движется по диагонали вниз-влево)
- Игрок отпускает левый (блок останавливается)
Ожидаемое поведение состоит в том, что на шаге 3 блок будет продолжать двигаться вниз, а не полностью останавливаться.
Судя по следам, которые я вставил в код, кажется, что событие нажатия клавиши фактически останавливает распространение дальнейших событий нажатия клавиши, даже когда мой палец все еще держит одну из клавиш со стрелками.
Вот фрагмент соответствующего кода. Может ли кто-нибудь сказать мне, где может быть проблема?
// Creates an animation handler for a specific element.
// Animation reacts to any changes as they are submitted
var getMovementAnimator = function(element) {
var params = {},
$element = $(element);
return function(changes) {
_.each(changes, function(val, key) {
// Remove null or zeroish keys from animation params
if ( (val == 0 || !val) && _.has(params, key)) {
delete params[key];
} else {
params[key] = '+=' + val + 'px';
}
});
$element.animate(params, {duration: 0, queue: false});
console.log(params);
};
};
// Determines direction and speed of movement for an element
// after a keypress event
var getMovementChange = function(keyEvent, keydown) {
var isMoving = !!keydown,
params = {},
dir = '',
speed = keydown ? 5 : 0,
arrows = {left: 37, up: 38, right: 39, down: 40};
switch (keyEvent.which) {
case arrows.left:
dir = 'left';
speed = -speed;
break;
case arrows.up:
dir = 'top';
speed = -speed;
break;
case arrows.right:
dir = 'left';
break;
case arrows.down:
dir = 'top';
break;
}
// If key hit not one of above, do nothing
if (!dir) {
return false;
}
if (!speed) {
console.log('key up: ', dir);
}
params[dir] = speed;
return params;
}
// Sets up key handlers
$(document).ready(function() {
var board = $('#board'),
animatePlayer = getMovementAnimator('.player');
$(document).keydown(function(e) {
e.preventDefault();
var changes = getMovementChange(e, true);
animatePlayer(changes);
}).keyup(function(e) {
e.preventDefault();
var changes = getMovementChange(e, false);
animatePlayer(changes);
});
});