Accueil

Traduction

Tutoriel Python - sommaire

Tutoriel Python - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Pygame - pour aller encore plus loin

Concernant les Rect tout n'a pas été dit.
Des astuces programmatiques très utiles n'ont pas encore été évoquées.

Tester si un sprite est sorti ou pas de la fenêtre de jeu

Jusqu'à présent pour savoir si un sprite était ou non sorti de la fenêtre de jeu il fallait quatre tests : un pour chaque bord.
Je vous propose ci-dessous un technique très simple (un seul test). Il faut cependant créer au préalable un objet de type rect correspondant à la fenêtre de jeu.
Autre nouveauté dans ce script : emploi de la méthode move_ip() à la place de move().

Le script

import pygame
from pygame.locals import *

pygame.init()
X, Y = 640, 480
fenetre = pygame.display.set_mode((X, Y))
# création d'un objet rect correspondant à la fenêtre de jeu
fenetre_rect = pygame.Rect(0, 0, X, Y)

# sprite
surface = pygame.Surface((50, 50))
surface.fill((255, 0, 0))
sprite = surface.get_rect(topleft=(X/2, Y/2))
# conversion surface en objet rect nommé 'sprite'
clock = pygame.time.Clock()
points = 20
boucler = True
#-------------boucle de jeu---------------
while boucler :
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False

    # déplacement du sprite
    keys = pygame.key.get_pressed()
    if keys[K_RIGHT]:
        sprite.move_ip(5, 0)
    if keys[K_LEFT]:
        sprite.move_ip(-5, 0)
    if keys[K_UP]:
        sprite.move_ip(0, -5)
    if keys[K_DOWN]:
        sprite.move_ip(-5, 5)

    # vérification de sortie du sprite de la fenêtre
    if not fenetre_rect.contains(sprite):
        print("Le sprite est hors de l’écran !")
        points -=1

    if points < 0 :
        boucler = False
    fenetre.fill((0, 0, 0))
    fenetre.blit(surface, sprite)
    pygame.display.flip()
    clock.tick(10)
# ----------------------
pygame.quit()
print("Vous avez perdu")

Si le sprite reste en dehors de la fenêtre durant 20 itérations cumulées, il y a sortie de la boucle de jeu.

fenetre_rect = pygame.Rect(0, 0, X, Y) : création d'un objet rect nommé "fenetre_rect" correspondant à la fenêtre de jeu.
sprite = surface.get_rect(topleft=(X/2, Y/2)) : le sprite est un Rect.
if not fenetre_rect.contains(sprite): La méthode objet1.contains(objet2) vérifie que l'objet2 est entièrement contenu dans l'objet1 ; la méthode retourne False si ce n'est pas le cas.
sprite.move_ip(5, 0) : La méthode move_ip () déplace directement de 5px vers la droite le Rect nommé "sprite".

Le rendu

Une image grossit à chaque itération

Le script

