Aller au contenu

Pygame

Avant toute chose, il nous faut installer Pygame et comprendre globalement comment la bibliothèque marche.

Installation

Il existe plusieurs méthodes pour installer pygame. Dans tous les cas il faut que votre ordinateur soit connecté à Internet au moment de l'installation.

Par thonny

TODO prof editer les screens pour les rendre plus explicites

Pour vérifier si Pygame est installée sur votre ordinateur, ouvrez Thonny.

Par la barre de menu en haut, sélectionnez Outils > Gérer les plugins.

Vous devriez voir une fenêtre ressemblant à ça :

Gestionnaire package

Dans la barre de recherche, écrivez pygame, comme ci-dessous, puis appuyez sur Rechercher sur PyPi.

Recherche pygame

Vous devriez après quelques instants voir une liste apparaître dans le cadre en bas à droite.

Recherché pygame

Selectionnez l'item qui a pour nom pygame en cliquant sur son nom.

Vous devriez avoir un écran similaire à celui ci-dessous :

Pygame fiche

Cliquez sur Installer.

Laissez faire, vous devriez ensuite pouvoir chercher pygame à nouveau, vous verrez alors que Pygame est installée :

pygame installée

Pour vérifier que pygame est installée, copiez-collez cette ligne dans un nouveau fichier Python avec Thonny, et lancez le :

import pygame

Si aucune erreur se produit, pygame a été installée avec succès, sinon, demandez de l'aide au professeur.

Par un script

Si l'installation par Thonny echoue, ou que vous utilisez un autre outils de développement et que vous ne savez pas comment installer pygame, vous pouvez utiliser la méthode décrite dans cette section.

Créez un fichier Python, copiez-collez y le script suivant, et executez-le avec votre outils de développement (par exemple, Thonny).

Attention

Il est peu recommandé d'exécuter des scripts qui ne proviennent pas d'une source fiable sans les comprendre, n'en faite pas une habitude !

import subprocess
import sys

def install(package):
    subprocess.check_call([sys.executable, "-m", "pip", "install", package])

install("pygame")

Vous devriez obtenir une sortie de cette forme :

