Dojo Defender : Session 3

Aujourd’hui, Dojo Defender déménage de pgzero vers le vrai pygame. Plus de pgzrun.go() — c’est toi qui écris la game loop. Le jeu reste le même, mais le moteur en dessous change. Et à la fin, tu ajoutes du SON.

Ce que tu vas apprendre aujourd’hui

  • La différence entre pgzero et raw pygame
  • Programmer la game loop toi-même : while running: clock.tick(60)
  • Convertir les Actors en Surface + Rect
  • Charger et jouer du son avec pygame.mixer
  • Faire tourner la musique de fond en boucle

Étape 0 : Télécharge le starter

Le starter d’aujourd’hui est un portage complet de Dojo Defender Session 2 vers raw pygame. Plus de pgzero, mais il se joue pareil.

  1. Télécharge le starter Dojo Defender d’aujourd’hui, décompresse et ouvre main.py.
  2. Tu n’étais pas là la dernière fois ? Télécharge la solution de la session 2 et essaie de la porter.
  3. Clique sur Run. Le jeu marche comme tu en as l’habitude : vaisseau, astéroïdes, balles, ennemis, vagues, explosions.

Qu’est-ce qui a changé ?

En pgzero, tu écrivais draw() et update() et pgzrun faisait le reste. En raw pygame, tu fais tout toi-même :

pgzero (avant) :

import pgzrun

def draw():
    screen.fill((10, 10, 30))
    ship.draw()

def update():
    if keyboard.left:
        ship.x -= 5

pgzrun.go()

raw pygame (maintenant) :

import pygame, sys
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()

running = True
while running:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit(); sys.exit()

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        ship.rect.centerx -= 5

    screen.fill((10, 10, 30))
    ship.draw(screen)
    pygame.display.flip()

Les différences les plus importantes :

pgzeroraw pygame
Actor('plaatje')GameObject('plaatje.png', x, y)
keyboard.leftkeys[pygame.K_LEFT]
on_key_down(key)event.type == pygame.KEYDOWN
screen.draw.text(...)font.render() + screen.blit()
rock.colliderect(ship)rock.rect.colliderect(ship.rect)
pgzrun.go()while running: ... clock.tick(60)

Étape 1 : Explore le code

Ouvre main.py et compare avec l’ancien code pgzero de la session 2. Cherche ces morceaux :

  1. Game loop — Cherche la boucle while running:. Tu vois clock.tick(60), pygame.display.flip() ?
  2. GameObject — Cherche la class GameObject. Comment une image est-elle chargée ? C’est quoi, rect ?
  3. Input — Cherche pygame.key.get_pressed() et pygame.KEYDOWN. Comment marche la barre d’espace ?

Change WIDTH en 1024. Qu’est-ce qui se passe ? (Tout devient plus large — le jeu marche encore.)

Étape 2 : ✅ Basic — Ajoute un restart avec la touche R

Dans la version pgzero, tu ne savais pas redémarrer après un game over. Ajoute-le maintenant :

# dans la boucle d'événements, à KEYDOWN :
if event.key == pygame.K_r and game_over:
    # tout réinitialiser
    ship.rect.center = (WIDTH / 2, HEIGHT - 50)
    ship.visible = True
    asteroids.clear()
    bullets.clear()
    enemies.clear()
    lives = 3
    score = 0
    wave = 1
    enemies_destroyed = 0
    spawn_counter = 0
    spawn_interval = 120
    wave_display_timer = 0
    game_over = False
    invincible = False
    ship.visible = True

Affiche aussi un indice sur l’écran de game over : appuie sur R pour rejouer.

Étape 3 : ⭐ Stretch — Ajoute du son

Le starter n’a pas encore de son. Ajoute des sons !

Crée un dossier sounds/ à côté de images/ et copie les fichiers audio de dojo-defender-assets/sounds/ (demande au coach). Ou télécharge la solution qui les contient déjà.

Ajoute en haut :

pygame.mixer.init()  # après pygame.init()

shoot_sound = pygame.mixer.Sound('sounds/shoot.wav')
explode_sound = pygame.mixer.Sound('sounds/explode.wav')
hit_sound = pygame.mixer.Sound('sounds/hit.wav')
pygame.mixer.music.load('sounds/bg_music.wav')
pygame.mixer.music.play(-1)  # -1 = répéter en boucle

Attention : le chemin doit être correct. Utilise os.path.join(_DIR, 'sounds/shoot.wav') comme le starter le fait aussi pour les images.

Joue les sons au bon moment :

  • shoot_sound.play() — quand tu tires
  • explode_sound.play() — quand un ennemi ou un astéroïde explose
  • hit_sound.play() — quand ton vaisseau est touché

Étape 4 : 🔥 Expert — Bouton mute et volume

Ajoute une touche M qui coupe et remet le son :

muted = False

# à KEYDOWN :
if event.key == pygame.K_m:
    muted = not muted
    pygame.mixer.music.set_volume(0 if muted else 1)

Chaque son doit alors être vérifié :

if not muted:
    shoot_sound.play()

Volume par son : Mets le son de tir plus bas que l’explosion :

shoot_sound.set_volume(0.3)
explode_sound.set_volume(0.7)

Showcase

Montre à un coach que :

  • Ton jeu marche en vrai pygame sans pgzero
  • Tu as ajouté du son (shoot, explode, hit, bg music)
  • Bonus : restart avec R ou mute avec M

À la prochaine !

« La prochaine fois : les POWER-UPS. Des boucliers, des speed-boosts et des tirs en éventail. Et ton vaisseau devient plus fort à mesure que tu survis plus longtemps. »

À emporter chez toi

Essaie une de ces extensions à la maison :

  1. Health bar — Remplace le texte « Vies : 3 » par une barre visuelle : dessine trois petits rectangles en haut.
  2. Pause — Ajoute une touche P qui met le jeu en pause. Mettre running = False ne suffit pas — utilise une variable paused séparée.
  3. Effet de particules — Fais gicler de petits points blancs autour d’une explosion (utilise une liste de particules qui rétrécissent de plus en plus).
  4. Ton propre skin — Remplace player_ship.png par ton propre design.

Télécharger Dojo Defender