Ich versuche eine JavaScript-Spiel-Engine zu entwickeln und bin auf dieses Problem gestoßen:
- Wenn ich drücke SPACE, springt der Charakter.
- Wenn ich drücke →, bewegt sich der Charakter nach rechts.
Das Problem ist, dass wenn ich nach rechts drücke und dann die Leertaste drücke, der Charakter springt und sich dann nicht mehr bewegt.
Ich benutze die keydown
Funktion, um die Taste zu drücken. Wie kann ich überprüfen, ob mehrere Tasten gleichzeitig gedrückt wurden?
javascript
keydown
XCS
quelle
quelle
Antworten:
Hinweis: keyCode ist jetzt veraltet.
Die Erkennung mehrerer Tastenanschläge ist einfach, wenn Sie das Konzept verstehen
So mache ich das:
Dieser Code ist sehr einfach: Da der Computer jeweils nur einen Tastendruck durchläuft, wird ein Array erstellt, um mehrere Schlüssel zu verfolgen. Das Array kann dann verwendet werden, um gleichzeitig nach einem oder mehreren Schlüsseln zu suchen.
Nehmen wir zur Erklärung an, Sie drücken Aund B, jedes löst ein
keydown
Ereignis aus, dasmap[e.keyCode]
auf den Wert von gesetzte.type == keydown
ist und entweder als wahr oder falsch ausgewertet wird . Jetzt sind beidemap[65]
undmap[66]
eingestellt auftrue
. Wenn Sie loslassenA
, wird daskeyup
Ereignis ausgelöst, wodurch dieselbe Logik das entgegengesetzte Ergebnis fürmap[65]
(A) ermittelt, das jetzt falsch ist , aber damap[66]
(B) immer noch "down" ist (es hat kein Keyup-Ereignis ausgelöst). es bleibt wahr .Das
map
Array sieht bei beiden Ereignissen folgendermaßen aus:Sie können jetzt zwei Dinge tun:
A) Ein Schlüsselprotokollierer ( Beispiel ) kann als Referenz für später erstellt werden, wenn Sie schnell einen oder mehrere Schlüsselcodes herausfinden möchten. Angenommen, Sie haben ein HTML-Element definiert und mit der Variablen darauf verwiesen
element
.Hinweis: Sie können ein Element leicht anhand seines
id
Attributs erfassen.Dadurch wird ein HTML-Element erstellt, auf das in Javascript leicht verwiesen werden kann
element
Sie müssen es nicht einmal benutzen
document.getElementById()
oder$()
greifen. Aus Kompatibilitätsgründen sollten Sie jedoch jQuery's verwenden$()
allgemein empfohlen.Stellen Sie einfach sicher, dass das Skript- Tag hinter dem HTML-Text steht. Optimierungstipp : Die meisten namhaften Websites setzen das Skript- Tag zur Optimierung nach dem Body-Tag. Dies liegt daran, dass das Skript-Tag das Laden weiterer Elemente blockiert, bis das Herunterladen des Skripts abgeschlossen ist. Wenn Sie es vor den Inhalt stellen, kann der Inhalt zuvor geladen werden.
B (hier liegt Ihr Interesse) Sie können nach einem oder mehreren Schlüsseln gleichzeitig suchen
/*insert conditional here*/
. Nehmen Sie dieses Beispiel:Bearbeiten : Das ist nicht das am besten lesbare Snippet. Die Lesbarkeit ist wichtig, daher können Sie so etwas ausprobieren, um die Augen zu schonen:
Verwendung:
Ist das besser?
(Ende der Bearbeitung)
In diesem Beispiel wird überprüft CtrlShiftA, CtrlShiftBundCtrlShiftC
So einfach ist das :)
Anmerkungen
KeyCodes im Auge behalten
In der Regel empfiehlt es sich, Code zu dokumentieren, insbesondere Schlüsselcodes (wie
// CTRL+ENTER
), damit Sie sich daran erinnern können, was sie waren.Sie sollten die Schlüsselcodes auch in derselben Reihenfolge wie die Dokumentation
CTRL+ENTER => map[17] && map[13]
einfügen ( , NICHTmap[13] && map[17]
). Auf diese Weise werden Sie nie verwirrt, wenn Sie zurückgehen und den Code bearbeiten müssen.Ein Gotcha mit If-else-Ketten
Wenn Sie nach Combos mit unterschiedlichen Beträgen (wie CtrlShiftAltEnterund CtrlEnter) suchen, setzen Sie kleinere Combos nach größeren Combos. Andernfalls überschreiben die kleineren Combos die größeren Combos, wenn sie ähnlich genug sind. Beispiel:
Gotcha: "Diese Tastenkombination wird weiterhin aktiviert, obwohl ich die Tasten nicht drücke."
Wenn Sie mit Warnungen oder anderen Elementen arbeiten, die den Fokus aus dem Hauptfenster übernehmen, möchten Sie möglicherweise
map = []
das Array zurücksetzen, nachdem die Bedingung erfüllt ist. Dies liegt daran, dass einige Dinge, wie z. B.alert()
den Fokus vom Hauptfenster wegnehmen und dazu führen, dass das 'keyup'-Ereignis nicht ausgelöst wird. Beispielsweise:Gotcha: Browser-Standardeinstellungen
Hier ist eine nervige Sache, die ich mit der enthaltenen Lösung gefunden habe:
Problem: Da der Browser normalerweise Standardaktionen für Tastenkombinationen ausführt (z. B. CtrlDdas Lesezeichenfenster CtrlShiftCaktivieren oder Skynote auf maxthon aktivieren), möchten Sie möglicherweise auch
return false
nachher hinzufügenmap = []
, damit Benutzer Ihrer Website nicht frustriert werden, wenn die "Datei duplizieren" Wenn diese Funktion CtrlDaktiviert ist, wird stattdessen die Seite mit einem Lesezeichen versehen.Ohne würde
return false
das Lesezeichenfenster zum Entsetzen des Benutzers auftauchen.Die return-Anweisung (neu)
Okay, Sie möchten die Funktion an diesem Punkt nicht immer beenden. Deshalb ist die
event.preventDefault()
Funktion da. Es wird ein internes Flag gesetzt, das den Interpreter anweist, dem Browser nicht zu erlauben, seine Standardaktion auszuführen. Danach wird die Ausführung der Funktion fortgesetzt (währendreturn
die Funktion sofort beendet wird).Verstehen Sie diese Unterscheidung, bevor Sie sich für
return false
oder entscheidene.preventDefault()
event.keyCode
ist veraltetBenutzer SeanVieira wies in den Kommentaren darauf hin, dass
event.keyCode
veraltet ist.Dort gab er eine ausgezeichnete Alternative :
event.key
, die eine Zeichenfolgendarstellung der gedrückten Taste zurückgibt, wie"a"
für Aoder"Shift"
für Shift.Ich ging voran und kochte ein Werkzeug, um diese Saiten zu untersuchen.
element.onevent
vs.element.addEventListener
Mit registrierte Handler
addEventListener
können gestapelt werden und werden in der Reihenfolge der Registrierung aufgerufen, während die.onevent
direkte Einstellung ziemlich aggressiv ist und alles überschreibt, was Sie zuvor hatten.Die
.onevent
Eigenschaft scheint alles und das Verhalten von zu überschreibenev.preventDefault()
undreturn false;
kann ziemlich unvorhersehbar sein.In beiden Fällen
addEventlistener
scheinen über registrierte Handler einfacher zu schreiben und zu begründen zu sein.Es gibt auch
attachEvent("onevent", callback)
eine nicht standardmäßige Implementierung von Internet Explorer, die jedoch nicht mehr als veraltet ist und sich nicht einmal auf JavaScript bezieht (es handelt sich um eine esoterische Sprache namens JScript ). Es wäre in Ihrem besten Interesse, polyglotten Code so weit wie möglich zu vermeiden.Eine Helferklasse
Um Verwirrung / Beschwerden zu beheben, habe ich eine "Klasse" geschrieben, die diese Abstraktion ausführt ( Pastebin-Link ):
Diese Klasse macht nicht alles und behandelt nicht jeden denkbaren Anwendungsfall. Ich bin kein Bibliothekar. Für den allgemeinen interaktiven Gebrauch sollte dies jedoch in Ordnung sein.
Um diese Klasse zu verwenden, erstellen Sie eine Instanz und zeigen Sie auf das Element, dem Sie Tastatureingaben zuordnen möchten:
Dadurch wird dem Element mit einen neuen Eingabe-Listener hinzugefügt
#txt
angehängt (nehmen wir an, es handelt sich um einen Textbereich), und ein Überwachungspunkt für die Tastenkombination festgelegtCtrl+5
. Wenn beideCtrl
und nicht5
verfügbar sind, wird die von Ihnen übergebene Rückruffunktion (in diesem Fall eine Funktion, die"FIVE "
den Textbereich erweitert) aufgerufen. Der Rückruf ist mit dem Namen verknüpft.print_5
Um ihn zu entfernen, verwenden Sie einfach:So lösen Sie sich
input_txt
vomtxt
Element:Auf diese Weise kann die Garbage Collection das Objekt (
input_txt
) aufnehmen, falls es weggeworfen wird, und Sie haben keinen alten Zombie-Ereignis-Listener mehr übrig.Aus Gründen der Gründlichkeit finden Sie hier eine kurze Referenz zur API der Klasse, die im C / Java-Stil dargestellt wird, damit Sie wissen, was sie zurückgeben und welche Argumente sie erwarten.
Update 2017-12-02 Als Antwort auf eine Anfrage, dies in github zu veröffentlichen, habe ich eine Übersicht erstellt .
Update 2018-07-21 Ich habe eine Weile mit deklarativem Programmieren gespielt und dieser Weg ist jetzt mein persönlicher Favorit: Geige , Pastebin
Im Allgemeinen funktioniert es mit den Fällen, die Sie realistisch möchten (Strg, Alt, Umschalt), aber wenn Sie beispielsweise drücken müssen,
a+w
, wäre es nicht allzu schwierig, die Ansätze zu einem zu "kombinieren" Multi-Key-Lookup.Ich hoffe diese
gründlich erklärte AntwortMini-Blog war hilfreich :)quelle
return false
preventDefault()
keyCode
ist veraltet - wenn Sie zu wechseln, erhaltenkey
Sie die tatsächliche Zeichendarstellung des Schlüssels, was sehr hilfreich sein kann.myString[5]
dasselbe ist wie5[myString]
und dass Sie nicht einmal eine Kompilierungswarnung erhalten (auch nicht mit-Wall -pedantic
)? Es ist , weil diepointer[offset]
Notation der Zeiger nimmt, fügt den Offset und dereferenziert dann das Ergebnis, so dassmyString[5]
das gleiche wie*(myString + 5)
.Sie sollten das Keydown- Ereignis verwenden, um die gedrückten Tasten zu verfolgen, und Sie sollten die Tastenkombination verwenden Ereignis verwenden, um zu verfolgen, wann die Tasten losgelassen werden.
Siehe dieses Beispiel: http://jsfiddle.net/vor0nwe/mkHsU/
(Update: Ich reproduziere den Code hier, falls jsfiddle.net ausfällt :) Der HTML:
... und das Javascript (mit jQuery):
In diesem Beispiel verwende ich ein Array, um zu verfolgen, welche Tasten gedrückt werden. In einer realen Anwendung möchten Sie vielleicht
delete
jedes Element, sobald der zugehörige Schlüssel freigegeben wurde.Beachten Sie, dass ich in diesem Beispiel zwar jQuery verwendet habe, um mir die Arbeit zu erleichtern, das Konzept jedoch genauso gut funktioniert, wenn Sie in "rohem" Javascript arbeiten.
quelle
onblur
Ereignishandler hinzufügen , der alle gedrückten Tasten aus dem Array entfernt. Sobald Sie den Fokus verloren haben, ist es sinnvoll, alle Tasten erneut drücken zu müssen. Leider gibt es kein JS-Äquivalent zuGetKeyboardState
.quelle
Ich habe diesen Weg benutzt (musste überprüfen, wo Umschalt + Strg gedrückt wird):
quelle
für wer braucht vollständigen Beispielcode. Rechts + Links hinzugefügt
quelle
Lassen Sie den Keydown sogar mehrere Funktionen aufrufen, wobei jede Funktion nach einer bestimmten Taste sucht und entsprechend reagiert.
quelle
Ich würde versuchen, einen
keypress
Event
Handler hinzuzufügenkeydown
. Z.B:Dies soll nur ein Muster veranschaulichen; Ich werde hier nicht ins Detail gehen (insbesondere nicht auf die browserspezifische Level2 +
Event
Registrierung).Bitte zurückschicken, ob dies hilft oder nicht.
quelle
Wenn eine der gedrückten Tasten Alt / Strg / Umschalt ist, können Sie diese Methode verwenden:
quelle
quelle
Dies ist keine universelle Methode, aber in einigen Fällen nützlich. Es ist nützlich für Kombinationen wie CTRL+ somethingoder Shift+ somethingoder CTRL+ Shift+ somethingusw.
Beispiel: Wenn Sie drucken möchten , eine Seite mit CTRL+ Pgedrückt, ersten Schlüssel wird immer CTRLgefolgt von P. Gleiches gilt für CTRL+ S, CTRL+ Uund andere Kombinationen.
quelle
Nicht der beste Weg, ich weiß.
quelle
quelle