Gestion des événements Contrôle temporel * Possibilité de déclencher des actions dans le futur * setTimeout(action,n); * Déclenchement de l'action dans n millisecondes * id = setInterval(action,n); * Répétition de l'action toutes les n millisecondes * Retourne un identifiant pour stopper la répétition: clearInterval(id); * Syntaxe d'une action: () => { code; } * Exemple: déplacement d'un sprite * setInterval(() => { sprite.setX(sprite.getX()+1); }, 1000/25); * Déplacement vers la gauche d'un pixel tous les 25èmes de seconde Evénements * Quelque chose se produit ==> "événement" * Evénement toujours rattaché à un objet: le "sujet" * Celui qui subit l'événement * Possibilité d'associer une action à un événement * Un événement se produit ==> exécution de l'action * L'action reçoit alors un objet avec des infos sur l'événement * Syntaxe d'une action liée à un événement * (e : TypeEvenement) => { code; } * e contient des informations sur l'événement * Association d'une action à un événement * sujet.addEventListener("evenement",action); Evénement sur un sprite * Exemple: capter le clic de la souris sur un sprite * Clic sur un carré ==> changement de position * Code placé au démarrage de la scène * Evénement: mousedown * Type de l'objet reçu par l'action: MouseEvent * Action = "fonction" qui reçoit des informations sur l'événement let actionBouger : any = (e : MouseEvent) => { sprite.setX(Math.random()*300); sprite.setY(Math.random()*300); }; * Association de l'événement à l'action * carre.addEventListener("mousedown",actionBouger); Evénements souris * Principaux événements (type "MouseEvent") * click: clic de souris sur le sujet * mousedown: bouton souris enfoncé sur le sujet * mouseup: bouton souris relâché sur le sujet * mousemove: déplacement souris sur le sujet * mouseover: souris arrive sur le sujet * mouseout: souris sort du sujet * Connaître les coordonnées de la souris * Coordonnées stockées dans l'objet e reçu par l'action * Coordonnées dans le repère de la page * let sx : number = e.clientX; let sy : number = e.clientY; * Coordonnées dans le repère de la scène * let sx : number = e.clientX - scene.getX(); * Coordonnées dans le repère du sujet * let sx : number = e.clientX - scene.getX() - sujet.getX(); Evénement au niveau de la page * Un sprite ne peut capter que les événements qui le concerne * s.addEventListener("mousemove",action); * Le mouvement de la souris est détecté uniquement s'il survient sur s * Un événement peut être capté au niveau de la page * "window" est un objet qui représente la fenêtre du navigateur * window.addEventListener("mousemove",action); * Le mouvement de la souris est détecté n'importe où dans la page * Exemple: savoir où se trouve le curseur de la souris let action : any = (e : MouseEvent) => { let sourisX : number = e.clientX; let sourisY : number = e.clientY; console.log(sourisX + ";" + sourisY); }; window.addEventListener("mousemove",action); Evénement dans une classe (1/2) * Exemple: classe "Carre" héritant de "Sprite" class Carre extends Sprite { private actionBouger_ : any; public constructor(balise : HTMLElement) { ... } public bouger() { ... } } * Conseils * Stocker l'action dans un attribut: actionBouger_ * Permet un accès n'importe où dans la classe * Ecrire une méthode qui contient le code de l'action: bouger * Plus de lisibilité * Approche objet: action = méthode public bouger() { this.setX(Math.random()*300); this.setY(Math.random()*300); } Evénement dans une classe (2/2) * Association événement-action établie dans le constructeur public constructor(balise : HTMLElement) { super(balise); this.actionBouger_ = (e : MouseEvent) => { this.bouger(); }; this.addEventListener("mousedown",this.actionBouger_); } * Dissocier une action d'un événement * A tout moment, il est possible d'arrêter le suivi d'un événement * Méthode: removeEventListener * Mêmes paramètres que "addEventListener" * D'où l'importance de stocker l'action dans un attribut * this.removeEventListener("mousemove",this.actionBouger_); Exemple: "drag and drop" (1/2) * Détecter l'appui d'un bouton sur le sprite * Passage en mode déplacement * this.addEventListener("mousedown",this.actionColler_); * Détecter le relâchement d'un bouton sur le sprite * Arrêt du mode déplacement * this.addEventListener("mouseup",this.actionDecoller_); * Détecter le déplacement de la souris dans l'application * Mode déplacement ==> déplacement du sprite * window.addEventListener("mousemove",this.actionBouger_); Exemple: "drag and drop" (2/2) * Actions this.actionBouger_ = (e : MouseEvent) => { this.bouger(e); }; this.actionColler_ = (e : MouseEvent) => { this.bouge_ = true; }; this.actionDecoller_ = (e : MouseEvent) => { this.bouge_ = false; }; * Déplacement public bouger(e : MouseEvent) { if (this.bouge_) { this.setX(e.clientX - this.getParent().getX() - this.getLargeur()/2); this.setY(e.clientY - this.getParent().getY() - this.getHauteur()/2); } } Evénements clavier * Principaux événements (type "KeyboardEvent") * keydown: touche enfoncée * keyup: touche relâchée * Détection au niveau de l'application let action : any = (e : KeyboardEvent) => { console.log("touche = " + e.key); }; window.addEventListener("keydown",action); * key = texte correspondant à la touche concernée * Soit un caractère visible: "a", "Z"... * Soit le nom de la touche: "ArrowLeft", "Escape"... * Eviter la propagation de l'événement * Si l'événement est traité ici, éviter qu'il remonte au navigateur * e.preventDefault(); |