# pygame_echelle.py
import pygame
pygame.init()
X = 600
Y = 600
fenetre = pygame.display.set_mode((X,Y))
pygame.display.set_caption('transformations') 
#incorporation d'une image
image_originale = pygame.image.load("images_sons/lion.png").convert_alpha()
# création d'un objet rect à partir de l'image
origine_rect = image_originale.get_rect()
centre_fenetre = (X//2,Y//2)
clock = pygame.time.Clock()
echelle_facteur = 1.0      
echelle_pas   = 0.05

boucle_jeu = True
#-----------------
while boucle_jeu :
    for event in pygame.event.get():
             if event.type ==pygame.QUIT:
                boucle_jeu =False
    echelle_facteur += echelle_pas
    nouvelleL  = int(origine_rect.width  * echelle_facteur)
    nouvelleH = int(origine_rect.height * echelle_facteur)

    #nouvelle surface
    image_agrandie = pygame.transform.scale(image_originale,(nouvelleL,nouvelleH))
    # création d'un objet rect à partir d'une surface
    agrandie_rect = image_agrandie.get_rect()
    
    agrandie_rect.center = centre_fenetre
    fenetre.fill('navy')
    fenetre.blit(image_agrandie,agrandie_rect)
    pygame.display.flip()
    clock.tick(8)
#---------------
pygame.quit()

origine_rect = image_originale.get_rect() : création d'un objet rect à partir de l'image.
echelle_facteur += echelle_pas : la valeur de "echelle_facteur" augmente de 0.05
nouvelleL = int(origine_rect.width * echelle_facteur) : nouvelle largeur de l'image
image_agrandie = pygame.transform.scale(image_originale,(nouvelleL,nouvelleH)) : nouvelle image à partir de l'originale.
agrandie_rect = image_agrandie.get_rect() : création d'un objet rect correspondant à la nouvelle image
agrandie_rect.center = centre_fenetre : l'image et son rect associé sont centrés dans la fenêtre de jeu
fenetre.blit(image_agrandie,agrandie_rect) : dessiner l'image et son Rect associé

Le rendu

Problème : l'image PNG n'a pas un fond transparent mais un fond blanc ...
Heureusement il y a une solution ; voir le script suivant.

Convertir en transparent le fond opaque d'une image

Dans l'exemple ci-dessous deux individus peuvent joueur et déplacer chacun un sprite.

Le programme

# pygame_images_complements.py

import pygame
import random
import time

pygame.init()
tuile_dim =30
tuile_nombre = 20
largeur = tuile_dim * tuile_nombre
hauteur = tuile_dim * tuile_nombre
fenetre = pygame.display.set_mode((largeur,hauteur))
pygame.display.set_caption("compléments sur les images")
frequence = pygame.time.Clock()

class Predateurs(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("images_sons/lion.png").convert_alpha()
        self.image =pygame.transform.scale(self.image,(tuile_dim*2,tuile_dim *2))
        self.image.set_colorkey('white')
        self.rect = self.image.get_rect()

# création d'un groupe de sprites
tous = pygame.sprite.Group()
# deux instance de la classe Predateurs
lion = Predateurs()
lion.rect.bottomright = (largeur,hauteur)
lionne =Predateurs()
lionne.rect.topleft = (0,0)
tous.add(lion)
tous.add(lionne)

encore = True
# --------------boucle de jeu------------------
while encore :
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            encore = False

    # deplacement par clavier du lion qui ne peut sortir de la fenêtre de jeu
    touches = pygame.key.get_pressed()
    if lion.rect.left >=0 : 
        if touches[pygame.K_LEFT]:
            lion.rect.x -= 10
    if lion.rect.right <= largeur :
        if touches[pygame.K_RIGHT]:
            lion.rect.x += 10
    if lion.rect.top >= 0 :
        if touches[pygame.K_UP]:
            lion.rect.y -= 10
    if lion.rect.bottom <= hauteur :
        if touches[pygame.K_DOWN]:
            lion.rect.y += 10

    # deplacement par clavier de la lionne qui peut sortir de la fenêtre de jeu
    touches = pygame.key.get_pressed()
    if touches[pygame.K_d]:
        lionne.rect.x -= 10
    if touches[pygame.K_q]:
        lionne.rect.x += 10
    if touches[pygame.K_z]:
        lionne.rect.y -= 10
    if touches[pygame.K_w]:
        lionne.rect.y += 10
            
    fenetre.fill('wheat')
    # affichage des sprites
    tous.draw(fenetre)
    # actualisation 
    pygame.display.flip()
    frequence.tick(8)
# -----------------
pygame.quit()

Notez la technique des "tuiles" pour dimensionner la fenêtre de jeu.
Modifiez les variables "tuile_dim" et "tuile_nombre" pour redimensionner le jeu sans devoir modifier d'autres instructions du script.
self.image =pygame.transform.scale(self.image,(tuile_dim*2,tuile_dim *2)) : les dimensions de l'image sont modifiées ; l'image fera 2 tuiles sur donc 60 par 60 (tant que "tuile_dim" vaut 30).
self.image.set_colorkey('white') : la méthode set_colorkey(couleur) permet de rendre une couleur spécifique transparente. Donc ici je demande que le fond blanc devienne transparent. J'aurai pu écrire la couleur blanche en notation RGV sous forme d'un tuple : (255,255,255).
self.rect = self.image.get_rect() : création d'un Rect à partir de l'image.
if touches[pygame.K_d]: : si appui sur la touche "D" du clavier.
lion.rect.bottomright = (largeur,hauteur) : L'instance de Prédateur nommée "lion" est positionnée dans le coin bas droit.
lionne.rect.topleft = (0,0) : l'instance de Prédateur nommée "lionne" est positionnée dans le coin haut gauche.

Le rendu

Les images ont désormais un fond transparent et elles ont été redimensionnées.

Déplacement d'un sprite via la souris

Vous savez déplacer un sprite via les touches du clavier mais quid du déplacement via la souris ?

Les évènements relatifs à la souris

Le script

Avant de déplacer le Rect via la souris, il faut faire un clic gauche sur l'objet.
Vous pouvez alors effectuer un glissement ('drag') du Rect.
Dès que vous avez cessé l'appui d'appuyer sur le bouton de la souris, le 'drag' n'est plus possible.

# pygame_deplacer_rect_avec_souris.py
import pygame

pygame.init()
X = 600
Y = 600
fenetre = pygame.display.set_mode((X, Y))
clock = pygame.time.Clock()

# Rect à déplacer nommé 'sprite'
sprite = pygame.Rect(X/2, Y/2,50,50)
glisser = False # indique si le rect est en cours de glissement

boucler = True
#----------boucle de jeu--------------
while boucler :
    for evenement in pygame.event.get():
        if evenement.type == pygame.QUIT:
            boucler = False

        # Clic de la souris
        if evenement.type == pygame.MOUSEBUTTONDOWN:
            if evenement.button == 1: # bouton gauche de la souris
                if sprite.collidepoint(evenement.pos): # le clic est sur le Rect
                    glisser = True
                    
        # Relâchement du bouton
        if evenement.type == pygame.MOUSEBUTTONUP:
            if evenement.button == 1:
                glisser = False

        # Mouvement de la souris
        if evenement.type == pygame.MOUSEMOTION:
            if glisser :
                souris_x, souris_y = pygame.mouse.get_pos()
                sprite.x = souris_x
                sprite.y = souris_y
                print(f"position souris : {pygame.mouse.get_pos()}")
    fenetre.fill('aqua')         
    pygame.draw.rect(fenetre,'navy',sprite)  
    pygame.display.flip()
    clock.tick(10)
# --------------------------
pygame.quit()

Nouveauté dans ce programme : méthode Rect.collidepoint(coordonnées XY) qui retourne True si les coordonnées appartiennent au Rect.

Je vous invite à revoir éventuellement le chapitre 27.
if evenement.type == pygame.MOUSEBUTTONDOWN : si appui sur un bouton de la souris.
if evenement.button == 1 : si appui sur le bouton gauche de la souris.
evenement.pos : coordonnées de la souris sous forme d'un tuple.
if sprite.collidepoint(evenement.pos) : si la souris pointe bien le Rect.
if evenement.type == pygame.MOUSEBUTTONUP: si relachement de l'appui
if evenement.type == pygame.MOUSEMOTION: si déplacement de la souris
souris_x, souris_y = pygame.mouse.get_pos() : affectation des coordonnées xy de la souris à deux variables.
sprite.x = souris_x : nouvelle coordonnée x du Rect

Le rendu

Je vous invite à recréer ce script.
Vous verrez qu'il y a un petit inconvénient : un décalage ('offset') entre la position de la souris et le coin haut gauche du Rect.

La solution

...
# Mouvement de la souris
        if evenement.type == pygame.MOUSEMOTION:
            if glisser :
                souris_x, souris_y = pygame.mouse.get_pos()
                sprite.centerx = souris_x
                sprite.centery = souris_y
                print(f"position souris : {pygame.mouse.get_pos()}")

Il faut mieux utiliser les propriétés centerx & centery pour éviter "l'offset" constaté dans la première version.

Un jeu : "Jungle cruelle"

Je vous propose un jeu en guise de synthèse ; une version toute personnelle du fameux jeu du serpent. Le serpent doit dévorer 30 souris dans le minimum de temps.

Le programme

# nom du programme : jungle_cruelle.py
# apparition aléatoire de souris que le serpent doit dévorer avant qu'elles ne disparaissent

import pygame, random
pygame.init() 
pygame.mixer.init()
tuile = 25
tuile_nombre = 25
delta = tuile
compteur = 0
style= pygame.font.SysFont("Arial", 30, 0, 0)
clock = pygame.time.Clock()
son1 = pygame.mixer.Sound("images_sons/crash1.mp3") 
son2 = pygame.mixer.Sound("images_sons/crash2.mp3")
 
X =tuile * tuile_nombre
Y = tuile * tuile_nombre
duree_vie = 2000  #durée d'apparition d'une souris

fenetre = pygame.display.set_mode((X,Y)) 
pygame.display.set_caption('Le jeu du serpent')
# création d'un Rect correspondant à la fenêtre de jeu
fenetre_rect = pygame.Rect(0, 0, X, Y)

# déclaration des classes
class Serpents(pygame.sprite.Sprite): 
 def __init__(self): 
   pygame.sprite.Sprite.__init__(self) 
   self.image = pygame.transform.scale(pygame.image.load('images_sons/serpent.png') /
   .convert_alpha(),(tuile*2,tuile*2))
   self.rect = self.image.get_rect() 

class Souris(pygame.sprite.Sprite): 
 def __init__(self): 
   pygame.sprite.Sprite.__init__(self) 
   self.image = pygame.transform.scale(pygame.image.load('images_sons/souris.png') /
   .convert_alpha(), (tuile, tuile))
   self.rect = self.image.get_rect()
   # génération alétoire des coordonnées d'une nouvelle souris
   self.rect.right = random.randint(0, X)
   self.rect.top = random.randint(0, Y)
   self.instant = pygame.time.get_ticks() 

 def update(self):
    #suppresion des vieilles souris
   if pygame.time.get_ticks() - self.instant > duree_vie : 
     self.kill()
# ----------------------

# groupes de sprites : 
liste_souris = pygame.sprite.Group()
liste_sprites = pygame.sprite.Group()

# une instance de serpents : 
serpent = Serpents()
serpent.rect.center =(X //2, Y//2)
liste_sprites.add(serpent)
debut_jeu = pygame.time.get_ticks()
fin_jeu =0
#---------fonctions
def ecrire_regles(): 
    regles = [
    "Règle 1 : Utilisez la souris pour déplacer le serpent.",
    "Règle 2 : Évitez de sortir de la fenêtre de jeu.",
    "Règle 3 : Tuer 30 souris le plus vite possible.",
    "Appuyez sur ESPACE pour lancer le jeu ! "
    ]
    y = Y/2
    fenetre.fill('ivory')
    for ligne in regles:
        texte_surface = style.render(ligne, True,'navy')
        texte_rect = texte_surface.get_rect(center=(X/2, y))
        fenetre.blit(texte_surface, texte_rect)
        y += 40
    pygame.display.flip()

def score(): 
    fin_jeu = pygame.time.get_ticks()
    temps_jeu = (fin_jeu - debut_jeu) //1000
    message = f"Vous avez gagné en {temps_jeu} secondes"
    texte_surface = style.render(message, 1, 'navy')
    texte_rect = texte_surface.get_rect(center=(X/2, Y/2))
    fenetre.fill('ivory')
	fin = True
    fenetre.blit(texte_surface, texte_rect)
    pygame.display.flip()
    pygame.time.wait(5000)
    pygame.quit()

#------variables pour contrôler les boucles--------
affichage = True
fin = False
glisser = False

# -------------boucle d'affichage des règles-------
while affichage : 
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
            affichage = False        
    ecrire_regles()
    clock.tick(16)
#------------boucle de jeu--------------
while not fin: 
    
# création éventuelle d'un objet Souris à chaque itération de  la boucle de jeu
    alea = random.randint(1,4)
    if alea == 1 : 
        souris = Souris()#création d'une instance de Souris
        liste_souris.add(souris)
        liste_sprites.add(souris)
        liste_souris.update()  #appel de la méthode qui supprime les vieilles souris

    # deplacement du serpent par la souris, serpent peut sortir de la fenêtre de jeu
    for evenement in pygame.event.get():
        if evenement.type == pygame.QUIT: 
            fin = True
        # Clic de la souris
        if evenement.type == pygame.MOUSEBUTTONDOWN:
            if evenement.button == 1: # bouton gauche de la souris
                if serpent.rect.collidepoint(evenement.pos): # le clic est sur le Rect
                    glisser = True
        # Relâchement du bouton
        if evenement.type == pygame.MOUSEBUTTONUP:
            if evenement.button == 1:
                glisser = False
        # Mouvement de la souris
        if evenement.type == pygame.MOUSEMOTION:
            if glisser :
                sourisX, sourisY = pygame.mouse.get_pos()
                serpent.rect.center = (sourisX,sourisY)
        
    # gestion collision 
    if pygame.sprite.spritecollide(serpent,liste_souris,True):
        compteur +=1
        son2.play()
              
    # pénalisation si serpent sort de la fenêtre de jeu
    if not fenetre_rect.contains(serpent):
        son1.play()
        compteur -=1
       
    # si objectif atteint 
    if compteur ==30 :
        score() #appel fonction qui affiche le score

    # dans tous les cas :
    fenetre.fill("ivory")
    clock.tick(16)
    liste_sprites.draw(fenetre) 
    pygame.display.flip()

Étude de certains blocs de code

Positionnement aléatoire d'une nouvelle souris et disparation de celle-ci

Dans la définition de la classe Souris() vous trouvez le code suivant :

   # génération alétoire des coordonnées d'une nouvelle souris
   self.rect.right = random.randint(0, X)
   self.rect.top = random.randint(0, Y)
   self.instant = pygame.time.get_ticks() 

 def update(self):
    #suppresion des vieilles souris
   if pygame.time.get_ticks() - self.instant > duree_vie : 
     self.kill()

Le positionnement d'une souris est aléatoire.

Et dans la boucle de jeu on retrouve le bloc ci-dessous :

	# ajout & suppression de souris
    alea = random.randint(1,4)
    if alea == 1 : 
        souris = Souris()       #création d'une instance de Souris
        liste_souris.add(souris)
        liste_sprites.add(souris)
        liste_souris.update()  #appel de la méthode qui supprime les vieilles souris

Une nouvelle souris est créée uniquement si alea vaut 1 ; son positionnement est généré de façon aléatoire.
Toujours dans la boucle de jeu appel de la méthode update(self) qui supprime les vieilles souris : self.kill().
La méthode kill() supprime le sprite de tous les groupes (à la différence de remove()).

Les règles du jeu

Observez attentivement la fonction ecrire_regles() qui affiche sur N lignes les règles du jeu. Notez l'emploi d'une liste et d'une boucle pour afficher chaque élément de la liste.
La boucle d'affichage des règles :

while affichage : 
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
            affichage = False        
    ecrire_regles() #appel fonction 
    clock.tick(16)

Les règles du jeu sont affichées (appel fonction ecrire_regles()) tant que le joueur n'a pas appuyé sur la touche ESPACE pour entre alors dans la boucle de jeu.

Pénalisation si le serpent quitte la fenêtre de jeu

Un seul test !

	if not fenetre_rect.contains(serpent):
        son1.play()
        compteur -=1

fenetre_rect est un Rect qui correspond à la fenêtre de jeu ; le compteur est décrémenté.

Gestion collision

 if pygame.sprite.spritecollide(serpent,liste_souris,True):
        compteur +=1
        son2.play()

L'argument "dokill" est à True.

La fonction score()

Fonction appelée dès que "compteur" atteint 30.

def score() : 
	fin_jeu = pygame.time.get_ticks()
    temps_jeu = (fin_jeu - debut_jeu) //1000
    message = f"Vous avez gagné en {temps_jeu} secondes"
    texte_surface = style.render(message, 1, 'navy')
    texte_rect = texte_surface.get_rect(center=(X/2, Y/2))
    fenetre.fill('ivory')
	fin = True
    fenetre.blit(texte_surface, texte_rect)
    pygame.display.flip()
    pygame.time.wait(5000)
    pygame.quit()

Le shell n'est pas utilisé ; tout est affiché dans la fenêtre de jeu.

Durcir le jeu

Le rendu

Les règles du jeu :

Le jeu :

Jouez !

Téléchargez le programme
Afin que les chemins relatifs vers les images et les fichiers audio soient corrects, transférez le script dans le dossier "c:/pygame_jeux" (qui contient le répertoire "images_sons").

Une version améliorée du jeu labyrinthe

Nouveautés

Dans cette nouvelle version des choses vertes (des salades) apparaissent sur le parcours.
Il existe une astuce programmatique pour que ces objets soient positionnés dans les couloirs (et pas dans les parois).
Le chronomètre s'arrête dès que le personnage atteint l'aire d'arrivée et à condition d'avoir avalé toutes les 'salades'.
Par ailleurs j'ai sonorisé le jeu.

Le programme

Je ne vous présente que les ajouts / corrections par rapport à la version initiale.

Variables globales

# variables globales
tuile = 30
nbre_tuiles = 25
maxi = nbre_tuiles-2
largeur_laby = tuile * nbre_tuiles
hauteur_laby = tuile * nbre_tuiles
X = largeur_laby +20
Y = hauteur_laby + 20

Donc si vous utilisez comme trame des fichiers TXT de 40 par 40 caractères, il suffira de changer la valeur de "nbre_tuiles".

Sons et textes

pygame.init()
style= pygame.font.SysFont("Arial", 30, 0, 0)
pygame.mixer.init()
son1 = pygame.mixer.Sound("images_sons/crash1.mp3")
son2 = pygame.mixer.Sound("images_sons/crash2.mp3")

La classe Choses

Il faut définir une nouvelle classe.

class Choses(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((28,28))
        self.image.fill('green')
        self.rect = self.image.get_rect()
        self.rect.x = random.randint(2,maxi)*tuile
        self.rect.y = random.randint(2,maxi)* tuile

Le positionnement d'une instance de Choses est généré de façon aléatoire. Ça serait mieux d'afficher une image de salade plutôt qu'un carré vert ...

Les groupes de sprites

	mur = pygame.sprite.Group()
	tous = pygame.sprite.Group()
	choses = pygame.sprite.Group()

Il y a maintenant trois groupes de sprites.

Création de 10 choses vertes

Étudiez très attentivement la boucle ci-dessous.
Les "salades" doivent être créées dans les couloirs (et pas ailleurs). Donc il faut créer une instance de Choses s'il n'y a pas de conflit entre 'mur' et cette chose.

while len(choses) < 10 :
    chose = Choses()
    conflits = pygame.sprite.spritecollide(chose,mur,False)
    # création d'une chose uniquement si celle-ci n'est pas localisée dans le mur
    if len(conflits) ==0 :
        choses.add(chose)
        tous.add(chose)

Si la liste "conflits" est vide la "chose" est bien créée.
La boucle est effectuée tant que la longueur du groupe 'choses' est inférieur à 10.

Gestion collision entre personnage et choses

Il faut rajouter dans la boucle de jeu les collisions entre personnage et choses.

 if pygame.sprite.spritecollide(personnage,choses,True):
        son1.play()

L'argument "dokill" est bien sûr à True puisque le personnage doit cueillir toutes les salades.

Gestion fin de partie

    if (personnage.rect.y >= largeur_laby) and (personnage.rect.y >= largeur_laby) and len(choses)==0 :
        score()     # appel fonction qui affiche le score

Trois conditions doivent être remplies pour qu'il y ait fin de partie.

La fonction score()

def score(): 
    fin_jeu = pygame.time.get_ticks()
    temps_jeu = (fin_jeu - debut_jeu) //1000
    temps_jeu = int(temps_jeu)
    message = f"Vous avez gagné en {temps_jeu} secondes"
    texte_surface = style.render(message, 1, 'navy')
    texte_rect = texte_surface.get_rect(center=(X/2, Y/2))
	encore = False
    fenetre.fill('white')
    fenetre.blit(texte_surface, texte_rect)
    pygame.display.flip()
    pygame.time.wait(5000)
    pygame.quit()

Le score (temps parcouru) est affiché dans la fenêtre de jeu (et plus dans le shell).

Le rendu

Observez bien les dix choses ('salades' vertes) placées dans les couloirs.

À vous de jouer

Téléchargez le fichier .zip
Après décompression vous obtiendrez le fichier.py et les trois fichiers .txt.
Déplacez tous ces fichiers vers le dossier "c:\pygame_jeux" (qui contient déjà le sous-dossier "images_sons").
Enfin, vous pourrez jouer !

Règles du jeu alternatives

On pourrait imaginer que le joueur puisse faire des choix tactiques ; ne pas avaler une 'salade' trop éloignée du parcours optimal. Dans ce cas il est pénalisé d'une seconde par 'salade' non avalée mais ça peut valoir le coup ...
On pourrait imaginer aussi qu'il soit pénalisé d'une seconde pour chaque collision avec les cloisons.
Seriez-vous capable d'imaginer une nouvelle version de la fonction score() avec ces différents malus ?