1

Я пишу простую игру в JavaScript, который уже обрабатывает основной ввод с клавиатуры, как так:Как справиться с событиями в главном игровом цикле?

var input = {}; 
document.onkeydown = function(e) { 
    input[e.keyCode] = true; 
} 
document.onkeyup = function(e) { 
    input[e.keyCode] = false; 
} 

while (!done) { 
    handleInput(input); 
    update(); 
    render(); 
} 

Теперь мне нужна игра для обработки ключевых комбо (например, CTRL + X, например). Я хотел был бы принять такие комбо на keyup только.

EDIT: Клавиши-модификаторы не нужно входить в то же время, что и «основная» клавиша. /EDIT

два возможных решения, которые приходят в мой ум:

  • обнажая массив, содержащий список keyup событий (объект с «основными» клавиш-модификаторов плюс). Функция handleInput будет отвечать за слив очереди при каждом ее опросе
  • отслеживание возможных комбинаций клавиш внутри handleInput (просмотр удерживаемых клавиш модификатора) и запуск комбинированного режима, когда «основная» клавиша поднимается (я фактически не нравится это так)

Не могли бы вы предложить мне элегантный способ продлить текущую функциональность?

+0

В любом случае, хороший вопрос! – PDKnight

ответ

1

Все, что вам нужно сделать, это создать переменную upInput, в которой вы будете хранить ключи для ключей. Затем, чтобы проверить, была ли комбинация нажата, вы должны проверить, есть ли только CTRL + C (или 17, 67) комбо в переменной и если все они были true. Затем легко распечатайте сообщение и установите переменную upInput.

var input = upInput = {}; 

document.onkeydown = function(e) { 
    input[e.keyCode] = true; 
    if (JSON.stringify(Object.keys(upInput)) != '["17","67"]') 
     upInput = {}; 
} 
document.onkeyup = function(e) { 
    var k = e.keyCode; 
    input[k] = false; 
    if ([17, 67].indexOf(k) > -1) 
     upInput[k] = true; 
    if (JSON.stringify(Object.keys(upInput)) == '["17","67"]' 
      && upInput[17] && upInput[67]) // CTRL + C 
     alert('YES!'), 
     upInput = {}; 
} 

Demo

Надежда, что помогает!

+0

Mmm ... могу ли я сказать, что мне не нравится 'JSON.stringify (Object.keys (upInput)) == '[" 17 "," 67 "]'' бит?Кроме того, обработчики событий должны просто обновить состояние ввода, которое должно обрабатываться функцией 'handleInput' в основном цикле (код в моем вопросе неверен, я исправлю его) –

+0

@MarcoBolis' JSON.stringify() 'был самым быстрым вариантом, иначе мне пришлось создать пользовательскую функцию' .contains() 'для прототипа объекта. Как я понимаю, вам не нравится иметь код внутри ваших слушателей событий? Тогда это невозможно. Кроме того, вы не объявляете переменную 'done', поэтому ваш оператор while не имеет смысла в текущем коде. – PDKnight

+0

нет проблем с кодом внутри слушателей, мы просто вынимаем часть _handling_ и захлопываем ее в 'handleInput'. О бит, который мне не понравился, дело не в 'JSON.stringify()', я просто не доверяю 'Object.keys()', чтобы возвращать ключи в правильном порядке! –

0

Я бы в одном из этих способов:

  • Проверка комбинаций в части handleInput (вид вашей второй apporach)
  • Ведение списка самых последних X клавиатурных событий (где X является максимальная длина последовательности комбо) и проверить, соответствует ли этот список, чтобы любой предопределенный комбо триггеры
1

Попробуйте это;) это будет ppear сообщение при нажатии CTRL + X и отпустить один (или оба) из них

var map = {17: false, 88: false}; 
var fire_event = false; 

window.addEventListener('keydown', function(e) { 
    if (e.keyCode in map) { 
     map[e.keyCode] = true; 
     if (map[17] && map[88]) { 
      fire_event = true; 
     } 
    } 
}, false); 

window.addEventListener('keyup', function(e) { 
    if (e.keyCode in map) { 
     map[e.keyCode] = false; 
    } 
    if (fire_event) { 
     fire_event = false; 
     alert('YOU PRESSED CTRL + X'); 
    } 
}, false); 
+0

Первый раз, когда он работает, но после того, как я снова нажму Ctrl + x, он не пройдет. – PDKnight

+0

Попробуйте сейчас, я внес изменения ... Я не видел, чтобы это было указано «только на клавиатуре». – Dan

+0

Нет. Что делать, если я нажимаю 'CTRL + X + A' и' A'? Или 'CTRL + X', а затем' CTRL + C'? – PDKnight

0

Попробуйте, если он работает:

var KEY_QUEUE = []; 
var KEYs = [17, 88]; 

document.onkeydown = function (e) { 
    if (KEY_QUEUE.indexOf(e.keyCode) === -1) { 
     KEY_QUEUE.push(e.keyCode); 
    } 
}; 

document.onkeyup = function (e) { 
    var index = KEY_QUEUE.indexOf(e.keyCode); 
    if (isSubArray(KEYs, KEY_QUEUE) 
     && KEYs.indexOf(e.keyCode) > -1) { 
     console.log("You press CTRL + X"); 
    } 
    KEY_QUEUE.splice(index, 1); 
}; 

function isSubArray(ary, targetAry) { 
    return new RegExp(ary.toString()).test(targetAry.toString()); 
} 

Я проверил некоторые случаи, как Ctrl x, x Ctrl, Ctrl x a , Ctrl a x, и он работает так, как я ожидал. Но я не уверен, что это то же самое с идеей.

+0

Разве это решение не требует от пользователя выпускать ключи в точном порядке? –

+0

@Marco Bolis, это требует. 'Ctrl x' вызовет событие,' x Ctrl' не будет. И 'Ctrl a x' не будет работать, если вы сначала перенесите x или Ctrl, но он будет работать, если вы uppress' a' сначала оставите 'Ctrl' и' x' вместе. –