Skip to content

Un jeu de snake avec Pyxel

Énoncé de l'exercice

Voici le PDF de l'énoncé de l'exercice comportant des trous, ainsi que la version corrigée de l'énoncé :

Correction

Voici le programme Python corrigé, comprenant de nombreux commentaires pour vous aider à comprendre le code :

import pyxel
from random import randint

# constantes de jeu (ne sont pas modifiées)
TITLE = "snake"
WIDTH = 200
HEIGHT = 160
CASE = 20
FRAME_REFRESH = 10  # Gère la vitesse de jeu

# initialiser l'application Pyxel
pyxel.init(WIDTH, HEIGHT, title=TITLE)

# variables globales pouvant être modifiées
snake = [[3,3], [2,3], [1,3]]  # position de chaque élément du snake
head = snake[0]  # la tête du serpent
food = [8, 3]  # position de la nourriture
direction = [1,0]  # direction du snake
score = 0  # score

def update():
    # Le mot-clé "global" permet d'autoriser la modification de variables globales
    global direction
    global score
    global food
    global head

    # Permet de n'effectuer un déplacement que toutes les 10 frames
    # (cette valeur peut être modifiée dans la variable globale FRAME_REFRESH)
    if pyxel.frame_count % FRAME_REFRESH == 0:
        head = [snake[0][0] + direction[0], snake[0][1] + direction[1]]
        # insérer la tête au début
        snake.insert(0, head)

        # effacer le dernier élément de snake :
        snake.pop()

    # En cas d'appui sur une touche : Changer direction du snake
    if pyxel.btn(pyxel.KEY_ESCAPE):
        exit()
    elif pyxel.btn(pyxel.KEY_RIGHT) and direction in ([0, 1], [0, -1]):
        direction = [1, 0]
    elif pyxel.btn(pyxel.KEY_LEFT) and direction in ([0, 1], [0, -1]):
        direction = [-1, 0]
    elif pyxel.btn(pyxel.KEY_UP) and direction in ([1, 0], [-1, 0]):
        direction = [0, -1]
    elif pyxel.btn(pyxel.KEY_DOWN) and direction in ([1, 0], [-1, 0]):
        direction = [0, 1]

    # Faire mourir le snake s'il se touche lui-même ou sort de la zone
    if head in snake[1:] \
       or head[0] < 0 \
       or head[0] > WIDTH/CASE - 1 \
       or head[1] < 0 \
       or head[1] > HEIGHT/CASE - 1:
        exit()

    # Lorsque la tête du snake touche une nourriture
    if head == food:  # si la position de la tête = la position de la nourriture
        score += 1
        # replacer la nourriture tant qu'elle est sur le snake
        while food in snake:
            food = [randint(0, WIDTH/CASE - 1), randint(0, HEIGHT/CASE - 1)]

def draw():
    # l'écran : à effacer puis remplir de noir
    pyxel.cls(0)

    # afficher le scoe en couleur blanche
    pyxel.text(4, 4, f"SCORE : {score}", 7)

    # dessiner le corps en vert
    for anneau in snake[1:]:
        x, y = anneau[0], anneau[1]
        # 11 est une couleur un peu verte
        pyxel.rect(x * CASE, y * CASE, CASE, CASE, 11)

    # dessiner la tête en orange
    x_head, y_head = snake[0]  # récupérer position (x, y) de la tête
    pyxel.rect(x_head * CASE, y_head * CASE, CASE, CASE, 9)  # 9 est la couleur orange

    # dessiner la nourriture
    x_food, y_food = food
    pyxel.rect(x_food * CASE, y_food * CASE, CASE, CASE, 8)  # 8 est la couleur rose

pyxel.run(update, draw)  # exécuter le jeu

Télécharger ce programme

Une version améliorée

Voici une version améliorée du jeu dans laquelle :

  • on a agrandit la fenêtre de jeu,
  • à chaque nourriture mangée, la queue du snake augmente d'un élément,
  • on accélère la vitesse de déplacement du snake toutes les 5 nourritures mangées.

Télécharger ce programme

Pistes d'amélioration

On pourrait améliorer davantage le jeu, par exemple :

  • en faisant en sorte qu'en sortant de l'écran d'un côté, le snake réapparaisse de l'autre côté,
  • en ajoutant un écran de "Game Over" en cas d'échec,
  • en créant un système de niveaux de plus en plus durs et en y ajoutant des obstacles,
  • etc.