L'event "keydown" s'active plusieurs fois

Résolu
Hibou-Propulseur Messages postés 3 Date d'inscription   Statut Membre Dernière intervention   -  
kaneagle Messages postés 86481 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour !
Je travaille le déplacement dans un petit moteur 3D, et j'utilise pour cela les touches du clavier.
En gros, quand on appuie sur "z", on avance jusqu'à ce qu'on relève la touche.
J'utilise donc les événements
keyup
et
keydown
avec un écouteur d'événement.
Tout marche très bien (keydown lance un "setInterval", et keyup le supprime). Seulement si on appuie un peu trop longtemps, keyup se lance plusieurs fois et il n'y a plus assez de keyup pour supprimer les boucles... Pourquoi ? Comment changer ça ?
Merci !

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>3D</title>
  </head>
  <body onload="initialiser();">
 <p id="x">x:</p>
 <p id="y">y:</p>
 <p id="z">z:</p>
    <script src="jsTEST.js"></script>
  </body>
</html>


function refresh(){
 pX.innerHTML = "x: "+xC;
 pY.innerHTML = "y: "+yC;
 pZ.innerHTML = "z: "+zC;
}

function initialiser(){
 console.log("---creation des touches d'écoute---");
 var dict = {
  90 : function(){//Z
   zC += vitesse/nbDePasParSec;
  },
  81 : function(){//Q
   xC -= vitesse/nbDePasParSec;
  },
  83 : function(){//S
   zC -= vitesse/nbDePasParSec;
  },
  68 : function(){//D
   xC += vitesse/nbDePasParSec;
  },
  32 : function(){//SPACEBAR
   yC += vitesse/nbDePasParSec;
  },
  16 : function(){//shift
   yC -= vitesse/nbDePasParSec;
  }
 };
 var dictIntervalles = {};
 document.addEventListener("keydown", function(e) {
  console.log("keydown");
  for(var k in dict) {
   if (e.keyCode == k) {
    console.log("touche n°: "+k+" appuyée");
    function modif(){
     dict[k]();
     refresh();
    }
    modif();
    dictIntervalles[k] = setInterval(modif,1000/nbDePasParSec);// tant que la touche est appuyée on avance régulièrement
   }
  }
 });
 document.addEventListener("keyup", function(e) {
  for(var k in dictIntervalles) {
   if (e.keyCode == k) {
    console.log("touche n°: "+k+" relevée");
    clearInterval(dictIntervalles[k]);
    delete dictIntervalles[k];
   }
  }
 });
 console.log("touches d'écoute créées");
}
var xC=0, yC=0, zC=0;
var pX = document.getElementById("x");
var pY = document.getElementById("y");
var pZ = document.getElementById("z");
var vitesse = 1;// distance faite à chaque seconde
var nbDePasParSec = 6;// fluidité du mouvement
refresh();

2 réponses

Hibou-Propulseur Messages postés 3 Date d'inscription   Statut Membre Dernière intervention  
 
Ok j'ai trouvé une réponse... (https://javascript.info/keyboard-events)

Auto-repeat
If a key is being pressed for a long enough time, it starts to “auto-repeat”: the keydown triggers again and again, and then when it’s released we finally get keyup. So it’s kind of normal to have many keydown and a single keyup.

For events triggered by auto-repeat, the event object has event.repeat property set to true.

donc ça donne :
document.addEventListener("keydown", function(e) {
  console.log("keydown");
  for(var k in dict) {
   if (e.keyCode == k) {
    if (e.repeat != true){// petite modif ici !
     console.log("touche n°: "+k+" appuyée");
     function modif(){
      dict[k]();
      refresh();
     }
     modif();
     dictIntervalles[k] = setInterval(modif,1000/nbDePasParSec);
    }
   }
  }
 });


EDIT: Comment on fait pour clore ce sujet ?
0
kaneagle Messages postés 86481 Date d'inscription   Statut Modérateur Dernière intervention   14 528
 
Bonjour,

Comment on fait pour clore ce sujet ? 


Regarde ceci -->> Marquer un fil de discussion comme étant résolu

0