Utilisation de Pygame – bases

Pygame est une bibliothèque permettant la création de jeu en Python.

Elle permet de créer une fenêtre graphique dans laquelle il est possible de dessiner, elle prend également en charge les événements utilisateur (clavier, souris, …), le son, les images et autres outils indispensables à la création d’un jeu interactif en mode graphique.

Programme de base en Pygame :

Voici une version commentée d’un programme créant une fenêtre et permettant de la fermer proprement avec Pygame :

# on importe la librairie pygame
import pygame
# pour plus de clarté, on importe les constantes dans notre espace de nom
from pygame.locals import *

# on initialise pygame (système de son, polices, graphismes...)
pygame.init()

# on crée une fenêtre
window = pygame.display.set_mode( (800,600) )

# une variable pour indiquer si le programme est en train de tourner
running = True
# la boucle principalequi tourne en permanence pour modifier l'affichage
# et gérer les évènements
while running:
    # ici on modifie l'affichage si nécessaire, par exemple en remplissant la
    # fenêtre d'une couleur unie (en rvb) :
    window.fill( (255,0,0) )

    # ATTENTION : par défaut pygame est en mode double buffer, ce qui veut dire
    # que toute vos manipulation de window sont uniquement faite en mémoire,
    # pour envoyer votre window modifiée sur l'écran il faut utiliser flip()
    pygame.display.flip()

    # à chaque tour de boucle, on inspecte les événements (clavier, souris, ...)
    for event in pygame.event.get(): # get() renvoie et vide la liste des événements

        # event.type indique le type d'événement :
        # - KEYDOWN : appui sur une touche
        # - KEYUP : relache d'une touche
        # ...
        # QUIT : un événement spécial émis par l'OS lorsque l'on clique sur la croix
        # ou l'on appuie sur Alt+F4 (sous Windows)
        if event.type == QUIT or(event.type == KEYUP and event.key == K_ESCAPE):
            # on met fin à la boucle
            running = False

# on arrête proprement les systèmes pygame (uniquement nécessaire si le programme
# n'est pas tout à fait fini)
pygame.quit()

Et voici la version sans commentaires que vous pouvez recopier et utiliser (essayez de changer la couleur du fond de la fenêtre) :

import pygame
from pygame.locals import *

pygame.init()
window = pygame.display.set_mode( (800,600) )

running = True
while running:
    window.fill( (255,0,0) )

    pygame.display.flip()

    for event in pygame.event.get(): 
        if event.type == QUIT or(event.type == KEYUP and event.key == K_ESCAPE):
            # on met fin à la boucle
            running = False

pygame.quit()

Dessiner en Pygame

Au lieu de simplement mettre un fond d’une couleur unie avec window.fill(...), vous pouvez aussi dessiner des formes géométriques sur la fenêtre avec les fonctions de pygame.draw. Ou ajoutez des images PNG ou JPEG.

import pygame
from pygame.locals import *

pygame.init()
clock = pygame.time.Clock()

# window est du type Surface(), on peut donc utiliser blit(), fill() sur window
# et donc "dessiner sur l'écran" (attention cela se fait en réalité en mémoire, il
# faut appeler flip() pour que cela devienne visible)
window = pygame.display.set_mode( (800,600) )

# vous pouvez chargez n'importe quel fichier image, les png sont recommandés comme
# format (car ils gèrent bien la transparence)
image = pygame.image.load("p1_stand.png")

running = True
while running:
    clock.tick(60)

    # ATTENTION à l'ordre dans lequel vous manipulez window, commencez par le fond
    # puis dessinez par dessus sinon vous recouvrirez vos images par votre fond
    window.fill( (255,0,0) )

    # blit() permet de recopier une Surface dans une autre Surface à n'importe quelles
    # coordonnées (attention l'axe des ordonnées est orienté vers le bas et l'origine
    # est dans le coin en haut à gauche)
    window.blit( image, (10,10) )


    # il est possible de dessiner des formes géométriques simples avec pygame.draw :
    # comme un cercle sur window de couleur bleue, de centre (150,70)
    # et de rayon 50 (le 0 est l'épaisseur du bord, 0 déclenche le remplissement)
    pygame.draw.circle(window, (0,0,255), (150,70), 50, 0)

    pygame.display.flip()

    for event in pygame.event.get():

        if event.type == QUIT or(event.type == KEYUP and event.key == K_ESCAPE):
            running = False

pygame.quit()

Utilisez ces indications pour faire un dessin simple avec les formes géométriques disponibles.

Animation en Pygame

Dans un programme Pygame, la fenêtre est redessinée un grand nombre de fois par seconde, si le dessin change d’une fois sur l’autre, cela donnera l’illusion du mouvement comme au cinéma. On peut assurer que l’image sera redessinée au plus un certain nombre de fois par seconde (60 par exemple) pour diminuer la charge de travail pour l’ordinateur. On peut également changer l’image par rapport au temps écoulé depuis le début du programme pour obtenir une animation :

import pygame
from pygame.locals import *

pygame.init()

# l'horloge doit être initialisée au début du jeu
clock = pygame.time.Clock()

window = pygame.display.set_mode( (800,600) )

# vous pouvez utilisez des variables pour savoir si certaines action ont déjà été
# exécutées (ou compter combien de fois elles l'ont été)
deja_fait = False

# il est possible de stocker un temps dans une variable
since = pygame.time.get_ticks()

running = True
while running:
    # tick(60) assure que la boucle sera exécutée au plus 60 fois par seconde, si
    # un tour de boucle a été trop rapide (moins d'1/60ème de seconde), elle bloque
    # jusqu'à ce que le temps soit écoulée
    clock.tick(60)
    
    temps = pygame.time.get_ticks()

    # on peut changer la couleur du fond selon le temps écoulé
    if  temps < 2000:
        window.fill(0,0,0)
    else:
        window.fill(255,255,255)

    # on peut même utiliser le temps dans nos fonctions
    pygame.draw.circle(window, (0,0,255), (150+int(temps/10),70+int(temps/20)), 50, 0)

    pygame.display.flip()

    for event in pygame.event.get():
        if event.type == QUIT or(event.type == KEYUP and event.key == K_ESCAPE):
            running = False


pygame.quit()

Vous pouvez consulter une aide plus avancée pour Pygame pour aller plus loin.