5 mini-jeux Pygame étape par étape — Crée, joue, customise !
|

5 mini-jeux Pygame étape par étape — Crée, joue, customise !

Spread the love

Tu veux apprendre à créer des jeux rapidement, sans moteur lourd ? Parfait — voici 5 mini-jeux complets et expliqués pas à pas avec Pygame. Chaque jeu est minimal, prêt à lancer et facile à étendre. Je te donne le code, les commandes, les contrôles et des idées d’amélioration. Zéro blabla inutile, que du fun et du concret.

Avant de commencer
Installe Pygame :
pip install pygame
Puis sauvegarde chaque script dans un fichier .py (ex : pong.py) et exécute-le avec python pong.py.

Pong — le classique revisité (niveau : débutant)

But : garder la balle sur ton côté et marquer contre l’IA.

Contrôles

  • Z / S (ou UP/DOWN) pour monter/descendre.

Étapes rapides

  1. Crée fenêtre, paddles, balle.
  2. Gère mouvement et collisions.
  3. Ajoute score et reset après but.

Code (copier → lancer)

# pong.py - Pong minimal avec IA simple
import pygame, sys, random

pygame.init()
W, H = 800, 500
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("Pong - Mini")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 36)

P_W, P_H = 12, 90
p1 = pygame.Rect(20, H//2 - P_H//2, P_W, P_H)
p2 = pygame.Rect(W-32, H//2 - P_H//2, P_W, P_H)
ball = pygame.Rect(W//2-10, H//2-10, 20, 20)

p_speed = 6
ball_vx, ball_vy = random.choice([-5,5]), random.choice([-3,3])
score1 = score2 = 0

def reset_ball():
    global ball_vx, ball_vy
    ball.center = (W//2, H//2)
    ball_vx = random.choice([-5,5])
    ball_vy = random.choice([-4,4])

running = True
while running:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
    keys = pygame.key.get_pressed()
    if keys[pygame.K_z] or keys[pygame.K_UP]:
        p1.y -= p_speed
    if keys[pygame.K_s] or keys[pygame.K_DOWN]:
        p1.y += p_speed
    p1.y = max(0, min(H-P_H, p1.y))

    # IA simple : suivre la balle
    if p2.centery < ball.centery:
        p2.y += 4
    else:
        p2.y -= 4
    p2.y = max(0, min(H-P_H, p2.y))

    # Ball movement
    ball.x += ball_vx
    ball.y += ball_vy

    if ball.top <= 0 or ball.bottom >= H:
        ball_vy *= -1
    if ball.colliderect(p1) or ball.colliderect(p2):
        ball_vx *= -1

    # Score
    if ball.left <= 0:
        score2 += 1
        reset_ball()
    if ball.right >= W:
        score1 += 1
        reset_ball()

    screen.fill((10,10,30))
    pygame.draw.rect(screen, (200,200,200), p1)
    pygame.draw.rect(screen, (200,200,200), p2)
    pygame.draw.ellipse(screen, (255,200,0), ball)
    score_text = font.render(f"{score1}  -  {score2}", True, (200,200,200))
    screen.blit(score_text, (W//2 - score_text.get_width()//2, 10))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
sys.exit()

Extensions

  • Ajouter rebonds angulaires selon la partie du paddle touchée.
  • Mode deux joueurs local.
  • Power-ups (ball speed up / slow).

Snake — le serpent glouton (niveau : débutant)

But : manger la nourriture, grandir, éviter le mur et ton corps.

Contrôles

  • Flèches ou ZQSD selon ton clavier.

Principes

  • Grille régulière (taille bloc) pour simplifier la logique.
  • Corps = liste de segments.

Code

# snake.py - version simple
import pygame, sys, random

pygame.init()
W, H = 600, 400
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("Snake - Mini")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 36)

BLOCK = 20
def rnd():
    return random.randrange(0, W, BLOCK), random.randrange(0, H, BLOCK)

snake = [(BLOCK*5, BLOCK*5), (BLOCK*4, BLOCK*5)]
dx, dy = BLOCK, 0
food = rnd()
score = 0

running = True
while running:
    for e in pygame.event.get():
        if e.type == pygame.QUIT: running = False
        if e.type == pygame.KEYDOWN:
            if e.key == pygame.K_LEFT and dx == 0:
                dx, dy = -BLOCK, 0
            if e.key == pygame.K_RIGHT and dx == 0:
                dx, dy = BLOCK, 0
            if e.key == pygame.K_UP and dy == 0:
                dx, dy = 0, -BLOCK
            if e.key == pygame.K_DOWN and dy == 0:
                dx, dy = 0, BLOCK

    head = (snake[0][0] + dx, snake[0][1] + dy)
    snake.insert(0, head)
    if head == food:
        score += 1
        while True:
            food = rnd()
            if food not in snake: break
    else:
        snake.pop()

    # Collisions
    if (head[0] < 0 or head[0] >= W or head[1] < 0 or head[1] >= H or head in snake[1:]):
        print("Game Over. Score:", score)
        running = False

    screen.fill((0,0,0))
    for seg in snake:
        pygame.draw.rect(screen, (50,200,50), (*seg, BLOCK, BLOCK))
    pygame.draw.rect(screen, (200,50,50), (*food, BLOCK, BLOCK))
    score_surf = font.render(f"Score: {score}", True, (255,255,255))
    screen.blit(score_surf, (10,10))
    pygame.display.flip()
    clock.tick(10)

pygame.quit()
sys.exit()

Extensions

  • Portails, murs aléatoires, niveaux de vitesse progressifs, pause & save.

Breakout / Casse-briques (niveau : intermédiaire)

But : casser toutes les briques avec une balle qui rebondit sur ta raquette.

Contrôles

  • Gauche/Droite ou souris pour déplacer la raquette.

Notes

  • Liste de briques = liste de pygame.Rect, on supprime à la collision.

Code

# breakout.py - Casse-briques minimal
import pygame, sys, random

pygame.init()
W, H = 640, 480
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("Breakout - Mini")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 30)

paddle = pygame.Rect(W//2-60, H-30, 120, 12)
ball = pygame.Rect(W//2-8, H-50, 16, 16)
ball_vx, ball_vy = 4, -4

# Create bricks
rows, cols = 5, 8
brick_w = W // cols
bricks = []
for r in range(rows):
    for c in range(cols):
        rect = pygame.Rect(c*brick_w + 2, 40 + r*25, brick_w-4, 20)
        bricks.append(rect)

running = True
lives = 3
while running:
    for e in pygame.event.get():
        if e.type == pygame.QUIT: running = False
    mx = pygame.mouse.get_pos()[0]
    paddle.x = mx - paddle.width//2
    paddle.x = max(0, min(W-paddle.width, paddle.x))

    ball.x += ball_vx; ball.y += ball_vy
    if ball.left <= 0 or ball.right >= W:
        ball_vx *= -1
    if ball.top <= 0:
        ball_vy *= -1
    if ball.colliderect(paddle):
        ball_vy *= -1
        # add angle based on hit position
        offset = (ball.centerx - paddle.centerx) / (paddle.width/2)
        ball_vx = int(offset * 6)

    # Brick collision
    hit_index = ball.collidelist(bricks)
    if hit_index != -1:
        hit = bricks.pop(hit_index)
        ball_vy *= -1

    if ball.bottom >= H:
        lives -= 1
        ball.center = (W//2, H-60)
        ball_vx, ball_vy = random.choice([-4,4]), -4
        if lives <= 0:
            print("Game Over")
            running = False

    screen.fill((12,12,40))
    pygame.draw.ellipse(screen, (255,200,0), ball)
    pygame.draw.rect(screen, (200,200,200), paddle)
    for b in bricks:
        pygame.draw.rect(screen, (100,180,240), b)
    txt = font.render(f"Lives: {lives}  Bricks: {len(bricks)}", True, (255,255,255))
    screen.blit(txt, (10,10))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
sys.exit()

Extensions

  • Power-ups qui élargissent la raquette, balles multiples, niveaux.

Flappy-like (niveau : intermédiaire)

But : éviter les tuyaux en tapotant pour sauter.

Contrôles

  • SPACE pour sauter.

Principes

  • Gravité, impulsion de saut, tuyaux générés à intervalle régulier.

Code

# flappy.py - clone basique
import pygame, sys, random

pygame.init()
W, H = 400, 600
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("Flappy Mini")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 36)

x = 60
y = H//2
vel = 0
gravity = 0.6
jump = -10
pipes = []
SPAWN = pygame.USEREVENT + 1
pygame.time.set_timer(SPAWN, 1400)
gap = 140
speed = 3
score = 0

running = True
while running:
    for e in pygame.event.get():
        if e.type == pygame.QUIT: running = False
        if e.type == pygame.KEYDOWN and e.key == pygame.K_SPACE:
            vel = jump
        if e.type == SPAWN:
            h = random.randint(100, H-200)
            pipes.append([W, h])
    vel += gravity
    y += vel

    for p in pipes:
        p[0] -= speed

    # remove offscreen & score
    if pipes and pipes[0][0] < -100:
        pipes.pop(0)
        score += 1

    # Collision
    bird_rect = pygame.Rect(x-18, int(y)-18, 36, 36)
    for p in pipes:
        top = pygame.Rect(p[0], 0, 60, p[1])
        bot = pygame.Rect(p[0], p[1]+gap, 60, H - (p[1]+gap))
        if bird_rect.colliderect(top) or bird_rect.colliderect(bot):
            print("Game Over! Score:", score)
            running = False

    if y <= 0 or y >= H:
        print("Game Over! Score:", score)
        running = False

    screen.fill((80,200,250))
    # draw bird
    pygame.draw.circle(screen, (255,220,0), (x, int(y)), 18)
    # pipes
    for p in pipes:
        pygame.draw.rect(screen, (40,160,40), (p[0], 0, 60, p[1]))
        pygame.draw.rect(screen, (40,160,40), (p[0], p[1]+gap, 60, H - (p[1]+gap)))
    score_s = font.render(str(score), True, (255,255,255))
    screen.blit(score_s, (W//2 - score_s.get_width()//2, 20))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
sys.exit()

Extensions

  • Ajoute animations, sons, effet de rotation de l’oiseau, tableau des meilleurs scores.

Memory / Jeu des paires (niveau : intermédiaire)

But : retrouver toutes les paires en retournant deux cartes à la fois.

Contrôles

  • Clique gauche pour retourner une carte.

Principes

  • Grille 4×4, paires de valeurs mélangées, délai pour retourner si différent.

Code

# memory.py - Memory (paires)
import pygame, sys, random, time

pygame.init()
W, H = 480, 480
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("Memory - Mini")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 36)

ROWS, COLS = 4, 4
CARD_W = W // COLS
values = list(range((ROWS*COLS)//2)) * 2
random.shuffle(values)

# state arrays
revealed = [False] * (ROWS*COLS)
matched = [False] * (ROWS*COLS)
first = second = -1
lock_time = 0

def idx_from_pos(mx, my):
    c = mx // CARD_W
    r = my // CARD_W
    return r*COLS + c

running = True
while running:
    for e in pygame.event.get():
        if e.type == pygame.QUIT: running = False
        if e.type == pygame.MOUSEBUTTONDOWN and e.button == 1:
            if lock_time and time.time() < lock_time:
                continue
            mx, my = e.pos
            i = idx_from_pos(mx, my)
            if matched[i] or revealed[i]: continue
            if first == -1:
                first = i; revealed[i] = True
            elif second == -1:
                second = i; revealed[i] = True
                if values[first] == values[second]:
                    matched[first] = matched[second] = True
                    first = second = -1
                else:
                    lock_time = time.time() + 0.8  # show for 0.8s
        # unlock after delay
    if lock_time and time.time() > lock_time:
        revealed[first] = revealed[second] = False
        first = second = -1
        lock_time = 0

    screen.fill((30,30,40))
    for i in range(ROWS*COLS):
        r, c = divmod(i, COLS)
        rect = pygame.Rect(c*CARD_W+6, r*CARD_W+6, CARD_W-12, CARD_W-12)
        if revealed[i] or matched[i]:
            txt = font.render(str(values[i]), True, (10,10,10))
            pygame.draw.rect(screen, (200,200,200), rect)
            screen.blit(txt, (rect.x + rect.w//2 - txt.get_width()//2, rect.y + rect.h//2 - txt.get_height()//2))
        else:
            pygame.draw.rect(screen, (80,120,200), rect)
    if all(matched):
        w = font.render("Bravo ! Tu as gagné.", True, (255,255,255))
        screen.blit(w, (W//2 - w.get_width()//2, H//2 - 20))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
sys.exit()

Extensions

  • Remplacer les nombres par des images (cartes), ajouter timer, niveaux de difficulté (taille grille).

Conseils pratiques (pour tous les jeux)

  • Pas d’assets ? Dessine avec pygame.draw.* — c’est suffisant pour un prototype.
  • Sons : pygame.mixer.Sound("ping.wav") → joue un effet.
  • FPS : règle clock.tick() pour ajuster la difficulté.
  • Organisation : sépare les fichiers (assets, utils, niveaux) quand ton projet grandit.
  • Versionnage : utilise Git dès le début — tu remercieras ton futur toi.

Idées pour aller plus loin (freelance / portfolio)

  • Pack plusieurs mini-jeux dans un launcher + menu, sauvegarde du score → beau projet portfolio.
  • Prototypage rapide d’un jeu éducatif pour écoles (quiz gamifié).
  • Atelier “game jam” : adapte un des jeux en 48h et propose-le sur Itch.io.

Licence & assets

Tous les scripts ci-dessus sont libres pour usage personnel et apprentissage. Si tu utilises des images ou sons externes, vérifie les licences (Creative Commons, domaine public, ou crée-les toi-même).

Conclusion

Créer des mini-jeux avec Python et Pygame est une excellente façon d’apprendre à programmer tout en s’amusant. Que ce soit avec Pong, Snake ou encore un petit Flappy, chaque projet t’aide à développer ta logique, ta créativité et tes compétences techniques pas à pas.

Et si tu veux aller encore plus loin, sache qu’il est même possible de gagner de l’argent avec Python grâce à tes compétences. Pour découvrir comment, je t’invite à lire cet article 👉 Comment gagner de l’argent avec Python.

Similar Posts