Ce que vous allez apprendre

Dans ce chapitre, vous allez apprendre a dessiner des formes geometriques a l'ecran : rectangles, cercles et lignes. Ce sont les briques de base (sans jeu de mots) de tout jeu 2D. A la fin, vous aurez une raquette, une balle et un mur de briques colorees affiches a l'ecran.

Le concept

Pygame offre un module pygame.draw qui contient des fonctions pour dessiner directement sur une Surface. La fenetre du jeu est elle-meme une Surface. A chaque frame, on efface tout avec fill() puis on redessine chaque element.

Les fonctions principales sont :

  • pygame.draw.rect(surface, couleur, rectangle) : dessine un rectangle
  • pygame.draw.circle(surface, couleur, centre, rayon) : dessine un cercle
  • pygame.draw.line(surface, couleur, debut, fin) : dessine une ligne

Un rectangle est defini par un tuple (x, y, largeur, hauteur). Les coordonnees (x, y) representent le coin superieur gauche. Les couleurs sont des tuples RGB de 0 a 255.

L'ordre dans lequel vous dessinez est important : ce qui est dessine en dernier apparait par-dessus le reste. C'est le principe du painter's algorithm (algorithme du peintre). Dessinez d'abord le fond, puis les briques, puis la raquette, puis la balle.

Etape par etape

1. Definir les dimensions des elements

On commence par definir les constantes pour chaque element du jeu. Utiliser des constantes en majuscules rend le code lisible et facile a modifier.

python
# Paddle
PADDLE_WIDTH = 100
PADDLE_HEIGHT = 15
PADDLE_COLOR = (200, 200, 200)
paddle_x = SCREEN_WIDTH // 2 - PADDLE_WIDTH // 2
paddle_y = SCREEN_HEIGHT - 40

# Ball
BALL_RADIUS = 8
BALL_COLOR = (255, 255, 255)
ball_x = SCREEN_WIDTH // 2
ball_y = SCREEN_HEIGHT // 2

# Bricks
BRICK_ROWS = 5
BRICK_COLS = 10
BRICK_WIDTH = 70
BRICK_HEIGHT = 20
BRICK_PADDING = 5
BRICK_OFFSET_X = 30
BRICK_OFFSET_Y = 50

Remarquez que paddle_x est calcule pour centrer la raquette horizontalement. L'operateur // effectue une division entiere, ce qui est important car les pixels sont des entiers.

2. Palette de couleurs pour les briques

Chaque rangee de briques aura une couleur differente. On stocke les couleurs dans une liste, indexee par le numero de rangee.

python
BRICK_COLORS = [
    (231, 76, 60),   # Red
    (230, 126, 34),  # Orange
    (241, 196, 15),  # Yellow
    (46, 204, 113),  # Green
    (52, 152, 219),  # Blue
]

3. Dessiner les briques avec une double boucle

On utilise deux boucles imbriquees : une pour les rangees, une pour les colonnes. La position de chaque brique est calculee a partir de sa rangee et sa colonne, en tenant compte de l'espacement (BRICK_PADDING) et du decalage initial.

python
# Draw bricks
for row in range(BRICK_ROWS):
    for col in range(BRICK_COLS):
        x = BRICK_OFFSET_X + col * (BRICK_WIDTH + BRICK_PADDING)
        y = BRICK_OFFSET_Y + row * (BRICK_HEIGHT + BRICK_PADDING)
        color = BRICK_COLORS[row]
        pygame.draw.rect(screen, color, (x, y, BRICK_WIDTH, BRICK_HEIGHT))

4. Dessiner la raquette et la balle

La raquette est un simple rectangle. La balle est un cercle. Notez que pour draw.circle, on donne le centre du cercle, alors que pour draw.rect, c'est le coin superieur gauche.

python
# Draw paddle
pygame.draw.rect(screen, PADDLE_COLOR,
                 (paddle_x, paddle_y, PADDLE_WIDTH, PADDLE_HEIGHT))

# Draw ball
pygame.draw.circle(screen, BALL_COLOR, (ball_x, ball_y), BALL_RADIUS)

Points cles a retenir

Astuce : pour dessiner un rectangle avec seulement le contour (sans remplissage), ajoutez un parametre width a la fin : pygame.draw.rect(screen, color, rect, 2) dessine un contour de 2 pixels d'epaisseur.

Piege courant : si vos briques semblent decalees, verifiez que vous n'oubliez pas le padding dans le calcul de position. Une erreur classique est d'ecrire col * BRICK_WIDTH au lieu de col * (BRICK_WIDTH + BRICK_PADDING).

Fonctions Pygame utilisees :

  • pygame.draw.rect() : dessine un rectangle (plein ou contour)
  • pygame.draw.circle() : dessine un cercle

Code complet

python
"""Brick Breaker - Chapter 2: Drawing Primitives"""
import pygame
import sys

pygame.init()

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
BG_COLOR = (20, 20, 40)

# Paddle
PADDLE_WIDTH = 100
PADDLE_HEIGHT = 15
PADDLE_COLOR = (200, 200, 200)
paddle_x = SCREEN_WIDTH // 2 - PADDLE_WIDTH // 2
paddle_y = SCREEN_HEIGHT - 40

# Ball
BALL_RADIUS = 8
BALL_COLOR = (255, 255, 255)
ball_x = SCREEN_WIDTH // 2
ball_y = SCREEN_HEIGHT // 2

# Bricks
BRICK_ROWS = 5
BRICK_COLS = 10
BRICK_WIDTH = 70
BRICK_HEIGHT = 20
BRICK_PADDING = 5
BRICK_OFFSET_X = 30
BRICK_OFFSET_Y = 50
BRICK_COLORS = [
    (231, 76, 60),   # Red
    (230, 126, 34),  # Orange
    (241, 196, 15),  # Yellow
    (46, 204, 113),  # Green
    (52, 152, 219),  # Blue
]

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Brick Breaker - Chapter 2")
clock = pygame.time.Clock()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            running = False

    screen.fill(BG_COLOR)

    # Draw bricks
    for row in range(BRICK_ROWS):
        for col in range(BRICK_COLS):
            x = BRICK_OFFSET_X + col * (BRICK_WIDTH + BRICK_PADDING)
            y = BRICK_OFFSET_Y + row * (BRICK_HEIGHT + BRICK_PADDING)
            color = BRICK_COLORS[row]
            pygame.draw.rect(screen, color, (x, y, BRICK_WIDTH, BRICK_HEIGHT))

    # Draw paddle
    pygame.draw.rect(screen, PADDLE_COLOR,
                     (paddle_x, paddle_y, PADDLE_WIDTH, PADDLE_HEIGHT))

    # Draw ball
    pygame.draw.circle(screen, BALL_COLOR, (ball_x, ball_y), BALL_RADIUS)

    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
sys.exit()

Telechargement

Telecharger le code source de ce chapitre : brick-breaker-ch02.zip