Créer un jeu en Python
Développe un jeu vidéo complet avec Pygame : Snake, Pong, ou Casse-briques. Un projet ambitieux pour les passionnés de programmation !
Objectifs pédagogiques
- Comprendre la boucle de jeu (game loop)
- Gérer les événements clavier et souris
- Dessiner des formes et des images à l'écran
- Détecter les collisions entre objets
- Gérer un score et des vies
Prérequis
- Python avec la bibliothèque Pygame (pip install pygame)
- Bonnes connaissances en Python (fonctions, boucles, listes)
- Notions de base en géométrie (coordonnées, rectangles)
Concepts clés
Game Loop
Boucle infinie qui gère les événements, met à jour le jeu et affiche le rendu. Elle tourne ~60 fois par seconde.
Événements
Actions de l'utilisateur : touche pressée, clic souris, fermeture de fenêtre. On les capture avec pygame.event.get().
Sprites & Rectangles
Objets du jeu représentés par des rectangles (Rect). La collision est détectée avec rect1.colliderect(rect2).
Score & Game Over
Variables pour suivre le score et les vies. Affichage de texte avec pygame.font.
Structure de base Pygame
Voici la structure de base de tout jeu Pygame :
import pygame
import sys
# Initialisation
pygame.init()
# Configuration de la fenêtre
LARGEUR = 800
HAUTEUR = 600
ecran = pygame.display.set_mode((LARGEUR, HAUTEUR))
pygame.display.set_caption("Mon Jeu")
# Couleurs (RGB)
NOIR = (0, 0, 0)
BLANC = (255, 255, 255)
ROUGE = (255, 0, 0)
# Horloge pour contrôler les FPS
horloge = pygame.time.Clock()
FPS = 60
# Variables du jeu
score = 0
en_cours = True
# Boucle principale
while en_cours:
# 1. GESTION DES ÉVÉNEMENTS
for event in pygame.event.get():
if event.type == pygame.QUIT:
en_cours = False
# 2. MISE À JOUR DU JEU
# (déplacements, collisions, score...)
# 3. AFFICHAGE
ecran.fill(NOIR) # Effacer l'écran
# (dessiner les objets du jeu)
pygame.display.flip() # Mettre à jour l'affichage
# 4. CONTRÔLE DES FPS
horloge.tick(FPS)
# Fermeture
pygame.quit()
sys.exit()Projet : Snake
Le serpent se déplace et grandit en mangeant des pommes. S'il touche un mur ou son corps, c'est game over !
import pygame
import random
import sys
pygame.init()
# Configuration
LARGEUR, HAUTEUR = 600, 400
TAILLE_CASE = 20
ecran = pygame.display.set_mode((LARGEUR, HAUTEUR))
pygame.display.set_caption("Snake")
# Couleurs
NOIR = (0, 0, 0)
VERT = (0, 255, 0)
ROUGE = (255, 0, 0)
BLANC = (255, 255, 255)
# Police pour le score
police = pygame.font.Font(None, 36)
def nouvelle_pomme(serpent):
"""Place une pomme à un endroit libre"""
while True:
x = random.randint(0, (LARGEUR - TAILLE_CASE) // TAILLE_CASE) * TAILLE_CASE
y = random.randint(0, (HAUTEUR - TAILLE_CASE) // TAILLE_CASE) * TAILLE_CASE
if (x, y) not in serpent:
return (x, y)
def jeu():
# Position initiale du serpent (liste de tuples)
serpent = [(100, 100), (80, 100), (60, 100)]
direction = (TAILLE_CASE, 0) # Vers la droite
# Pomme
pomme = nouvelle_pomme(serpent)
# Score
score = 0
horloge = pygame.time.Clock()
while True:
# Événements
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and direction != (0, TAILLE_CASE):
direction = (0, -TAILLE_CASE)
elif event.key == pygame.K_DOWN and direction != (0, -TAILLE_CASE):
direction = (0, TAILLE_CASE)
elif event.key == pygame.K_LEFT and direction != (TAILLE_CASE, 0):
direction = (-TAILLE_CASE, 0)
elif event.key == pygame.K_RIGHT and direction != (-TAILLE_CASE, 0):
direction = (TAILLE_CASE, 0)
# Nouvelle position de la tête
tete = serpent[0]
nouvelle_tete = (tete[0] + direction[0], tete[1] + direction[1])
# Collision avec les murs ?
if (nouvelle_tete[0] < 0 or nouvelle_tete[0] >= LARGEUR or
nouvelle_tete[1] < 0 or nouvelle_tete[1] >= HAUTEUR):
print(f"Game Over! Score: {score}")
return
# Collision avec soi-même ?
if nouvelle_tete in serpent:
print(f"Game Over! Score: {score}")
return
# Ajouter la nouvelle tête
serpent.insert(0, nouvelle_tete)
# Manger la pomme ?
if nouvelle_tete == pomme:
score += 10
pomme = nouvelle_pomme(serpent)
else:
serpent.pop() # Retirer la queue
# Affichage
ecran.fill(NOIR)
# Dessiner le serpent
for segment in serpent:
pygame.draw.rect(ecran, VERT, (*segment, TAILLE_CASE-2, TAILLE_CASE-2))
# Dessiner la pomme
pygame.draw.rect(ecran, ROUGE, (*pomme, TAILLE_CASE-2, TAILLE_CASE-2))
# Afficher le score
texte = police.render(f"Score: {score}", True, BLANC)
ecran.blit(texte, (10, 10))
pygame.display.flip()
horloge.tick(10) # Vitesse du serpent
# Lancer le jeu
jeu()
pygame.quit()Projet : Pong (1 joueur)
Une raquette contrôlée par le joueur, une balle qui rebondit. Ne laisse pas la balle sortir !
import pygame
import sys
pygame.init()
LARGEUR, HAUTEUR = 800, 600
ecran = pygame.display.set_mode((LARGEUR, HAUTEUR))
pygame.display.set_caption("Pong")
NOIR = (0, 0, 0)
BLANC = (255, 255, 255)
# Raquette
raquette = pygame.Rect(LARGEUR // 2 - 60, HAUTEUR - 30, 120, 15)
vitesse_raquette = 10
# Balle
balle = pygame.Rect(LARGEUR // 2 - 10, HAUTEUR // 2 - 10, 20, 20)
vitesse_balle_x = 5
vitesse_balle_y = 5
# Score
score = 0
vies = 3
police = pygame.font.Font(None, 36)
horloge = pygame.time.Clock()
while vies > 0:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Contrôles de la raquette
touches = pygame.key.get_pressed()
if touches[pygame.K_LEFT] and raquette.left > 0:
raquette.x -= vitesse_raquette
if touches[pygame.K_RIGHT] and raquette.right < LARGEUR:
raquette.x += vitesse_raquette
# Déplacement de la balle
balle.x += vitesse_balle_x
balle.y += vitesse_balle_y
# Rebond sur les côtés
if balle.left <= 0 or balle.right >= LARGEUR:
vitesse_balle_x = -vitesse_balle_x
# Rebond en haut
if balle.top <= 0:
vitesse_balle_y = -vitesse_balle_y
# Collision avec la raquette
if balle.colliderect(raquette) and vitesse_balle_y > 0:
vitesse_balle_y = -vitesse_balle_y
score += 10
# Balle sortie en bas
if balle.bottom >= HAUTEUR:
vies -= 1
balle.center = (LARGEUR // 2, HAUTEUR // 2)
vitesse_balle_y = abs(vitesse_balle_y)
# Affichage
ecran.fill(NOIR)
pygame.draw.rect(ecran, BLANC, raquette)
pygame.draw.ellipse(ecran, BLANC, balle)
# Score et vies
texte = police.render(f"Score: {score} Vies: {vies}", True, BLANC)
ecran.blit(texte, (10, 10))
pygame.display.flip()
horloge.tick(60)
# Game Over
ecran.fill(NOIR)
game_over = police.render(f"GAME OVER - Score final: {score}", True, BLANC)
ecran.blit(game_over, (LARGEUR//2 - 150, HAUTEUR//2))
pygame.display.flip()
pygame.time.wait(3000)
pygame.quit()Idées d'amélioration
Pour Snake :
- - Augmenter la vitesse au fil du temps
- - Ajouter des obstacles
- - Différents types de pommes (bonus)
- - Mode 2 joueurs
- - Meilleur score sauvegardé
Pour Pong :
- - Mode 2 joueurs
- - Effets de son
- - Balle qui accélère
- - Briques à casser (Casse-briques)
- - Power-ups (raquette plus grande...)
Critères d'évaluation
| Critère | Points |
|---|---|
| Jeu fonctionnel et jouable | 4 pts |
| Contrôles réactifs (clavier/souris) | 3 pts |
| Détection des collisions | 3 pts |
| Système de score et/ou vies | 3 pts |
| Code structuré et commenté | 3 pts |
| Originalité et fonctionnalités bonus | 4 pts |
| Total | 20 pts |
Pour aller plus loin
Variante 1 : Casse-briques
Combine Pong avec des briques à détruire. Ajoute des niveaux de difficulté.
Variante 2 : Platformer
Crée un jeu de plateforme avec gravité, sauts et obstacles.
Variante 3 : Space Invaders
Un vaisseau qui tire sur des ennemis qui descendent.
Variante 4 : Quiz Game
Un quiz interactif avec interface graphique et chronomètre.
