Initiation à Pygame⚓︎
1. Préparation de la scène⚓︎
import pygame
from pygame.locals import *
pygame.init() # (4)
fenetre = pygame.display.set_mode((640, 480)) # (1)
fenetre.fill((10, 186, 181)) # (2)
running = True
while running:
fenetre.fill((10, 186, 181)) # (2)
pygame.display.flip() #(3)
pygame.quit()
- On crée une fenêtre de taille
(640, 480)
. - On remplit la fenêtre avec la couleur
(10, 186, 181)
. - Permet de rafraîchir la totalité de la fenêtre. Pour l'instant inutile car rien ne bouge...
- Initialisation du module
pygame
.
Ce code devrait vous donner ceci :
Remarques
- La ligne
from pygame.locals import *
permettra d'utiliser des variables locales déjà définies parpygame
, commeMOUSEBUTTONDOWN
, par exemple. - Durant tout le code, notre scène de travail sera l'objet
fenetre
, dans lequel nous viendrons coller de nouveaux éléments. - Pour l'instant, notre code nous enferme dans une boucle infinie : la fenêtre ne se ferme pas, il faut arrêter Python depuis Thonny. Nous y remedierons bientôt.
Les éléments structurants d'un code pygame
pygame.init()
effectue une initialisation globale de tous les modulespygame
importés. À mettre au début du code.while running:
comme très souvent dans les jeux, la structure essentielle est une boucle infinie dont on ne sortira que par la bascule d'un booléen. Ici on restera bloqué dans la boucle jusqu'au moment où la variablerunning
passera àFalse
.pygame.display.flip()
effectue un rafraîchissement total de tous les éléments graphiques de la fenêtre. À mettre à l'intérieur de la boucle infinie, généralement à la fin de celle-ci.
2. Apparition d'un personnage⚓︎
2.1. Téléchargement de l'image⚓︎
Nous allons travailler avec le sprite ci-dessous, nommé perso.png
. Il est issu de https://openclassrooms.com/fr/courses/1399541-interface-graphique-pygame-pour-python/1399813-premieres-fenetres
Téléchargez-le pour le mettre dans le même dossier que votre code pygame
.
Vous pouvez trouver sur internet un grand nombre de sprites libres de droits, au format png
(donc gérant la transparence), dans de multiples positions (ce qui permet de simuler des mouvements fluides). Ici nous travaillerons avec un sprite unique.
2.2. Importation de l'image dans la fenêtre⚓︎
perso = pygame.image.load('perso.png').convert_alpha()
convert_alpha()
est appelée pour que soit correctement traité le canal de transparence (canal alpha) de notre image.
2.3. Affichage de l'image⚓︎
À ce stade, perso
est un objet pygame
de type Surface
.
Afin de facilement pouvoir le déplacer, nous allons stocker la position de cet objet dans une variable position_perso
, grâce à l'instruction perso.get_rect()
.
Notre image est devenue «un rectangle» que nous allons positionner où nous voulons.
Par exemple, pour positionner le coin supérieur gauche du personnage aux coordonnées (100, 200)
, nous écrirons :
position_perso = perso.get_rect()
position_perso.topleft = (100, 200)
Il y a d'autres instructions que
topleft
: vous pouvez les retrouver ici.
Pour afficher cette image, nous allons venir le superposer aux éléments graphiques déjà dessinés (en l'occurence : rien) avec l'instruction blit()
:
fenetre.blit(perso, position_perso)
▸ récapitulatif du code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Aperçu
3. Gestion des évènements⚓︎
Lorsqu'un programme pygame
est lancé, la variable interne pygame.event.get()
reçoit en continu les évènements des périphériques gérés par le système d'exploitation.
Nous allons nous intéresser aux évènements de type KEYDOWN
(touche de clavier appuyée) ou de type MOUSEBUTTONDOWN
(boutons de souris appuyé).
Pour commencer, la gestion des évènements nous permettra de pouvoir enfin fermer proprement la fenêtre Pygame, grâce au code suivant :
1 2 3 |
|
Exercice 1
Intégrer le code ci-dessus au code précédent afin de pouvoir fermer proprement la fenêtre.
Correction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
3.1. Évènements clavier⚓︎
3.1.1. Exemple de code⚓︎
La structure de code pour détecter l'appui sur une touche de clavier est, dans le cas de la détection de la touche «Flèche droite» :
1 2 3 4 |
|
K_RIGHT
par pygame
.
il ne doit y avoir qu'une seule boucle de capture d'évènements, donc la routine de fermeture de la fenêtre doit être dans la même boucle :
1 2 3 4 5 6 7 |
|
Le nom de toutes les touches peut être retrouvé à l'adresse https://www.pygame.org/docs/ref/key.html.
Remarque : c'est grâce à la ligne initiale
from pygame.locals import *
K_RIGHT
(et toutes les autres) est reconnue.
3.1.2. Problème de la rémanence⚓︎
Quand une touche de clavier est appuyée, elle le reste un certain temps. Parfois volontairement (sur un intervalle long) quand l'utilisateur décide de la laisser appuyée, mais aussi involontairement (sur un intervalle très court), lors d'un appui «classique».
Il existe donc toujours un intervalle de temps pendant lequel la touche reste appuyée. Que doit faire notre programme pendant ce temps ? Deux options sont possibles :
- option 1 : considérer que la touche appuyée correspond à un seul et unique évènement, quelle que soit la durée de l'appui sur la touche.
- option 2 : considérer qu'au bout d'un certain délai, la touche encore appuyée doit déclencher un nouvel évènement.
Par défaut,pygame
est réglé sur l'option 1. Néanmoins, il est classique pour les jeux vidéos de vouloir que «laisser la touche appuyée» continue à faire avancer le personnage. Nous allons donc faire en sorte que toutes les 50 millisecondes, un nouvel appui soit détecté si la touche est restée enfoncée. Cela se fera par l'expression :
pygame.key.set_repeat(50)
3.2 Évènements souris⚓︎
3.2.1. Exemple de code⚓︎
La structure de code pour détecter l'appui sur un bouton de la souris est :
for event in pygame.event.get():
if event.type == MOUSEBUTTONDOWN and event.button == 1 :
print('clic gauche détecté')
if event.type == MOUSEBUTTONDOWN and event.button == 3 :
print('clic droit détecté')
Le clic-gauche est associé à la valeur 1, le clic-droit à la valeur 3 (le clic-molette éventuel à la valeur 2).
Exercice 2
Reprendre le code initial et y intégrer la capture d'évènements souris afin que s'affiche en console le bouton de souris appuyé.
Correction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
3.2.2. Récupération des coordonnées de la souris⚓︎
Le tuple (abscisse, ordonnée)
des coordonnées de la souris sera récupéré avec l'instruction pygame.mouse.get_pos()
.
Cette fonction n'a pas besoin d'être dans notre boucle d'écoute des évènements : elle peut se situer n'importe où dans le code.
Exercice 3
Faire afficher en console les coordonnées de la souris.
Correction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
3.3 Activation d'un framerate⚓︎
Pour l'instant, notre boucle infinie tourne «à fond» et le rafraîchissement de l'affichage se fait aussi rapidement que le peut le processeur. Afin de garder le contrôle sur cet fréquence de rafraîchissement (le nombre de frames par seconde, le fameux FPS) nous allons utiliser une horloge.
clock = pygame.time.Clock()
crée une horloge dans le corps du programme.
Ensuite, dans la boucle, nous rajouterons
clock.tick(30)
pour régler (par exemple) le FPS à 30.
4. Déplacement du personnage⚓︎
Le déplacement d'un personnage se fera toujours par modification de ses coordonnées (et visuellement, par effacement de la dernière position). Ce déplacement pourra être :
- absolu : on donne de nouvelles coordonnées au personnage.
- relatif : on indique de combien le personnage doit se décaler par rapport à sa position initiale.
4.1. Déplacement absolu⚓︎
Rappel : pour afficher le personnage à la position (300,200)
, on écrit simplement:
position_perso.topleft = (300,200)
Au prochain fenetre.blit(perso, position_perso)
, le personnage sera positionné à cette nouvelle position.
Exercice 4
Réaliser un déplacement aléatoire, comme l'animation ci-dessous.
Vous pourrez utiliser les instructions :
pygame.time.delay(1000)
afin de ne bouger le personnage que toutes les 1000 millisecondes.randint(a,b)
du packagerandom
, qui renvoie un entier pseudo-aléatoire entrea
etb
.
Correction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
4.2. Déplacement relatif⚓︎
Pour déplacer le personnage de 15 pixels vers la droite et de 10 pixels vers le haut par rapport à sa position précédente, on écrira :
position_perso = position_perso.move(15,-10)
position_perso
est l'objet de type rect
contenant les coordonnées.
Exercice 5
Réaliser un contrôle au clavier du personnage, comme dans l'animation ci-dessous.
Correction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
Exercice 6
Rajouter des instructions afin que le personnage ne puisse pas sortir de la fenêtre de jeu.
On utilisera les variables suivantes :
position_perso.top
: ordonnée du haut du personnageposition_perso.bottom
: ordonnée du bas du personnageposition_perso.left
: abscisse de la gauche du personnageposition_perso.right
: abscisse de la droite du personnage
Correction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
|
Exercice 7
Reprendre l'exercice précédent mais faire en sorte que le personnage réapparaisse à l'opposé de là où il est sorti.
Correction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
|
5. Contrôle avec la micro:bit⚓︎
Pour pouvoir contrôler notre personnage avec (par exemple) les boutons de la carte micro:bit, il va falloir :
- mettre dans la carte un programme minimal qui va se contenter d'envoyer des données.
- mettre dans notre programme Pygame une instruction capable de recevoir les données envoyées par la carte.
5.1 Programme à téléverser dans la micro:bit⚓︎
1 2 3 4 5 6 7 8 9 10 |
|
Ce programme va envoyer, 20 fois par seconde, la valeur de l'inclinaison en X et la valeur de l'inclinaison en Y.
5.2 Récupération des données dans Pygame⚓︎
Il faut connaître le port utilisé par le système d'exploitation pour communiquer avec la micro:bit. Sous Linux, ce port est de la forme ttyACM0
, sous Windows il sera de la forme COM2
.
connaitre le port sous Windows
Ouvrir un terminal via cmd
et taper la commande mode
.
Une fois le programme d'envoi téléversé dans la micro:bit et le port connu, testez le programme suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
En inclinant la carte, vous devriez voir bouger les valeurs dans la console de Thonny. Observer quelles sont les valeurs minimales et maximales.
Exercice 8
À l'aide de l'exemple précédent, modifiez le code de l'exercice 5 afin de pouvoir bouger le personnage à l'aide de la micro:bit.
Correction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
|
Bibliographie
- Documentation officielle de Pygame, https://www.pygame.org/docs/
- Cours d'OpenClassrooms, https://openclassrooms.com/fr/courses/1399541-interface-graphique-pygame-pour-python/1399813-premieres-fenetres.