Aller au contenu

CHAPITRE 5


Dessiner⚓︎

Il est temps de dessiner des carrés pour visualiser notre serpent. Pygame offre une méthode draw.rect pour dessiner des rectangles. La syntaxe est la suivante :

pygame.draw.rect(surface, couleur, rectangle)

Où :

  • surface est la surface où dessiner (pour nous, ce sera l'ecran)
  • couleur est une couleur nous y reviendrons
  • rectangle est un rectangle pygame qu'il va falloir construire

Des objets Pygame courants⚓︎

Un rectangle⚓︎

Pygame offre un objet Rect qui se construit par pygame.Rect et en fournissant les coordonnées du point supérieur gauche ainsi que les dimensions : pygame.Rect(x, y, largeur, hauteur).

Une couleur⚓︎

Il existe un objet Color de pygame qui construit une couleur si on lui passe un triplet (R, V, B) (les valeurs décimales entre 0 et 255 représentant des quantités de rouge, de vert et de bleu) ou bien un quadruplet : la 4e composante étant la transparence.

Par exemple, pygame.Color(0, 0, 0) correspond à la couleur noir. Depuis pygame 2.0 on peut aussi donner le nom d'une couleur (une simple chaine de caractères). Un tableau des couleurs est disponible sur htmlcolorcodes

On peut aussi, par souci de compatibilité, créer une couleur par pygame.Color en lui passant un nom.

Voici les couleurs que nous allons utiliser (à mettre dans constantes.py bien sûr) :

COULEUR_TETE = pygame.Color('lightcoral')
COULEUR_CORPS = pygame.Color('lightslategrey')
COULEUR_FOND = pygame.Color('sienna')

Le serpent prend forme⚓︎

Comment notre serpent se dessine-t-il ? C'est assez simple : parcourir chacune des coordonnées du tableau de positions, calculer les coordonnées en pixels correspondantes et dessiner un carré de SIZE x SIZE à cet endroit.

class Serpent:
    ...
    def se_dessine(self):
        for coords in self.pos:
            px, py = xy_vers_pixels(coords)
            pygame.draw.rect(self.ecran, COULEUR_CORPS, pygame.Rect(px, py, SIZE, SIZE))
        px, py = xy_vers_pixels(self.pos[self.tete]) 
        pygame.draw.rect(self.ecran, COULEUR_TETE, pygame.Rect(px, py, SIZE, SIZE))

xy_vers_pixels est une fonction à qui on passe un couple d'entiers, correspondants au numéro de ligne et de colonne d'un carré et qui calcule les coordonnées en pixels du coin supérieur gauche de ce carré.

Les concepts à revoir
  1. Définition d'une fonction
  2. Appel d'une fonction

Dès lors, le Jeu, dans sa boucle va demander à l'Arène (son interlocuteur) de se dessiner... et l'Arène s'exécute en demandant à son serpent de se dessiner :

class Jeu:
    ...
    def loop(self):
        fini = False
        while not fini:
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    fini = True
            self.arene.se_dessine()
        pygame.quit()

Et du côté de l'Arène :

class Arene:
    ...
    def se_dessine(self):
        self.serpent.se_dessine()

Si vous avez suivi et réalisé l'ensemble du code en l'exécutant vous avez constaté que l'écran reste noir. Il nous manque quelque chose : en présence d'interfaces graphiques, il faut explicitement gérer les rafraîchissements de l'écran dès qu'une action de dessin est faite.

Ceci se fait par pygame.display.flip().

Exercice⚓︎

À faire vous-même

Dans un fichier snake_07.py, faites évoluer votre jeu depuis le fichier précédent pour :

  1. Faire afficher le serpent ;
  2. Dans la partie start, avant de lancer la boucle de jeu, changer la couleur de fond en utilisant

    self.ecran.fill(COULEUR_FOND)
    
  3. Chercher dans la documentation de Pygame, comment changer le titre de la fenêtre. Voici ce que vous devriez obtenir :

    snake 01

import pygame
from constantes import *

def xy_vers_pixels(coords):
    x, y = coords
    return x * SIZE, y * SIZE

class Serpent:
    def __init__(self, arene):
        self.arene = arene
        self.ecran = arene.ecran
        self.pos = [(COLS//2 + i, ROWS//2) for i in range(-LENGTH//2, LENGTH//2)]
        self.tete = -1

    def se_dessine(self):
        for coords in self.pos:
            px, py = xy_vers_pixels(coords)
            pygame.draw.rect(self.ecran, COULEUR_CORPS, pygame.Rect(px, py, SIZE, SIZE))
        px, py = xy_vers_pixels(self.pos[self.tete]) 
        pygame.draw.rect(self.ecran, COULEUR_TETE, pygame.Rect(px, py, SIZE, SIZE))        

class Arene:
    def __init__(self, jeu):
        self.jeu = jeu
        self.ecran = jeu.ecran
        self.serpent = Serpent(self)

    def se_dessine(self):
        self.serpent.se_dessine()

class Jeu:
    def __init__(self):
        self.ecran = pygame.display.set_mode((LARGEUR, HAUTEUR)) 
        self.arene = Arene(self)   

    def start(self):
        pygame.init()
        pygame.display.set_caption('Another SNAKE game...')
        self.ecran.fill(COULEUR_FOND)
        self.loop()

    def loop(self):
        fini = False
        while not fini:
            for event in pygame.event.get():
                if event.type in (pygame.KEYDOWN, pygame.QUIT):
                    fini = True
            self.arene.se_dessine()
            pygame.display.flip()
        pygame.quit()    

snake_game = Jeu()
snake_game.start()
Retour en haut de la page