Aller au contenu

TNSI : POO, Tutoriel Pygame⚓︎

Détecter les événements du Clavier⚓︎

Appui/Relâche Simple de Touche Sans Modificateur ( CTRL/ALT/SHIFT/..)⚓︎

import pygame
pygame.init()

# Générer la fenêtre du jeu
pygame.display.set_caption("Shoot'em Up")
screen = pygame.display.set_mode((1080,720))

running = True

while running:
    # boucle de détection des événements
    for event in pygame.event.get():
        # si l'événement est une fermeture de fenêtre
        if event.type == pygame.QUIT:
            running = False
            pygame.quit()
        # Détecte l'appui d'une touche
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                game.player.move_right()
                print("Touche Flèche Droite Appuyée")
            elif event.key == pygame.K_LEFT:
                game.player.move_left()
                print("Touche Flèche Gauche Appuyée")

Le principe général de détection de l'utilisation d'une touche de clavier se fait donc en trois temps:

  1. On parcoure la liste (au sens Python du terme) de tous les événements du jeu par l'instruction for event in pygame.event.get()
  2. On vérifie si un type d' événement 🇫🇷 / event type 🇬🇧 de touche est détecté, ou pas, et si oui lequel ? :

    • if event.type == pygame.KEYDOWN : Appui sur un touche
    • if event.type == pygame.KEYUP : Relâchement d'une touche
    • if event.type == pygame.QUIT : Fermeture de la fenêtre graphique (clic sur la croix en haut à droite de la fenêtre)
  3. Si un des événements précédents a bien été detecté, on peut ensuite déterminer de quelle touche il s'agit précisément. Une liste non exhaustive de touches :

    event.key
    (Source : cette page
    Caractère ASCII Description
    K_BACKSPACE \b retour arrière / backspace
    K_TAB \t tab
    K_CLEAR clear
    K_RETURN \r retour charriot / return
    K_PAUSE pause
    K_ESCAPE ^[ escape
    K_SPACE barre d'espace
    K_EXCLAIM ! point d'exclamation
    K_QUOTEDBL " guilllemets doubles
    K_HASH # hashtag / dièse
    K_DOLLAR $ dollar
    K_AMPERSAND & Esperluette / Et Commercial
    K_QUOTE ' guillemets simples
    K_LEFTPAREN ( parenthèse gauche
    K_RIGHTPAREN ) parenthèse droite
    K_ASTERISK * astérisque
    K_PLUS + plus
    K_COMMA , virgule
    K_MINUS - moins
    K_PERIOD . point
    K_SLASH / slash
    K_0 0 \(0\)
    K_1 1 \(1\)
    K_2 2 \(2\)
    K_3 3 \(3\)
    K_4 4 \(4\)
    K_5 5 \(5\)
    K_6 6 \(6\)
    K_7 7 \(7\)
    K_8 8 \(8\)
    K_9 9 \(9\)
    K_COLON : deux-points
    K_SEMICOLON ; point-virgule
    K_LESS < strictement inférieur
    K_EQUALS = égal
    K_GREATER > strictement supérieur
    K_QUESTION ? point d'interrogation
    K_AT @ arobase
    K_LEFTBRACKET [ crochet gauche
    K_BACKSLASH \ antislash
    K_RIGHTBRACKET ] crochet droit
    K_CARET ^ accent circonflexe / caret
    K_UNDERSCORE _ tiret du bas / tiret du 8 / underscore
    K_BACKQUOTE ` accent grave
    K_a a a
    K_b b b
    K_c c c
    K_d d d
    K_e e e
    K_f f f
    K_g g g
    K_h h h
    K_i i i
    K_j j j
    K_k k k
    K_l l l
    K_m m m
    K_n n n
    K_o o o
    K_p p p
    K_q q q
    K_r r r
    K_s s s
    K_t t t
    K_u u u
    K_v v v
    K_w w w
    K_x x x
    K_y y y
    K_z z z
    K_DELETE Suppr(ime)
    K_KP0 Pavé Numérique \(0\)
    K_KP1 Pavé Numérique \(1\)
    K_KP2 Pavé Numérique \(2\)
    K_KP3 Pavé Numérique \(3\)
    K_KP4 Pavé Numérique \(4\)
    K_KP5 Pavé Numérique \(5\)
    K_KP6 Pavé Numérique \(6\)
    K_KP7 Pavé Numérique \(7\)
    K_KP8 Pavé Numérique \(8\)
    K_KP9 Pavé Numérique \(9\)
    K_KP_PERIOD . Pavé Numérique Point
    K_KP_DIVIDE / Pavé Numérique Diviser
    K_KP_MULTIPLY * Pavé Numérique Multiplier
    K_KP_MINUS - Pavé Numérique Moins
    K_KP_PLUS + Pavé Numérique Plus
    K_KP_ENTER \r Pavé Numérique Entrer
    K_KP_EQUALS = Pavé Numérique Egal
    K_UP Flèche vers le Haut
    K_DOWN Flèche vers le Bas
    K_RIGHT Flèche vers la Droite
    K_LEFT Flèche vers la Gauche
    K_INSERT Insertion
    K_HOME Accueil / home
    K_END Fin / End
    K_PAGEUP page vers le Haut
    K_PAGEDOWN page vers le Bas
    K_F1 F1
    K_F2 F2
    K_F3 F3
    K_F4 F4
    K_F5 F5
    K_F6 F6
    K_F7 F7
    K_F8 F8
    K_F9 F9
    K_F10 F10
    K_F11 F11
    K_F12 F12
    K_F13 F13
    K_F14 F14
    K_F15 F15
    K_NUMLOCK numlock
    K_CAPSLOCK capslock
    K_SCROLLOCK scrollock
    K_RSHIFT Shift Droite
    K_LSHIFT Shift Gauche
    K_RCTRL Control Droite
    K_LCTRL Control Gauche
    K_RALT Alt Droite
    K_LALT Alt Gauche
    K_RMETA Meta Droite
    K_LMETA Meta Gauche
    K_LSUPER Windows Gauche
    K_RSUPER Windows Droite
    K_MODE changement de mode
    K_HELP Help
    K_PRINT Imprime Ecran / Impr Ecran
    K_SYSREQ sysrq
    K_BREAK break
    K_MENU menu
    K_POWER Bouton Alimentation
    K_EURO Euro
    K_AC_BACK Bouton Retour Android

Cette liste est issue de : cette page de la Documentation Officielle de Pygame.

Appui/Relâche Automatique de Touche Sans Modificateur ( CTRL/ALT/SHIFT/..)⚓︎

# Fichier main.py
import pygame
pygame.init() # Initialisation : Charge les éléments de pygame

WIDTH = 1080
HEIGHT = 720
# from player import Player
from game import Game

# Générer la fenêtre du jeu
pygame.display.set_caption("Shoot'Em Up")
# renvoie une Surface `screen`
screen = pygame.display.set_mode((WIDTH,HEIGHT))

# importer / charger l'arrière plan dans une variable python
background = pygame.image.load("assets/bg.jpg")

# Charge le Jeu
game = Game()

running = True

while running:
    # Appliquer le background au screen, à la position (largeur, hauteur)
    screen.blit(background, (0,-200))

    # Appliquer l'image du joueur au screen, à la position (largeur, hauteur) càd rect
    screen.blit(game.player.image, game.player.rect)

    if game.pressed.get(pygame.K_RIGHT): # vérifie si cette touche est pressée
        game.player.move_right()
    elif game.pressed.get(pygame.K_LEFT): # vérifie si cette touche est pressée
        game.player.move_left()

    # Mettre à jour l'écran
    pygame.display.flip()

    # boucle de détection des événements
    for event in pygame.event.get():
        # si l'événement est une fermeture de fenêtre
        if event.type == pygame.QUIT:
            running = False
            pygame.quit()
        # Détecte si une touche de clavier est pressée
        elif event.type == pygame.KEYDOWN:
            game.pressed[event.key] = True
        # Détecte si une touche de clavier est relâchée
        elif event.type == pygame.KEYUP:
            game.pressed[event.key] = False
# Fichier game.py
import pygame

from player import Player

# Classe du Joueur
class Game(pygame.sprite.Sprite):
    def __init__(self):
        # hérite du constructeur parent
        super().__init__()
        self.player = Player()
        self.pressed = {}
import pygame

# Classe du Joeur
class Player(pygame.sprite.Sprite):
    def __init__(self):
        # hérite du constructeur parent
        super().__init__()
        self.health = 100
        self.max_health = 100
        self.attack = 10
        self.velocity = 1

        self.image = pygame.image.load("assets/player.png")
        self.rect = self.image.get_rect()
        self.rect.x = 400
        self.rect.y = 500
    def move_right(self):
        self.rect.x += self.velocity
    def move_left(self):
        self.rect.x -= self.velocity
  • Le mode de programmation du paragraphe précédent est adapté lorsque l'on souhaite que l'appui ponctuel sur une touche déclenche un évenement graphique ponctuel. PAS de répétition automatique en cas de touche laissée longtemps appuyée.
  • Si, au contraire, on souhaite pouvoir répéter automatiquement un événement graphique, simplement en laissant appuyée une touche, alors cette programmation n'est plus adaptée : on peut (par exemple), pour régler cela :
    • commencer par créer un dictionnaire d'événements graphiques dans un attribut .pressed dans une classe Game : vide {} par défaut
    • ajouter une clé event.key avec pour valeur True dans le dictionnaire lors de l'appui d'une touche
    • fixer la valeur du dictionnaire correspondant à la clé event.key à False lors du relâchement de la touche
    • Enfin

Touche Avec Modificateur( CTRL/ALT/SHIFT/..)⚓︎

for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
        if event.mod == pygame.KMOD_NONE:
            print("Aucun modificateur n'a été pressé lors de cet événement")
        else:
            if event.mod & pygame.KMOD_LCTRL:
                print("LEFT CTRL a été pressé lors de cet événement")
            if event.mod & pygame.KMOD_RCTRL:
                print("RIGHT CTRL a été pressé lors de cet événement")
            if event.mod & pygame.KMOD_CTRL:
                print("LEFT CTRL, ou RIGHT CTRL, ou les deux, a été pressé lors de cet événement")

Si vous souhaitez détecter l'appui/relâchement simultané d'une touche ET d'un modificateur de touche (comme CTRL / SHIFT / ALT / ..)

event.mod Description
pygame.KMOD_NONE Aucune Touche Modificateur Appuyée
pygame.KMOD_LSHIFT Left Shift
pygame.KMOD_RSHIFT Right Shift
pygame.KMOD_SHIFT Left Shift ou Right Shift ou les deux
pygame.KMOD_LCTRL Left Control
pygame.KMOD_RCTRL Right Control
pygame.KMOD_CTRL Left Control ou Right Control ou les deux
pygame.KMOD_LALT Left Alt ( Win / ⌥ Mac )
pygame.KMOD_RALT Right Alt ( Win / ⌥ Mac )
pygame.KMOD_ALT Left Alt ou Right Alt ou les deux
pygame.KMOD_LMETA Left Meta ( Win ❖ / Mac ⌘ )
pygame.KMOD_RMETA Right Meta ( Win ❖ / Mac ⌘ )
pygame.KMOD_META Left Meta ou Right Meta ou les deux
pygame.KMOD_CAPS Caps Lock
pygame.KMOD_NUM Num Lock
pygame.KMOD_MODE AltGr