Ce que vous allez apprendre
Ce chapitre explore deux concepts fondamentaux : le systeme de couleurs (RGB, HSV, transparence) et le systeme de coordonnees de Pygame. Vous apprendrez a generer des couleurs arc-en-ciel, a comprendre ou se trouve le point (0, 0), et a afficher une grille de debug pour mieux visualiser le positionnement des elements.
Le concept
Le systeme de coordonnees
En Pygame, le point (0, 0) se trouve dans le coin superieur gauche de la fenetre. L'axe X va vers la droite, l'axe Y va vers le bas. C'est l'inverse de ce que vous avez appris en mathematiques, ou Y monte vers le haut.
Pour une fenetre de 800x600 :
- Le coin superieur gauche est
(0, 0) - Le coin superieur droit est
(799, 0) - Le coin inferieur gauche est
(0, 599) - Le coin inferieur droit est
(799, 599)
Les couleurs
Pygame supporte plusieurs facons de definir les couleurs :
- RGB : tuple de 3 entiers
(rouge, vert, bleu)de 0 a 255 - RGBA : tuple de 4 entiers avec un canal alpha (transparence) de 0 (invisible) a 255 (opaque)
- HSV : via
pygame.Color, on peut definir teinte, saturation et valeur
Le modele HSV est particulierement utile pour generer des degradees : en faisant varier la teinte (Hue) de 0 a 360, on obtient un arc-en-ciel complet.
Etape par etape
1. Generer des couleurs arc-en-ciel
Notre fonction rainbow_color utilise le modele HSV de Pygame. On fait varier la teinte en fonction du numero de rangee pour obtenir un spectre de couleurs uniforme.
def rainbow_color(row, total_rows):
"""Generate a rainbow color based on row position."""
hue = int(360 * row / total_rows)
color = pygame.Color(0)
color.hsva = (hue, 100, 100, 100)
return (color.r, color.g, color.b)
pygame.Color est un objet puissant. Sa propriete hsva accepte un tuple (teinte, saturation, valeur, alpha). La teinte va de 0 a 360 (cercle chromatique), la saturation et la valeur de 0 a 100. On recupere ensuite les composantes r, g, b pour obtenir un tuple RGB classique.
2. Effet de damier sur les briques
Pour donner plus de relief visuel, on alterne la luminosite des briques en fonction de la parite de (row + col). C'est un effet de damier simple mais efficace.
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 = rainbow_color(row, BRICK_ROWS)
# Alternate brightness for checkerboard effect
if (row + col) % 2 == 0:
color = tuple(min(255, c + 30) for c in color)
pygame.draw.rect(screen, color, (x, y, BRICK_WIDTH, BRICK_HEIGHT))
pygame.draw.rect(screen, (255, 255, 255),
(x, y, BRICK_WIDTH, BRICK_HEIGHT), 1)
Le deuxieme appel a draw.rect avec width=1 dessine un contour blanc fin autour de chaque brique, ce qui les separe visuellement.
3. Grille de coordonnees
Pour debugger le placement des elements, on ajoute une grille qui s'active avec la touche G. Elle trace des lignes tous les 50 pixels.
show_grid = False
# In the event loop:
if event.key == pygame.K_g:
show_grid = not show_grid
# In the draw section:
if show_grid:
for gx in range(0, SCREEN_WIDTH, 50):
pygame.draw.line(screen, (50, 50, 70), (gx, 0), (gx, SCREEN_HEIGHT))
for gy in range(0, SCREEN_HEIGHT, 50):
pygame.draw.line(screen, (50, 50, 70), (0, gy), (SCREEN_WIDTH, gy))
4. Afficher les coordonnees de la souris
Pour mieux comprendre le systeme de coordonnees, on affiche en permanence la position de la souris. On utilise pygame.mouse.get_pos() et le rendu de texte (que nous verrons en detail au chapitre 8).
mouse_x, mouse_y = pygame.mouse.get_pos()
font = pygame.font.SysFont("monospace", 14)
coord_text = font.render(f"({mouse_x}, {mouse_y})", True, (150, 150, 150))
screen.blit(coord_text, (10, SCREEN_HEIGHT - 25))
Points cles a retenir
Astuce : pygame.Color supporte aussi les noms de couleurs en anglais : pygame.Color("red"), pygame.Color("dodgerblue"). C'est pratique pour le prototypage rapide.
Piege courant : le canal alpha (RGBA) ne fonctionne pas directement avec pygame.draw sur la surface principale. Pour utiliser la transparence, il faut dessiner sur une surface intermediaire avec SRCALPHA, puis la copier sur l'ecran avec blit(). Nous verrons cela au chapitre 5.
Fonctions Pygame utilisees :
pygame.Color: objet couleur avec support RGB, RGBA, HSVcolor.hsva: definir/lire la couleur en Hue-Saturation-Valuepygame.mouse.get_pos(): position actuelle du curseurpygame.font.SysFont(): charger une police systemefont.render(): convertir du texte en Surface
Code complet
"""Brick Breaker - Chapter 3: Colors and Coordinates"""
import pygame
import sys
pygame.init()
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
BG_COLOR = (20, 20, 40)
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_RADIUS = 8
BALL_COLOR = (255, 255, 255)
ball_x = SCREEN_WIDTH // 2
ball_y = SCREEN_HEIGHT // 2
BRICK_ROWS = 6
BRICK_COLS = 10
BRICK_WIDTH = 70
BRICK_HEIGHT = 20
BRICK_PADDING = 5
BRICK_OFFSET_X = 30
BRICK_OFFSET_Y = 50
def rainbow_color(row, total_rows):
"""Generate a rainbow color based on row position."""
hue = int(360 * row / total_rows)
color = pygame.Color(0)
color.hsva = (hue, 100, 100, 100)
return (color.r, color.g, color.b)
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Brick Breaker - Chapter 3")
clock = pygame.time.Clock()
font = pygame.font.SysFont("monospace", 14)
show_grid = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if event.key == pygame.K_g:
show_grid = not show_grid
mouse_x, mouse_y = pygame.mouse.get_pos()
screen.fill(BG_COLOR)
# Draw bricks with rainbow colors and slight alpha variation
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 = rainbow_color(row, BRICK_ROWS)
# Alternate brightness for checkerboard effect
if (row + col) % 2 == 0:
color = tuple(min(255, c + 30) for c in color)
pygame.draw.rect(screen, color, (x, y, BRICK_WIDTH, BRICK_HEIGHT))
pygame.draw.rect(screen, (255, 255, 255),
(x, y, BRICK_WIDTH, BRICK_HEIGHT), 1)
# 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)
# Show grid overlay
if show_grid:
for gx in range(0, SCREEN_WIDTH, 50):
pygame.draw.line(screen, (50, 50, 70),
(gx, 0), (gx, SCREEN_HEIGHT))
for gy in range(0, SCREEN_HEIGHT, 50):
pygame.draw.line(screen, (50, 50, 70),
(0, gy), (SCREEN_WIDTH, gy))
# Show coordinates
coord_text = font.render(f"({mouse_x}, {mouse_y})", True, (150, 150, 150))
screen.blit(coord_text, (10, SCREEN_HEIGHT - 25))
# Show instructions
grid_text = font.render("[G] Toggle grid [ESC] Quit", True, (100, 100, 100))
screen.blit(grid_text, (SCREEN_WIDTH - 280, SCREEN_HEIGHT - 25))
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
sys.exit()
Telechargement
Telecharger le code source de ce chapitre : brick-breaker-ch03.zip