Defaulting to user installation because normal site-packages is not writeable
Collecting pygame
  Downloading pygame-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (13.7 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 13.7/13.7 MB 2.8 MB/s eta 0:00:00
Installing collected packages: pygame
Successfully installed pygame-2.1.3

L'important est la dernière ligne, qui doit mentionner "Successfully installed".

Si vous pygame est déjà installé, vous aurez une sortie de la forme :

Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pygame in ./.local/lib/python3.10/site-packages (2.1.3)

Qui mentionne "Requirement already satisfied : pygame".

Première fenêtre

pygame comporte de nombreux modules, nous n'allons pas les détailler pour le moment.

Pour utiliser pygame, la première chose à faire est de l'importer.

import pygame

Il nous faut ensuite initialiser pygame. Celà lui permet de préparer des ressources d'affichage, comme par exemple les circuits graphiques du processeur ou de la carte graphique.

pygame.init()

Quand nous n'aurons plus besoin de pygame, par exemple à la fin de l'exécution du programme, il faudra le dire à pygame, pour que pygame puisse rendre les ressources qu'elle utilise.

pygame.quit()

Pour afficher une fenêtre, on doit appeler la fonction set_mode du module display. Elle retourne une valeur de type fenêtre. La syntaxe la plus simple pour l'appeler est :

fenetre = pygame.display.set_mode([largeur_fenetre, hauteur_fenetre])

Par exemple :

fenetre = pygame.display.set_mode([1280, 720])

Si on met assemble tous ces morceaux de code, ça donne :

import pygame

pygame.init()

fenetre = pygame.display.set_mode([1280, 720])

pygame.quit()

Si vous lancez ce programme, vous verrez une fenêtre apparaître pendant une fraction de secondes, puis disparaître. Peut-être même que vous n'aurez pas le temps de la voir.

C'est normal : le programme suivant crée la fenêtre, puis juste après, on appelle pygame.quit() et le programme se termine, et donc la fenêtre est détruite.

On voudrait afficher la fenêtre et attendre une action du joueur avant de quitter.

Evenements

Un des aspect du jeu vidéo est capter les actions que fait le joueur (appui sur une touche, clic souris, ...) et d'y réagir. Quand le joueur fait une action au clavier ou à la souris (appuyer ou relacher une touche, fermer la fenêtre de jeu, connecter une manette, déplacer la souris, ...), pygame enregistre l'action sous forme d'un évènement, et le met dans sa liste d'évènements.

On peut récupérer une copie de cette liste en utilisant la fonction get du module event :

evenements = pygame.event.get()

A chaque fois que l'on appelle la fonction pygame.event.get(), pygame efface la liste des évènements après en avoir envoyé une copie. Les évènements que l'on obtient sont donc ceux qui ont eu lieu depuis la dernière fois qu'on a appelé la fonction. Schématiquement, ça donne :

## Le joueur appuie sur la touche Z

evenements = pygame.event.get()

## evenements contient [appui sur Z]

## le joueur déplace la souris, et appuie sur R

evenements = pygame.event.get()

## evenements contient [deplacement souris, appui sur R]

On va donc écrire une boucle qui regarde en permanence si le joueur à fait une action, jusqu'à qu'on détecte un appui sur la touche ECHAP, auquel cas on arrêtera le programme.

Une telle boucle s'écrit ainsi :

quitter = False
while not quitter:
    ## on utilise une boucle for pour traiter les évènements
    for e in pygame.event.get():
        ## (e.type est le type de l'évènement que l'on traite
        ## pygame.KEYDOWN est le type de l'appui sur une touche)
        if e.type == pygame.KEYDOWN: 
            ## Si une touche a été appuyée
            ## (e.key est la touche appuyée dans le cas d'un evènement de type KEYDOWN
            ## pygame.K_ESCAPE corresponds à la touche ECHAP)
            if e.key == pygame.K_ESCAPE:
                ## et que la touche est ECHAP, on envoie l'ordre de quitter.
                quitter = True

On peut ajouter cette boucle dans le code de notre jeu, juste après avoir créé la fenêtre :

import pygame

pygame.init()

fenetre = pygame.display.set_mode([1280, 720])

quitter = False
while not quitter:
    for e in pygame.event.get():
        if e.type == pygame.KEYDOWN: 
            if e.key == pygame.K_ESCAPE:
                quitter = True

pygame.quit()

Maintenant, quand on lance notre programme, la fenêtre apparaît, et attends que l'on appuie sur ECHAP avant de quitter.

Couleur de fond

On va maintenant remplir la fenêtre d'une couleur unie.

Celà peut se faire avec la méthode fill, que l'on doit appeler sur la fenêtre renvoyée par display.set_mode, en passant une couleur en paramètre, par exemple :

fenetre.fill((120, 120, 120))

On peut créer une lumière de n'importe quelle couleur en mélangeant des lumières de couleurs dites primaires : le rouge, le vert et le bleu. C'est la synthèse additive des couleurs.

pygame utilise le format RGB, qui représente donc une couleur par l'intensité de chacune des trois lumières primaires qui la composent (appelé canaux) par un nombre de 0 (absence de luminosité) à 255 (luminosité maximale). Le site colorpicker.fr permet de jouer avec cette représentation.

la méthode fill attends donc comme couleur un tuple de trois entiers entre 0 et 255 : (rouge, vert, bleu)

Dans le code que nous avons vu plus haut (120, 120, 120) correspond à du gris.

Pour des raisons de performances, pygame ne répercute pas directemement les changement à l'écran. A la place, pygame maintient deux fenêtres virtuelles. L'une est modifiée pendant que l'autre est affichée. Donc, après avoir dessiné à l'écran, il nous faut dire à pygame d'afficher les changements en appelant la fonction flip du module display. Elle ne prends aucun argument :

pygame.display.flip()

Ajoutons ces deux appels dans notre code avant notre boucle d'attente.

import pygame

pygame.init()

fenetre = pygame.display.set_mode([1280, 720])

fenetre.fill((120, 120, 120))

pygame.display.flip()

quitter = False
while not quitter:
    for e in pygame.event.get():
        if e.type == pygame.KEYDOWN: 
            if e.key == pygame.K_ESCAPE:
                quitter = True

pygame.quit()

Au lancement du programme, vous devriez avoir une fenêtre remplie de gris :

fenetre gris

Essayez de changer la couleur du fond de la fenêtre, par exemple pour obtenir un fond totalement noir ou totalement blanc !

Dessiner un cercle

Pour faire un jeu vidéo, et en particulier le nôtre, lasero, on va devoir dessiner des formes et des images à l'écran.

Notre personnage sera un simple cercle. Dessinons donc un cercle !

Pour celà, il nous faut utiliser la méthode circle du module draw, qui s'appelle comme suit :

pygame.draw.circle(fenetre, couleur, centre, rayon)

Avec :

  • fenetre, la fenêtre dans laquelle on veut dessiner.
  • couleur une couleur sous forme d'un tuple RGB, qui est la couleur de remplissage du cercle.
  • centre la position du centre du cercle dans la fenêtre, exprimé en pixels.
  • rayon, le rayon du cercle, en pixels.

On peut par exemple faire l'appel suivant entre les appels à fill et à flip dans notre code :

pygame.draw.circle(fenetre, (255, 146, 205), (1280/2, 720/2), 10)

Ici, (1280/2, 720/2) est la position du centre de la fenêtre.

Ce qui donne :

import pygame

pygame.init()

fenetre = pygame.display.set_mode([1280, 720])

fenetre.fill((0, 0, 0))

pygame.draw.circle(fenetre, (255, 146, 205), (1280/2, 720/2), 10)

pygame.display.flip()

quitter = False
while not quitter:
    for e in pygame.event.get():
        if e.type == pygame.KEYDOWN: 
            if e.key == pygame.K_ESCAPE:
                quitter = True

pygame.quit()

Ce code dessine un point rose au milieu de l'écran :

point_rose

Code récapitulatif :

Voici un récapitulatif du code à la fin de cette étape :

import pygame

pygame.init()

fenetre = pygame.display.set_mode([1280, 720])

fenetre.fill((0, 0, 0))

pygame.draw.circle(fenetre, (255, 146, 205), (1280/2, 720/2), 10)

pygame.display.flip()

quitter = False
while not quitter:
    for e in pygame.event.get():
        if e.type == pygame.KEYDOWN: 
            if e.key == pygame.K_ESCAPE:
                quitter = True

pygame.quit()

Constantes

TODO (prof) constantes