• {0} Easy|{1} Medium|{2} Hard

Free online content available in this course.

You can get support and mentoring from a private teacher via videoconference on this course.

Got it!

Last updated on 7/20/15

Gestion des événements [2]

Log in or subscribe for free to enjoy all this course has to offer!

Souvenez-vous de la première partie : nous avons appris à gérer le clavier et la souris avec Pygame, grâce aux évènements :) Il s'agissait des contrôles "classiques", que vous utiliserez souvent pour contrôler vos programmes.
Je vous propose de faire pareil pour permettre le contrôle de votre jeu grâce au Joystick !

Après ça, on découvrira un nouveau type d'évènements, les évènements de la fenêtre, et nous aurons fait le tour de la question... Autant dire que vous serez au top des évènements ! :p

C'est parti !

Initialiser le Joystick

Image utilisateur

Vous avez dégainé votre Joystick ou votre manette ? Ca y est, le monstre est branché ?
Le geek est devenu gamer ? Nous pouvons nous lancer dans la gestion du joystick par Pygame ! :diable:

Il faut savoir que contrairement au clavier et à la souris, disponibles et reconnus directement par Pygame, le Joystick nécessite une initialisation. Cela est sans doute du à la multitude et à la complexité des Joystick disponibles, contrairement aux modèles clavier et souris, souvent semblables... :)

Lançons nous donc dans l'initialisation, avant de passer à la gestion des évènements !

Compter le nombre de Joysticks branchés

Cela peut paraître bête, mais avant d'initialiser un Joystick et de permettre le contrôle de celui-ci, il faut vérifier si au moins un Joystick est branché au PC... :)

Utilisez pour cela la fonction du module Joystick nommée get_count(), qui renvoie le nombre de Joysticks disponible...

Nous pouvons tester avant de brancher :

nb_joysticks = pygame.joystick.get_count()
print("Il y a", nb_joysticks, "joystick(s) branché(s)")

Vous pouvez voir dans la console :

Il y a 0 joystick(s) branché(s)

Branchez maintenant votre Joystick au port USB, vous voyez maintenant :

Il y a 1 joystick(s) branché(s)
Initialiser un Joystick

Jusqu'ici, pas de problème ! :)
Nous voulons maintenant initialiser ce Joystick. Pygame propose de créer un objet Joystick, nous devons seulement passer en paramètre lors de sa création, l'id du Joystick voulu. :)

Comment je connais l'id de mon Joystick, moi ? C'est écrit sur la boîte ?

N'allez pas chercher si loin, les id sont attribués à partir de 0 à tous les Joysticks branchés, si on a un seul Joystick, son id sera donc 0, si on en a un deuxième, son id sera 1, etc... :p

Je vous propose donc de "créer" votre Joystick :

#On compte les joysticks
nb_joysticks = pygame.joystick.get_count()
#Et on en crée un s'il y a en au moins un
if nb_joysticks > 0:
	mon_joystick = pygame.joystick.Joystick(0)

Ca y est, notre Joystick est créé, il faut maintenant l'initialiser :)
Son initialisation permettra d'ajouter ses évènements à la liste des évènements Pygame, que nous testions déjà avec les évènements clavier et souris :)

Souvenez-vous :

for event in pygame.event.get():
	if event.type == QUIT:
		continuer = 0
        ...

Pour l'initialiser, rien de plus simple :

#On compte les joysticks
nb_joysticks = pygame.joystick.get_count()
#Et on en crée un s'il y a en au moins un
if nb_joysticks > 0:
	mon_joystick = pygame.joystick.Joystick(0)

	mon_joystick.init() #Initialisation

C'est tout, votre joystick est initialisé ! :)
Vous pouvez continuer !

Evénements au Joystick

Connaître les boutons disponibles

Votre Joystick est initialisé, mais comme je l'ai dit plus haut, à cause de la multitude de Joysticks disponibles dans le commerce, et de leurs configurations différentes, il est préférable de connaître les boutons disponibles sur le Joystick initialisé... :)

Voyons un peu les différents types de boutons que peut posséder un Joystick :

  • Les axes (d'une croix ou d'un pad)

  • Les boutons

  • Les trackballs

  • Les chapeaux ou hats

Je prendrai pour exemple, pour continuer dans la lignée de Donkey Kong, un Joystick bien connu...

Image utilisateur

Un Joystick de ce type possède 2 axes (haut-bas et gauche-droite), et 8 boutons. Pas de chapeau, pas de trackball, ah, le bon vieux temps...

Nous pouvons vérifier ceci en branchant le Joystick sur PC ( :-° ) et en essayant, après l'avoir correctement initialisé :

print("Axes :", mon_joystick.get_numaxes())
print("Boutons :", mon_joystick.get_numbuttons())
print("Trackballs :", mon_joystick.get_numballs())
print("Hats :", mon_joystick.get_numhats())

