Utilitaires¶
Répétition simultanée de plusieurs touches clavier¶
De base, lorsque l’utilisateur appuie sur plusieurs touches clavier à la fois, pygame ne prend en compte que la première touche enfoncée. Dans cette section, nous développons un utilitaire nous permettant de gérer plusieurs touches enfoncées simultanément.
Pygame fournit la méthode pygame.key.get_pressed()
qui renvoie l’état
de toutes les touches du clavier sous forme d’une liste de booléens. L’indice
d’une touche dans cette liste est la « constante de touche » correspondante
(définie par pygame, par exemple pygame.K_e
), et la valeur correspondante est 1
si la touche est enfoncée.
De là, il est assez simple « d’injecter », pour chaque touche enfoncée, un nouvel évènement pygame.KEYPRESSED
dans la file d’évènements que votre code lit (pygame.event.get()
) pour traiter
les entrées de utilisateur.
Le code ci-dessous permet de créer une nouvelleGestionClavier
, d’enregister
un délai initial et une période de répétition pour les touches qui vous intéressent
(repeteTouche
). La méthode scan
doit être appelée AVANT de lire la file d’évènements de pygame.
Notez bien que l’utilisation de la méthode pygame.key.set_repeat
dans votre programme
peut interférer avec le bon fonctionnement de notre utilitaire, et cette méthode ne devrait donc
pas être utilisée avec l’utilitaire.
import pygame
#définition d'un nouvel évènement pour représenter une touche qui reste enfoncée
pygame.KEYPRESSED = pygame.USEREVENT
BLEU_CIEL = (135, 206, 250)
FENETRE_LARGEUR = 800
FENETRE_HAUTEUR = 600
FLAPPY_LARGEUR = 60
FLAPPY_HAUTEUR = 51
pygame.init()
# Gestionnaire de répétition automatique de plusieurs touches
# !!! NE PAS UTILISER pygame.key.set_repeat() dans votre programme !!!
# ===== début GestionClavier =====
def _nouveauEtatTouche():
return {
'actif': False,
'delai': 0,
'periode': 0,
'suivant': 0
}
def nouvelleGestionClavier():
return {}
# gc: gestionnaire de clavier (créé par nouvelleGestion Clavier())
# touche: numéro de la touche (ex: pygame.K_e)
# delai: attente (en ms) avant la première répétition
# periode: temps (en ms) entre deux répétitions
def repeteTouche(gc, touche, delai, periode):
pygame.key.set_repeat()
if touche in gc:
entree = gc[touche]
else:
entree = _nouveauEtatTouche()
entree['delai'] = delai
entree['periode'] = periode
gc[touche] = entree
def scan(gc):
maintenant = pygame.time.get_ticks()
keys = pygame.key.get_pressed()
for touche in gc:
if keys[touche] == 1:
if gc[touche]['actif']:
if maintenant >= gc[touche]['suivant']:
gc[touche]['suivant'] = gc[touche]['periode'] + maintenant
pygame.event.post(pygame.event.Event(pygame.KEYPRESSED, {'key':touche}))
else:
gc[touche]['actif'] = True
gc[touche]['suivant'] = gc[touche]['delai'] + maintenant
else:
gc[touche]['actif'] = False
gc[touche]['suivant'] = 0
# ===== fin GestionClavier =====
fenetre_taille = (FENETRE_LARGEUR, FENETRE_HAUTEUR)
fenetre = pygame.display.set_mode(fenetre_taille)
pygame.display.set_caption('Test keyboard')
fini = False
temps = pygame.time.Clock()
fenetre.fill(BLEU_CIEL)
pygame.display.flip()
# répétition de plusieurs touches
gc = nouvelleGestionClavier()
repeteTouche(gc, pygame.K_e, 100, 25)
repeteTouche(gc, pygame.K_j, 100, 25)
while not fini:
now = pygame.time.get_ticks()
# --- Traiter entrées joueur
scan(gc) # DOIT être appelée avant pygame.event.get()
events = pygame.event.get()
#print("Events: " + str(len(events)))
for evenement in events:
#print(str(evenement))
if evenement.type == pygame.QUIT:
fini = True
if evenement.type == pygame.KEYDOWN:
print("KEYDOWN: " + str(evenement.key) + " " + str(now))
elif evenement.type == pygame.KEYPRESSED:
print("KEYPRESSED:" + str(evenement.key) + " " + str(now))
#print("keys: " + str(tk))
temps.tick(50)
pygame.display.quit()
pygame.quit()
exit()