Я пытаюсь разработать игровой движок JavaScript, и я столкнулся с этой проблемой:
- Когда я нажимаю, SPACEперсонаж прыгает.
- Когда я нажимаю, →персонаж движется вправо.
Проблема в том, что когда я нажимаю вправо, а затем нажимаю пробел, персонаж прыгает, а затем перестает двигаться.
Я использую keydown
функцию, чтобы нажать клавишу. Как я могу проверить, нажаты ли несколько клавиш одновременно?
Ответы:
Примечание: keyCode больше не поддерживается .
Обнаружение множественных нажатий клавиш легко, если вы понимаете концепцию
То, как я это делаю, выглядит так:
Этот код очень прост: поскольку компьютер одновременно выполняет только одно нажатие клавиши, создается массив для отслеживания нескольких клавиш. Затем этот массив можно использовать для проверки одного или нескольких ключей одновременно.
Просто чтобы объяснить, скажем, вы нажимаете Aи B, каждый запускает
keydown
событие, которое устанавливаетmap[e.keyCode]
значениеe.type == keydown
, которое оценивается как истинное или ложное . Теперь обаmap[65]
иmap[66]
настроены наtrue
. Когда вы отпускаетеA
,keyup
событие запускается, в результате чего та же логика определяет противоположный результат дляmap[65]
(A), который теперь является ложным , но посколькуmap[66]
(B) все еще находится в состоянии «вниз» (он не вызвал событие keyup), это остается правдой .map
Массив, через оба события, выглядит следующим образом :Есть две вещи, которые вы можете сделать сейчас:
A) Ключевой регистратор ( пример ) может быть создан как справочник для последующего использования, когда вы хотите быстро выяснить один или несколько кодов клавиш. Предполагая, что вы определили элемент html и указали на него с помощью переменной
element
.Примечание. Вы можете легко получить элемент по его
id
атрибуту.Это создает элемент HTML, на который можно легко ссылаться в JavaScript с помощью
element
Вы даже не должны использовать
document.getElementById()
или$()
захватить это. Но для совместимости$()
рекомендуется использовать jQuery .Просто убедитесь, что тег script идет после тела HTML. Совет по оптимизации : большинство известных сайтов ставят тег script после тега body для оптимизации. Это связано с тем, что тег script блокирует дальнейшую загрузку элементов до завершения загрузки скрипта. Размещение его перед контентом позволяет загружать контент заранее.
B (в этом и заключается ваш интерес). Вы можете проверить один или несколько ключей за раз, где
/*insert conditional here*/
был, возьмите этот пример:Изменить : это не самый читаемый фрагмент. Читаемость важна, поэтому вы можете попробовать что-то вроде этого, чтобы облегчить глаза:
Использование:
Это лучше?
(конец редактирования)
Этот пример проверяет наличие CtrlShiftA, CtrlShiftBиCtrlShiftC
Это так же просто, как это :)
Ноты
Отслеживание ключевых кодов
Как правило, рекомендуется документировать код, особенно такие, как коды клавиш (например
// CTRL+ENTER
), чтобы вы могли помнить, что они были.Вы также должны поместить коды клавиш в том же порядке, что и документация (
CTRL+ENTER => map[17] && map[13]
, НЕmap[13] && map[17]
). Таким образом, вы никогда не запутаетесь, когда вам нужно вернуться и отредактировать код.Гоча с цепями if-else
Если вы проверяете комбинации разных сумм (например, CtrlShiftAltEnterи CtrlEnter), поместите меньшие комбинации после больших, иначе меньшие комбинации будут заменять большие комбинации, если они достаточно похожи. Пример:
Попался: "Эта комбинация клавиш продолжает активироваться, хотя я не нажимаю клавиши"
При работе с оповещениями или чем-либо, что фокусируется на главном окне, вы можете включить
map = []
сброс массива после выполнения условия. Это потому, что некоторые вещи, напримерalert()
, убирают фокус с главного окна и приводят к тому, что событие 'keyup' не запускается. Например:Получил: браузер по умолчанию
Вот неприятная вещь, которую я нашел, с включенным решением:
Проблема: поскольку браузер обычно выполняет действия по умолчанию для сочетаний клавиш (например, CtrlDактивирует окно закладок или CtrlShiftCактивирует skynote на maxthon), вы также можете добавить
return false
послеmap = []
, чтобы пользователи вашего сайта не разочаровались, когда «Дублирующийся файл» функция, которая ставится CtrlD, вместо этого добавляет в закладки страницу.Без
return false
, окно закладок будет всплывало, к ужасу пользователя.Заявление о возврате (новый)
Итак, вы не всегда хотите выйти из функции в этот момент. Вот почему
event.preventDefault()
функция есть. Он устанавливает внутренний флаг, который говорит интерпретатору не разрешать браузеру выполнять действие по умолчанию. После этого выполнение функции продолжается (тогда какreturn
сразу же выйдет из функции).Поймите это различие, прежде чем вы решите, использовать ли
return false
илиe.preventDefault()
event.keyCode
устарелаПользователь SeanVieira указал в комментариях, что
event.keyCode
устарел.Там он дал отличную альтернативу:,
event.key
которая возвращает строковое представление нажатой клавиши, например,"a"
для Aили"Shift"
дляShift .Я пошел вперед и приготовил инструмент для изучения указанных струн.
element.onevent
противelement.addEventListener
Обработчики, зарегистрированные в,
addEventListener
могут быть сложены, и вызываются в порядке регистрации, в то время как установка.onevent
непосредственно довольно агрессивна и переопределяет все, что у вас было ранее..onevent
Свойство кажется переопределить все и поведениеev.preventDefault()
иreturn false;
может быть весьма непредсказуемым.В любом случае, обработчики, зарегистрированные через
addEventlistener
кажется, легче написать и рассуждать.Это также
attachEvent("onevent", callback)
из нестандартной реализации Internet Explorer, но это не рекомендуется, и даже не относится к JavaScript (это относится к эзотерическому языку, называемому JScript ). Было бы в ваших интересах избегать как можно большего количества полиглотов.Вспомогательный класс
Чтобы устранить путаницу / жалобы, я написал «класс», который делает эту абстракцию ( ссылка для вставки ):
Этот класс не делает все и не будет обрабатывать все возможные варианты использования. Я не библиотекарь. Но для общего интерактивного использования это должно быть хорошо.
Чтобы использовать этот класс, создайте экземпляр и укажите его на элемент, с которым вы хотите связать ввод с клавиатуры:
То, что это будет делать, это присоединить новый слушатель ввода к элементу с помощью
#txt
(давайте предположим, что это текстовое поле) и установить точку наблюдения для комбинации клавишCtrl+5
. Когда обаCtrl
и5
выключены,"FIVE "
будет вызвана функция обратного вызова (в данном случае это функция, которая добавляет текстовую область). Обратный вызов связан с именемprint_5
, поэтому, чтобы удалить его, вы просто используете:Чтобы отсоединить
input_txt
отtxt
элемента:Таким образом, сборщик мусора может забрать объект (
input_txt
), если он будет выброшен, и у вас не останется старый прослушиватель событий зомби.Для краткости приведу краткую ссылку на API класса, представленный в стиле C / Java, чтобы вы знали, что они возвращают и какие аргументы они ожидают.
Обновление 2017-12-02 В ответ на запрос опубликовать это на github я создал суть .
Обновление 2018-07-21 Некоторое время я играл с декларативным стилевым программированием, и теперь этот путь мой любимый: fiddle , pastebin.
Как правило, он будет работать с теми случаями, которые вы реально хотите (ctrl, alt, shift), но если вам нужно нажать, скажем,
a+w
в то же время, не составит труда объединить подходы в мульти-ключ-поиска.Надеюсь, этот
подробныймини-блог сответомбыл полезен :)источник
return false
vspreventDefault()
keyCode
устарело - если вы переключитесь наkey
то, вы получите фактическое символьное представление ключа, которое может быть хорошим.myString[5]
это то же самое5[myString]
, и оно даже не даст вам предупреждение о компиляции (даже с-Wall -pedantic
)? Это связано с тем, чтоpointer[offset]
нотация берет указатель, добавляет смещение, а затем разыменовывает результат, делаяmyString[5]
то же самое, что и*(myString + 5)
.Вы должны использовать событие keydown, чтобы отслеживать нажатые клавиши, и вы должны использовать событие keyup, чтобы отслеживать, когда клавиши отпущены.
Посмотрите этот пример: http://jsfiddle.net/vor0nwe/mkHsU/
(Обновление: я воспроизводю код здесь, на случай, если jsfiddle.net не поможет :) HTML:
... и Javascript (используя jQuery):
В этом примере я использую массив для отслеживания нажатия клавиш. В реальном приложении вы можете захотеть
delete
каждый элемент после освобождения соответствующего ключа.Обратите внимание, что, хотя я использовал jQuery, чтобы упростить для себя задачу в этом примере, концепция работает так же хорошо при работе в «сыром» Javascript.
источник
onblur
обработчик событий, который удаляет все нажатые клавиши из массива. После того, как вы потеряли фокус, имеет смысл снова нажимать все клавиши. К сожалению, нет JS-эквивалентаGetKeyboardState
.источник
Я использовал этот способ (должен был проверить, где нажата Shift + Ctrl):
источник
для кого нужен полный пример кода. Правый + левый добавлен
источник
Заставьте клавишу даже вызывать несколько функций, каждая из которых проверяет определенную клавишу и реагирует соответствующим образом.
источник
Я бы попробовал добавить
keypress
Event
обработчикkeydown
. Например:Это просто для иллюстрации шаблона; Я не буду вдаваться в подробности здесь (особенно не в браузер уровня 2 +
Event
регистрация).Отпишитесь, пожалуйста, помогает ли это или нет.
источник
Если одна из нажатых клавиш - Alt / Crtl / Shift, вы можете использовать этот метод:
источник
источник
Это не универсальный метод, но он полезен в некоторых случаях. Это полезно для таких комбинаций, как CTRL+ somethingили Shift+ somethingили CTRL+ Shift+ somethingи т. Д.
Пример: если вы хотите распечатать страницу с помощью CTRL+ P, всегда CTRLследует первая нажатая клавиша P. То же самое с CTRL+ S, CTRL+ Uи другими комбинациями.
источник
Не самый лучший способ, я знаю.
источник
источник