Introduction
Dans ce projet, nous allons créer un jeu de labyrinthe à l'aide de la bibliothèque Pygame en Python. Le jeu consiste à faire naviguer un joueur dans un labyrinthe pour ramasser des objets de nourriture tout en évitant les murs. Nous allons diviser le processus de développement en plusieurs étapes pour le rendre plus facile à comprendre et à suivre.
👀 Aperçu

🎯 Tâches
Dans ce projet, vous allez apprendre :
- Comment configurer l'environnement du jeu à l'aide de Pygame
- Comment créer le labyrinthe à l'aide de cellules et de murs
- Comment ajouter des objets de nourriture pour que le joueur puisse les ramasser
- Comment implémenter le mouvement du joueur et la détection de collisions
- Comment gérer la logique du jeu, y compris le calcul du score et les conditions de fin de partie
- Comment suivre le record du joueur
- Comment afficher des statistiques de jeu telles que le temps, le score et le record à l'écran
🏆 Réalisations
Après avoir terminé ce projet, vous serez capable de :
- Utiliser la bibliothèque Pygame pour le développement de jeux
- Appliquer les concepts de programmation orientée objet pour créer des éléments de jeu
- Monter en évidence votre capacité à penser algorithmiquement et à résoudre des problèmes pour la génération de labyrinthes
- Gérer le traitement des événements et l'entrée du joueur
- Implémenter la détection de collisions et les mécanismes de mouvement dans un environnement de jeu
- Gérer la manipulation de fichiers pour stocker et récupérer les records de jeu
- Afficher des statistiques et des informations de jeu à l'écran
Configuration de l'environnement
Tout d'abord, nous allons créer les fichiers du projet pour le jeu de labyrinthe.
cd ~/projet
touch maze.py
sudo pip install pygame
Dans cette étape, nous allons configurer l'environnement Pygame et définir des constantes.
import pygame
from random import choice, randrange
## Constantes pour les dimensions de l'écran et la taille des tuiles
RES = LARGEUR, HAUTEUR = 1202, 902
CARREAU = 100
cols, rows = LARGEUR // CARREAU, HAUTEUR // CARREAU
## Le reste de votre code ira ici...
Dans cette étape :
- Nous importons les bibliothèques nécessaires (Pygame et random).
- Nous définissons des constantes pour les dimensions de l'écran et la taille des tuiles.
- Pygame est initialisé et la fenêtre de jeu est configurée.
- Nous chargeons les images d'arrière-plan pour le jeu.
Création de la classe Cellule
Dans cette étape, nous allons définir la classe Cell pour représenter les cellules du labyrinthe.
## Définissez une classe pour représenter les cellules dans le labyrinthe
class Cell:
def __init__(self, x, y):
self.x, self.y = x, y
## Les murs représentent les limites de la cellule
self.walls = {"top": True, "right": True, "bottom": True, "left": True}
self.visited = False
self.thickness = 4
## Dessinez les murs de la cellule
def draw(self, sc):
x, y = self.x * TILE, self.y * TILE
if self.walls["top"]:
pygame.draw.line(
sc, pygame.Color("darkorange"), (x, y), (x + TILE, y), self.thickness
)
if self.walls["right"]:
pygame.draw.line(
sc,
pygame.Color("darkorange"),
(x + TILE, y),
(x + TILE, y + TILE),
self.thickness,
)
if self.walls["bottom"]:
pygame.draw.line(
sc,
pygame.Color("darkorange"),
(x + TILE, y + TILE),
(x, y + TILE),
self.thickness,
)
if self.walls["left"]:
pygame.draw.line(
sc, pygame.Color("darkorange"), (x, y + TILE), (x, y), self.thickness
)
## Obtenez les rectangles représentant chaque mur de la cellule
def get_rects(self):
rects = []
x, y = self.x * TILE, self.y * TILE
if self.walls["top"]:
rects.append(pygame.Rect((x, y), (TILE, self.thickness)))
if self.walls["right"]:
rects.append(pygame.Rect((x + TILE, y), (self.thickness, TILE)))
if self.walls["bottom"]:
rects.append(pygame.Rect((x, y + TILE), (TILE, self.thickness)))
if self.walls["left"]:
rects.append(pygame.Rect((x, y), (self.thickness, TILE)))
return rects
## Vérifiez si une cellule voisine existe
def check_cell(self, x, y):
find_index = lambda x, y: x + y * cols
if x < 0 or x > cols - 1 or y < 0 or y > rows - 1:
return False
return self.grid_cells[find_index(x, y)]
## Obtenez les cellules voisines qui n'ont pas été visitées
def check_neighbors(self, grid_cells):
self.grid_cells = grid_cells
neighbors = []
top = self.check_cell(self.x, self.y - 1)
right = self.check_cell(self.x + 1, self.y)
bottom = self.check_cell(self.x, self.y + 1)
left = self.check_cell(self.x - 1, self.y)
if top and not top.visited:
neighbors.append(top)
if right and not right.visited:
neighbors.append(right)
if bottom and not bottom.visited:
neighbors.append(bottom)
if left and not left.visited:
neighbors.append(left)
return choice(neighbors) if neighbors else False
## Le reste de votre code ira ici...
Dans cette étape :
- Nous définissons la classe
Cellavec ses propriétés et méthodes pour dessiner les murs et vérifier les voisins.
Suppression des murs et génération du labyrinthe
Dans cette étape, nous allons créer des fonctions pour supprimer les murs et générer le labyrinthe.
## Fonction pour supprimer les murs entre deux cellules adjacentes
def remove_walls(current, next):
dx = current.x - next.x
if dx == 1:
current.walls["left"] = False
next.walls["right"] = False
elif dx == -1:
current.walls["right"] = False
next.walls["left"] = False
dy = current.y - next.y
if dy == 1:
current.walls["top"] = False
next.walls["bottom"] = False
elif dy == -1:
current.walls["bottom"] = False
next.walls["top"] = False
## Fonction pour générer le labyrinthe
def generate_maze():
grid_cells = [Cell(col, row) for row in range(rows) for col in range(cols)]
current_cell = grid_cells[0]
array = []
break_count = 1
while break_count!= len(grid_cells):
current_cell.visited = True
next_cell = current_cell.check_neighbors(grid_cells)
if next_cell:
next_cell.visited = True
break_count += 1
array.append(current_cell)
remove_walls(current_cell, next_cell)
current_cell = next_cell
elif array:
current_cell = array.pop()
return grid_cells
## Le reste de votre code ira ici...
Dans cette étape :
- Nous définissons la fonction
remove_wallspour supprimer les murs entre les cellules adjacentes. - Nous créons la fonction
generate_mazepour générer le labyrinthe en utilisant un algorithme de recherche en profondeur.
Ajout de nourriture au jeu
Dans cette étape, nous allons créer une classe Food pour ajouter des objets de nourriture au jeu.
## Classe pour représenter la nourriture dans le jeu
class Food:
def __init__(self):
## Chargez l'image de la nourriture
self.img = pygame.image.load("img/food.png").convert_alpha()
self.img = pygame.transform.scale(self.img, (TILE - 10, TILE - 10))
self.rect = self.img.get_rect()
self.set_pos()
## Définissez la position de la nourriture aléatoirement
def set_pos(self):
self.rect.topleft = randrange(cols) * TILE + 5, randrange(rows) * TILE + 5
## Dessinez la nourriture à l'écran
def draw(self):
game_surface.blit(self.img, self.rect)
## Le reste de votre code ira ici...
Dans cette étape :
- Nous définissons la classe
Foodavec des méthodes pour définir la position et dessiner les objets de nourriture.
Déplacement du joueur et détection de collisions
Dans cette étape, nous allons configurer les contrôles, le déplacement du joueur et la détection de collisions.
## Vérifiez si le joueur entre en collision avec les murs
def is_collide(x, y):
tmp_rect = player_rect.move(x, y)
if tmp_rect.collidelist(walls_collide_list) == -1:
return False
return True
## Le reste de votre code ira ici...
Dans cette étape :
- Nous définissons la fonction
is_collidepour vérifier si le joueur entre en collision avec les murs.
Jeu et notation
Dans cette étape, nous allons implémenter la logique du gameplay, y compris la consommation de nourriture et la notation.
## Vérifiez si le joueur a consommé de la nourriture
def eat_food():
for food in food_list:
if player_rect.collidepoint(food.rect.center):
food.set_pos()
return True
return False
## Vérifiez si la partie est terminée (le temps s'écoule)
def is_game_over():
global time, score, record, FPS
if time < 0:
pygame.time.wait(700)
player_rect.center = TILE // 2, TILE // 2
[food.set_pos() for food in food_list]
set_record(record, score)
record = get_record()
time, score, FPS = 60, 0, 60
## Le reste de votre code ira ici...
Dans cette étape :
- Nous définissons la fonction
eat_foodpour vérifier si le joueur a consommé de la nourriture. - Nous créons la fonction
is_game_overpour vérifier si la partie est terminée lorsque le temps s'écoule.
Gestion des enregistrements
Dans cette étape, nous allons implémenter la conservation des records pour le jeu.
## Fonction pour obtenir le record actuel à partir d'un fichier
def get_record():
try:
with open("record") as f:
return f.readline()
except FileNotFoundError:
with open("record", "w") as f:
f.write("0")
return "0"
## Fonction pour définir et mettre à jour le record dans un fichier
def set_record(record, score):
rec = max(int(record), score)
with open("record", "w") as f:
f.write(str(rec))
## Le reste de votre code ira ici...
Dans cette étape :
- Nous définissons des fonctions pour récupérer le record actuel à partir d'un fichier et le mettre à jour.
Initialisation du jeu
Dans cette étape, nous allons effectuer les tâches d'initialisation du jeu.
## Initialisez Pygame et configurez la fenêtre du jeu
FPS = 60
pygame.init()
game_surface = pygame.Surface(RES)
surface = pygame.display.set_mode((WIDTH + 300, HEIGHT))
clock = pygame.time.Clock()
## Chargez les images d'arrière-plan
bg_game = pygame.image.load("img/bg_1.jpg").convert()
bg = pygame.image.load("img/bg_main.jpg").convert()
## Générez le labyrinthe
maze = generate_maze()
## Paramètres du joueur
vitesse_joueur = 5
img_joueur = pygame.image.load("img/0.png").convert_alpha()
img_joueur = pygame.transform.scale(
img_joueur, (TILE - 2 * maze[0].épaisseur, TILE - 2 * maze[0].épaisseur)
)
rect_joueur = img_joueur.get_rect()
rect_joueur.center = TILE // 2, TILE // 2
directions = {
"a": (-vitesse_joueur, 0),
"d": (vitesse_joueur, 0),
"w": (0, -vitesse_joueur),
"s": (0, vitesse_joueur),
}
keys = {"a": pygame.K_LEFT, "d": pygame.K_RIGHT, "w": pygame.K_UP, "s": pygame.K_DOWN}
direction = (0, 0)
## Paramètres de la nourriture
liste_nourriture = [Food() for i in range(3)]
## Créez une liste de rectangles représentant les murs pour la détection de collisions
liste_collisions_murs = sum([cell.get_rects() for cell in maze], [])
## Timer, score et record
pygame.time.set_timer(pygame.USEREVENT, 1000)
temps = 60
score = 0
record = get_record()
## Polices d'écriture
font = pygame.font.SysFont("Impact", 150)
text_font = pygame.font.SysFont("Impact", 80)
## Le reste de votre code ira ici...
Dans cette étape :
- Nous effectuons diverses tâches d'initialisation, y compris la configuration de Pygame, le chargement d'images, la génération du labyrinthe et l'initialisation des variables liées au joueur et à la nourriture.
Boucle principale du jeu
Dans cette étape, nous allons configurer la boucle principale du jeu et afficher les éléments du jeu.
## Boucle principale du jeu
while True:
## Affichez les images d'arrière-plan
surface.blit(bg, (WIDTH, 0))
surface.blit(game_surface, (0, 0))
game_surface.blit(bg_game, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
if event.type == pygame.USEREVENT:
temps -= 1
## Gérer les contrôles et le déplacement du joueur
touches_appuyées = pygame.key.get_pressed()
for key, key_value in keys.items():
if touches_appuyées[key_value] and not is_collide(*directions[key]):
direction = directions[key]
break
if not is_collide(*direction):
rect_joueur.move_ip(direction)
## Dessinez le labyrinthe
[cell.draw(game_surface) for cell in maze]
## Gameplay : Vérifiez si le joueur a consommé de la nourriture et si la partie est terminée
if eat_food():
FPS += 10
score += 1
is_game_over()
## Dessinez le joueur
game_surface.blit(img_joueur, rect_joueur)
## Dessinez les éléments de nourriture
[food.draw() for food in food_list]
## Le reste de votre code ira ici...
Dans cette étape :
- Nous configurons la boucle principale du jeu qui gère les événements, le déplacement du joueur et le rendu du jeu.
Affichage des statistiques du jeu
Dans cette étape, nous allons afficher les statistiques du jeu sur l'écran.
## Dessinez les statistiques du jeu
surface.blit(
text_font.render("TIME", True, pygame.Color("cyan"), True), (WIDTH + 70, 30)
)
surface.blit(font.render(f"{temps}", True, pygame.Color("cyan")), (WIDTH + 70, 130))
surface.blit(
text_font.render("score:", True, pygame.Color("forestgreen"), True),
(WIDTH + 50, 350),
)
surface.blit(
font.render(f"{score}", True, pygame.Color("forestgreen")), (WIDTH + 70, 430)
)
surface.blit(
text_font.render("record:", True, pygame.Color("magenta"), True),
(WIDTH + 30, 620),
)
surface.blit(
font.render(f"{record}", True, pygame.Color("magenta")), (WIDTH + 70, 700)
)
pygame.display.flip()
clock.tick(FPS)
Dans cette étape :
- Nous utilisons des polices pour afficher des informations liées au jeu telles que le temps, le score et le record.
- Nous utilisons la méthode
blit()pour dessiner le texte sur l'écran. - Nous utilisons la méthode
flip()pour mettre à jour l'affichage.
Lancez le jeu
Maintenant que nous avons terminé toutes les étapes, nous pouvons exécuter le jeu Labyrinthe en utilisant la commande suivante :
cd ~/projet
python maze.py

Résumé
Dans ce projet, nous avons divisé le processus de construction d'un jeu de labyrinthe utilisant Pygame en dix étapes claires et gérées facilement. Vous allez apprendre à configurer l'environnement du jeu, créer des cellules de labyrinthe, générer le labyrinthe, gérer le mouvement du joueur et la détection de collisions, implémenter le gameplay et le scoring, gérer les records, et bien plus encore. En suivant ces étapes, vous serez capable de créer un jeu de labyrinthe entièrement fonctionnel en Python.