Nous obtiendrons logiquement :

Axes : 2
Boutons : 8
Trackballs : 0
Hats : 0

Et voilà, vous savez comment compter vos boutons, et ainsi permettre un contrôle selon la configuration du Joystick !

Capturer les évènements

Nous allons maintenant nous attaquer à la partie la plus intéressante de ce chapitre, à savoir la gestion des évènements du Joystick !

Nous avons vu précédemment que, après l'initialisation du Joystick, tous les évènements étaient envoyés à la liste d'évènements, au même titre qu'un évènement clavier. :)
Vous devriez donc vous en sortir assez rapidement, j'ai seulement à vous donner les types des évènements, et les attributs renvoyés par ces types...

Evènements des boutons
Image utilisateur

Nous avons tout d'abord un évènement créé quand on appuie sur un bouton, ou qu'on le relâche, cet évènement est JOYBUTTONDOWN ou JOYBUTTONUP.

L'évènement créé possède deux attributs :

  • joy : l'id du Joystick source

  • button : le numéro du bouton

Les boutons de certains Joysticks sont numérotés, sinon, dites-vous que les premiers boutons sont les "classiques", proches du pouces, et que les autres suivent... ou faites simplement le test :

if event.type == JOYBUTTONDOWN:
	print(event.button)

Ce code vous affiche le numéro du bouton pressé.

Allez, je vous propose un petit test : codez-moi le programme qui initialise un Joystick, qui vérifie qu'il possède bien au moins 4 boutons, et qui assigne au premier bouton (numéro 0) l'action d'écrire dans la console "Boum !". Ca devrait aller vite ! Voilà la correction :

import pygame
from pygame.locals import *

pygame.init()
fenetre = pygame.display.set_mode((300,300))

#On compte les joysticks
nb_joysticks = pygame.joystick.get_count()
#Et on en crée un s'il y a en au moins un
if nb_joysticks > 0:
	mon_joystick = pygame.joystick.Joystick(0)

	mon_joystick.init()

	#On compte les boutons
	nb_boutons = mon_joystick.get_numbuttons()
	if nb_boutons >= 4:
	
		continuer = 1
		while continuer:
			for event in pygame.event.get():
				if event.type == QUIT:
					continuer = 0
					
				if event.type == JOYBUTTONDOWN and event.button == 0:
					print("Boum !")
	else:
		print("Votre Joystick ne possède pas au moins 4 boutons")
else:
	print("Vous n'avez pas branché de Joystick...")
Evènements des axes

Nous allons maintenant étudier les évènements créés lorsqu'on appuie sur une direction, sur une croix ou avec un pad.
L'évènement créé est de type JOYAXISMOTION et possède trois attributs :

  • joy : l'id du Joystick source

  • axis : le numéro de l'axe

  • value : la valeur de la direction

L'axe gauche-droite est le numéro 0, l'axe haut-bas est le numéro 1.
La valeur de la direction permet de savoir si l'on a pressé un côté ou l'autre de l'axe. (Avec un pad comme sur les manettes de PlayStation, value renvoie l'intensité du mouvement, entre 0 (aucun) et 1 (maximum)...

La valeur de la direction peut-être positive ou négative, c'est en étudiant son signe que l'on connait la direction pressée.
Voici le schéma pour une croix directionnelle :

Image utilisateur

Un évènement de mouvement d'axe renvoyant l'axe 0 et une valeur de 1 correspondra donc à une pression sur la flèche droite. :)

Par exemple :

if event.type == JOYAXISMOTION:
	if event.axis == 0 and event.value > 0:
		mouvement_droite()
	if event.axis == 0 and event.value < 0:
		mouvement_gauche()

Je vous dispense d'exercice pour les axes, mais si vous n'êtes pas sûr d'avoir compris, entraînez-vous ! :)
Nous en avons fini avec la gestion du Joystick, pas mal hein ? Je vous l'avez dit que ça serait cool :p
Si vous souhaitez savoir comment gérer les chapeaux et les trackballs, vous le savez : la documentation !

Evénements de la fenêtre

Il nous reste un dernier type d'évènements à connaître pour clore définitivement ce chapitre, il s'agit des évènements liés à la fenêtre.
Il s'agit en fait des évènements produits lors de l'interaction de l'utilisateur avec la fenêtre Pygame, comme le redimensionnement, la sortie ou l'entrée de la souris dans la fenêtre...

Focus et visibilité

Nous allons étudier tout de suite l'évènement ACTIVEEVENT, qui est créé quand :

  • le pointeur entre et sort de la fenêtre

  • on réduit la fenêtre

  • on change le focus de la fenêtre (active ou inactive)

