1

Ich verwende window.requestAnimationFrame, um eine Spielschleife zu erstellen.addEventListener mit requestAnimationFrame

Alles funktioniert gut, aber wenn ich versuche, einen Ereignis-Listener hinzuzufügen, feuert es hunderte Male sehr schnell.

Ich habe versucht, eine Schließung zu verwenden, aber das scheint nicht zu funktionieren.

game.update = function(){ 
    //code that runs every frame 
    window.addEventListener('keydown', function(){ 
     console.log("message"); 
    },false); 
} 

Ich möchte ONCE eine Funktion aufzurufen auf dem keydown Ereignis nicht mehrfach.

+0

* "Ich möchte eine Funktion ONCE beim Keydown-Event nicht mehrfach aufrufen." * Danach muss die Funktion nach dem Aufruf der Verbindung losgebunden werden. Warum binden Sie den Event-Handler trotzdem innerhalb der Schleife? Warum nicht draußen? Soll der Handler einmal pro Frame ausgeführt werden? Bitte erläutern Sie besser, welches Problem Sie damit lösen wollen. –

+0

Sie müssen Ereignis-Listener einmal und nicht innerhalb Ihrer Update-Schleife hinzufügen. Ihre Update-Schleife sollte nur Ereignis-Listener zu Objekten hinzufügen, die beim Erstellen erstellt werden. –

+0

Führen Sie diesen Code nicht innerhalb einer Funktion aus, die in jedem Frame ausgeführt wird. –

Antwort

0

Ereignis-Listener wird nur hinzugefügt, wenn ein neuer Listener hinzugefügt wird. Hinzufügen der gleiche Zuhörer mehr als einmal hat keine Wirkungby design.

Ihre Zuhörer Funktion aus der Funktion Sie zuweisen Verschieben game.update so dass eine neue Kopie der Zuhörer nicht jedes Mal, wenn addEventListener() rufen erstellt werden würde:

var updateListener = function() { 
    console.log('message'); 
}; 

game.update = function() { 
    //code that runs every frame 
    window.addEventListener('keydown', updateListener, false); 
}; 
+0

Ok, das hat funktioniert. Es hat sich einfach dazu gezwungen, es aus irgendeinem Grund in die Schleife zu werfen. – CriticalTheWizard

0

Vielleicht ein bisschen spät, aber das ergibt für mich keinen Sinn. Der Listener sollte nicht innerhalb des RAF hinzugefügt werden. Wenn Sie es nach draußen setzen und das Ergebnis des Handlers einer Variablen zuweisen, dann muss der RAF das Ergebnis erhalten und die Variable löschen, und Sie erhalten eine schnellere und stabilere/vorhersagbare Leistung. Dies wird bei ähnlichen Aufgaben, wie beispielsweise der Verwendung von Geräteorientierungs-Listenern für die Controller-Eingabe auf Mobilgeräten, offensichtlich. Ereignisse müssen nicht geloopt werden. Stellen Sie es einmal ein, es wird jedes Mal ausgelöst, wenn eine Taste gedrückt wird. Der RAF sollte nur zum Aktualisieren von Grafiken verwendet werden. Jede andere Logik sollte außerhalb sein. Zum Beispiel sollten Bewegung und Spielmechanik in einem setInterval sein, das ihre Ergebnisse auf Variablen und Objekte außerhalb des RAF verweist. Der RAF sollte nur die neuen Positionswerte aufnehmen und die Transformationen festlegen. Dann läuft es flüssiger, und "Zeit" wird nicht beschleunigt oder verlangsamt und ist unabhängig von der Bildrate auf verschiedenen Geräten konsistent.