J'essaye de développer un moteur de jeu JavaScript et j'ai rencontré ce problème:
- Lorsque j'appuie sur SPACEle personnage saute.
- Quand j'appuie, →le personnage se déplace vers la droite.
Le problème est que lorsque j'appuie à droite et que j'appuie sur espace, le personnage saute puis s'arrête de bouger.
J'utilise la keydown
fonction pour appuyer sur la touche. Comment puis-je vérifier si plusieurs touches sont pressées à la fois?
Réponses:
Remarque: keyCode est désormais obsolète.
La détection de plusieurs touches est facile si vous comprenez le concept
La façon dont je le fais est comme ceci:
Ce code est très simple: comme l'ordinateur ne passe qu'une seule touche à la fois, un tableau est créé pour garder une trace de plusieurs touches. Le tableau peut ensuite être utilisé pour rechercher une ou plusieurs clés à la fois.
Juste pour expliquer, disons que vous appuyez sur Aet B, chacun déclenche un
keydown
événement qui prendmap[e.keyCode]
la valeur dee.type == keydown
, qui prend la valeur true ou false . Maintenant, les deuxmap[65]
etmap[66]
sont réglés surtrue
. Lorsque vous relâchezA
, l'keyup
événement se déclenche, ce qui fait que la même logique détermine le résultat opposé pourmap[65]
(A), qui est maintenant faux , mais puisquemap[66]
(B) est toujours "down" (il n'a pas déclenché d'événement keyup), cela reste vrai .Le
map
tableau, à travers les deux événements, ressemble à ceci:Il y a deux choses que vous pouvez faire maintenant:
A) Un enregistreur de frappe ( exemple ) peut être créé comme référence pour plus tard lorsque vous souhaitez comprendre rapidement un ou plusieurs codes de clé. En supposant que vous avez défini un élément html et que vous l'avez pointé avec la variable
element
.Remarque: vous pouvez facilement saisir un élément par son
id
attribut.Cela crée un élément html qui peut être facilement référencé en javascript avec
element
Vous n'avez même pas besoin de l'utiliser
document.getElementById()
ou$()
de l'attraper. Mais pour des raisons de compatibilité, l'utilisation de jQuery$()
est plus largement recommandée.Assurez-vous simplement que la balise de script vient après le corps du HTML. Conseil d'optimisation : la plupart des sites Web de grande renommée placent la balise script après la balise body pour l'optimisation. Cela est dû au fait que la balise de script empêche le chargement d'autres éléments jusqu'à ce que le téléchargement de son script soit terminé. Le placer avant le contenu permet au contenu de se charger à l'avance.
B (qui est là où réside votre intérêt) Vous pouvez vérifier une ou plusieurs clés à la fois où
/*insert conditional here*/
était, prenez cet exemple:Edit : Ce n'est pas l'extrait de code le plus lisible. La lisibilité est importante, vous pouvez donc essayer quelque chose comme ceci pour le rendre plus facile pour les yeux:
Usage:
Est-ce mieux?
(fin de modification)
Cet exemple vérifie pour CtrlShiftA, CtrlShiftBetCtrlShiftC
C'est aussi simple que ça :)
Remarques
Suivi des KeyCodes
En règle générale, il est recommandé de documenter le code, en particulier des éléments tels que les codes clés (comme
// CTRL+ENTER
), afin que vous puissiez vous souvenir de ce qu'ils étaient.Vous devez également mettre les codes clés dans le même ordre que la documentation (
CTRL+ENTER => map[17] && map[13]
, PASmap[13] && map[17]
). De cette façon, vous ne serez jamais confus lorsque vous devez revenir en arrière et modifier le code.Un gotcha avec des chaînes if-else
Si vous recherchez des combinaisons de quantités différentes (comme CtrlShiftAltEnteret CtrlEnter), placez des combos plus petits après des combos plus grands, sinon les combos plus petits remplaceront les combos plus grands s'ils sont assez similaires. Exemple:
Gotcha: "Cette combinaison de touches continue de s'activer même si je n'appuie pas sur les touches"
Lorsque vous traitez des alertes ou de tout ce qui prend le focus de la fenêtre principale, vous souhaiterez peut-être inclure
map = []
pour réinitialiser le tableau une fois la condition terminée. C'est parce que certaines choses, commealert()
, éloignent le focus de la fenêtre principale et empêchent l'événement 'keyup' de se déclencher. Par exemple:Gotcha: Paramètres par défaut du navigateur
Voici une chose ennuyeuse que j'ai trouvée, avec la solution incluse:
Problème: étant donné que le navigateur a généralement des actions par défaut sur les combinaisons de touches (comme CtrlDactive la fenêtre des signets ou CtrlShiftCactive skynote sur maxthon), vous pouvez également ajouter
return false
aprèsmap = []
, afin que les utilisateurs de votre site ne soient pas frustrés lorsque le "fichier en double" fonction, étant mis CtrlD, marque la page à la place.Sans
return false
, la fenêtre Bookmark s'affiche, au grand dam de l'utilisateur.La déclaration de retour (nouveau)
D'accord, vous ne voulez donc pas toujours quitter la fonction à ce stade. C'est pourquoi la
event.preventDefault()
fonction est là. Ce qu'il fait, c'est définir un indicateur interne qui indique à l'interpréteur de ne pas autoriser le navigateur à exécuter son action par défaut. Après cela, l'exécution de la fonction continue (alors qu'ellereturn
quittera immédiatement la fonction).Comprenez cette distinction avant de décider d'utiliser
return false
ou dee.preventDefault()
event.keyCode
est obsolèteL'utilisateur SeanVieira a souligné dans les commentaires qu'il
event.keyCode
est obsolète.Là, il a donné une excellente alternative:,
event.key
qui renvoie une représentation sous forme de chaîne de la touche enfoncée, comme"a"
pour Aou"Shift"
pour Shift.Je suis allé de l'avant et ai concocté un outil pour examiner lesdites cordes.
element.onevent
contreelement.addEventListener
Les gestionnaires enregistrés avec
addEventListener
peuvent être empilés et sont appelés dans l'ordre d'enregistrement, tandis que la définition.onevent
directe est plutôt agressive et remplace tout ce que vous aviez auparavant.La
.onevent
propriété semble avoir le dessus sur tout et sur le comportement deev.preventDefault()
etreturn false;
peut être plutôt imprévisible.Dans les deux cas, les gestionnaires enregistrés via
addEventlistener
semblent être plus faciles à écrire et à raisonner.Il existe également
attachEvent("onevent", callback)
une implémentation non standard d'Internet Explorer, mais cela est au-delà de obsolète et ne concerne même pas JavaScript (il appartient à un langage ésotérique appelé JScript ). Il serait dans votre intérêt d'éviter autant que possible le code polyglotte.Une classe d'aide
Pour résoudre les problèmes de confusion / plaintes, j'ai écrit une "classe" qui fait cette abstraction ( lien pastebin ):
Cette classe ne fait pas tout et ne gérera pas tous les cas d'utilisation imaginables. Je ne suis pas un bibliothécaire. Mais pour une utilisation interactive générale, cela devrait aller.
Pour utiliser cette classe, créez une instance et pointez-la vers l'élément auquel vous souhaitez associer l'entrée au clavier:
Ce que cela va faire, c'est attacher un nouvel écouteur d'entrée à l'élément avec
#txt
(supposons que c'est une zone de texte), et définir un point de surveillance pour la combinaison de touchesCtrl+5
. Lorsque les deuxCtrl
et5
sont en panne, la fonction de rappel que vous avez passée (dans ce cas, une fonction qui ajoute"FIVE "
à la zone de texte) sera appelée. Le rappel est associé au nomprint_5
, donc pour le supprimer, il vous suffit d'utiliser:Pour se détacher
input_txt
de l'txt
élément:De cette façon, le garbage collection peut récupérer l'objet (
input_txt
), s'il est jeté, et vous n'aurez plus un ancien écouteur d'événement zombie.Pour plus de précision, voici une référence rapide à l'API de la classe, présentée dans le style C / Java afin que vous sachiez ce qu'ils retournent et quels arguments ils attendent.
Mise à jour 02/12/2017 En réponse à une demande de publication sur github, j'ai créé un résumé .
Mise à jour 2018-07-21 Je joue avec la programmation de style déclaratif depuis un certain temps, et c'est maintenant mon préféré: violon , pastebin
Généralement, cela fonctionnera avec les cas que vous voudriez de manière réaliste (ctrl, alt, shift), mais si vous devez appuyer, disons,
a+w
en même temps, il ne serait pas trop difficile de "combiner" les approches en un recherche multi-clé.J'espère que ce mini-blog de
réponse bien expliqué aété utile :)la source
return false
vspreventDefault()
keyCode
est obsolète - si vous passez à,key
vous obtenez la représentation réelle des caractères de la clé, ce qui peut être agréable.myString[5]
c'est la même chose5[myString]
et que cela ne vous donnera même pas d'avertissement de compilation (même avec-Wall -pedantic
)? C'est parce que lapointer[offset]
notation prend le pointeur, ajoute le décalage, puis déréférence le résultat, faisantmyString[5]
la même chose que*(myString + 5)
.Vous devez utiliser l' événement keydown pour garder une trace des touches enfoncées, et vous devez utiliser l' événement keyup pour garder une trace du moment où les touches sont relâchées.
Voir cet exemple: http://jsfiddle.net/vor0nwe/mkHsU/
(Mise à jour: je reproduis le code ici, au cas où jsfiddle.net bails :) Le HTML:
... et le Javascript (en utilisant jQuery):
Dans cet exemple, j'utilise un tableau pour garder une trace des touches qui sont enfoncées. Dans une application réelle, vous souhaiterez peut-être utiliser
delete
chaque élément une fois la clé associée libérée.Notez que même si j'ai utilisé jQuery pour me faciliter les choses dans cet exemple, le concept fonctionne tout aussi bien lorsque vous travaillez en Javascript «brut».
la source
onblur
gestionnaire d'événements, qui supprime toutes les touches enfoncées du tableau. Une fois que vous avez perdu la mise au point, il serait logique de devoir appuyer à nouveau sur toutes les touches. Malheureusement, il n'y a pas d'équivalent JS àGetKeyboardState
.la source
J'ai utilisé cette façon (j'ai dû vérifier où est enfoncée Shift + Ctrl):
la source
pour qui a besoin d'un exemple de code complet. Droite + Gauche ajoutés
la source
Faites en sorte que la touche enfoncée appelle même plusieurs fonctions, chaque fonction recherchant une touche spécifique et répondant de manière appropriée.
la source
J'essaierais d'ajouter un
keypress
Event
gestionnairekeydown
. Par exemple:Ceci est simplement destiné à illustrer un modèle; Je n'entrerai pas dans les détails ici (surtout pas dans l'
Event
enregistrement de niveau2 + spécifique au navigateur ).Envoyez un message s'il vous plaît si cela aide ou non.
la source
Si l'une des touches appuyées est Alt / Crtl / Shift, vous pouvez utiliser cette méthode:
la source
la source
Ce n'est pas une méthode universelle, mais elle est utile dans certains cas. C'est utile pour les combinaisons comme CTRL+ somethingou Shift+ somethingou CTRL+ Shift+ something, etc.
Exemple: lorsque vous souhaitez imprimer une page en utilisant CTRL+ P, la première touche enfoncée est toujours CTRLsuivie de P. Idem avec CTRL+ S, CTRL+ Uet d'autres combinaisons.
la source
Pas la meilleure façon, je sais.
la source
la source