Cet évènement possède deux attributs :

  • gain : indique si l'évènement est un gain ou une perte. (ex : si le pointeur entre dans la fenêtre, gain = 1, s'il sort, gain = 0)

  • state : indique le type d'évènement de fenêtre créé.

Pour cette partie, au lieu d'un long discours, il m'a paru préférable de créer un tableau, qui indique les états des deux attributs selon l'évènement :

- Evènement

- event.gain

- event.state

Sortie de la souris de la fenêtre

0

1

Entrée de la souris dans la fenêtre

1

1

Réduction de la fenêtre

0

6

Ré-ouverture de la fenêtre réduite

1

6

Inactivation de la fenêtre (ouverture d'un autre programme ou clic sur le bureau)

0

2

Ré-activation de la fenêtre (fermeture du programme actif ou clic sur la fenêtre)

1

6

Et voilà ! J'espère que vous comprenez, quand gain est égal à 1, il s'agit d'un évènement "en faveur" de la fenêtre, et state nous indique quel évènement ! :)

Il faut donc se servir des deux variables pour savoir ce qu'il se passe exactement...
Par exemple, comment savoir quand la souris entre dans la fenêtre ?

Il suffit d'utiliser ce code :) :

if event.type == ACTIVEEVENT:
	if event.gain == 1 and event.state == 1:
		print("Une souris est dans la fenêtre !! aaaah !!")

Ne me demandez pas à quoi correspondent les autres chiffres (3, 4 ou 5), je serai incapable de vous répondre ! :D
Je ne vois aucun autre évènement de fenêtre possible et utile à capturer... à part le redimensionnement, que nous allons voir maintenant !

Redimensionnement de la fenêtre

Pour permettre le redimensionnement de la fenêtre, rappelez-vous, nous utilisons le paramètre RESIZABLE lors de la création de la fenêtre :

fenetre = pygame.display.set_mode((640,480), RESIZABLE)

Lors du redimensionnement, un évènement VIDEORESIZE est créé, qui possède 3 attributs :

  • size : renvoie un tuple contenant la largeur et la hauteur de la nouvelle fenêtre : (largeur,hauteur)

  • w : renvoie la largeur de la nouvelle fenêtre.

  • h : renvoie la hauteur de la nouvelle fenêtre.

Facile non ? Vous pouvez maintenant connaître la taille de la fenêtre redimensionnée, et ainsi adapter votre programme !

Je vous propose un exercice, comme j'aime bien le faire... Codez-moi un programme qui ouvre une fenêtre de 300px de côté, redimensionnable, mais qui se ferme si on dépasse 500px de côté !
Voilà la correction :) :

import pygame
from pygame.locals import *

#Initialisation
pygame.init()
fenetre = pygame.display.set_mode((300,300), RESIZABLE)
continuer = 1

while continuer:
	for event in pygame.event.get():
                #Quitter
		if event.type == QUIT:
			continuer = 0
		
		if event.type == VIDEORESIZE:
			if event.w > 500 or event.h > 500:
					continuer = 0

Et voilà, vous savez gérer les redimensionnements de fenêtre !
C'était plutôt simple non ? Plus le tutoriel avance, plus vous devez aller vite avec les évènements :) Au bout d'un moment, on se rend compte que c'est assez semblable pour tous les types !

Fermeture, Clavier, Souris, Joystick, Fenêtre. Et bien voilà, je ne peux pas vous en apprendre plus à propos des évènements !
Certains points restent encore à approfondir, mais comme je vous le dis de plus en plus, si vous avez besoin de quelque chose de précis dont je n'ai pas parlé, consultez la documentation ! :D
Vous en êtes maintenant parfaitement capable, il suffit de parler un poil d'anglais... et disons qu'un traducteur peut vous aider si ce n'est pas le cas ! :-°

Dans le prochain chapitre nous nous intéresserons à l'objet Sprite, qui peut être utile et adapté à la gestion d'objets et de personnages dans les jeux Pygame :)

Comme vous pouvez le voir, cette partie n'est pas complète, je la compléterai au fur et à mesure de son écriture :)

Il manque un chapitre sur le temps, sur les Sprite et un TP de fin :)
Encore du boulot en perspective !
N'hésitez pas à laisser des commentaires si vous avez des conseils ou des questions :)

Comme vous pouvez le voir le tutoriel n'est pas encore terminé.
La première partie est complète, et la seconde en cours d'écriture :)
Il est possible que j'ajoute une troisième partie pour la gestion des CD, de la vidéo et quelques autres annexes pour ceux que ça intéressera !

Vous n'en avez donc pas tout à fait fini avec Pygame ! :p
N'hésitez pas à commenter ce tutoriel si vous trouvez des erreurs ou que vous le trouvez imprécis sur certains points. :)

Example of certificate of achievement
Example of certificate of achievement