Aller au contenu

La balle⚓︎

Le début du fichier

Nous allons commencer par mettre en place les bases de l'affichage et les rebonds de la balle sur les bords.

Dans un fichier \py{casse-briques.py}, recopier les lignes suivantes :

import random # Pour les tirages aleatoires
import sys # Pour quitter proprement
import pygame # Le module Pygame
import pygame.freetype # Pour afficher du texte
import math

pygame.init() # initialisation de Pygame

# Pour le texte.
pygame.freetype.init()
myfont=pygame.freetype.SysFont(None, 20) # texte de taille 20

# Taille de la fenetre
width, height = 800, 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Ping")

# Pour limiter le nombre d'images par seconde
clock=pygame.time.Clock() 

BLANC = (255, 255, 255)
NOIR = (0, 0, 0)

RAYON_BALLE = 10
XMIN, YMIN = 0, 0
XMAX, YMAX = width, height

Les premières lignes servent à inporter et à configurer les différentes bibliothèques, dont pygame. Les dernières servent à définir les constantes.

Les coordonnées

Les coordonnées utilisées par pygame sont exprimées en pixels. L'origine du repère se trouve en haut à gauche de l'écran, l'axe des abscisses va vers la droite et celui des ordonnées vers le bas. La balle se déplacera dans le rectangle dont le coin haut gauche est (XMIN, YMIN) et le coin bas droite est (XMAX, YMAX).

Pour l'instant nous allons utiliser l'ensemble de la surface disponible à l'écran.

La classe Balle

La balle est définie par la classe suivante :

class Balle:
    def vitesse_par_angle(self, angle):
        self.vx = self.vitesse * math.cos(math.radians(angle))
        self.vy = -self.vitesse * math.sin(math.radians(angle))

    def __init__(self):
        self.x, self.y = (400, 400)
        self.vitesse = 8 # vitesse initiale
        self.vitesse_par_angle(60) # vecteur vitesse

    def afficher(self):
        pygame.draw.rect(screen, BLANC,
                         (int(self.x-RAYON_BALLE), int(self.y-RAYON_BALLE),
                          2*RAYON_BALLE, 2*RAYON_BALLE), 0)

    def deplacer(self):
        self.x += self.vx
        self.y += self.vy
        if self.x + RAYON_BALLE > XMAX:
            self.vx = -self.vx
        if self.x - RAYON_BALLE < XMIN:
            self.vx = -self.vx
        if self.y + RAYON_BALLE > YMAX:
            self.vy = -self.vy
        if self.y - RAYON_BALLE < YMIN:
            self.vy = -self.vy

Une balle est définie par 5 attributs : x et y pour sa position, vx et vy pour le vecteur de déplacement, dont la norme est vitesse. À chaque étape, la balle avance de vx sur les abscisses et de vy sur les ordonnées.

Afin de calculer le vecteur initial, il faut faire un peu de trigonométrie. Les fonctions cos et sin de math prennent des angles exprimées en radians, c'est pourquoi il faut les convertir.

Les ordonnées étant orientées vers le bas, il faut prendre l'opposé de l'ordonnée du vecteur pour avoir les angles dans le sens trigonométrique classique.

Rebonds contre les murs

Pour l'affichage, nous nous contentons d'un rectangle blanc centré en (x, y) et dont le côté mesure \(2\times\)RAYON_BALLE.

Lorsqu'on met à jour la position de la balle, on vérifie si elle rebondit contre un des murs de la zone. Pour cela, il faut juste vérifier si le bord droit de la balle dépasse XMAX, le bord gauche est inférieur à XMIN... Selon les cas, on prend l'opposé de vx ou de vy.

La classe Jeu

Afin de voir évoluer la balle, nous rajoutons une classe Jeu qui s'occupera de la boucle principale du jeu :

class Jeu:        
    def __init__(self):
        self.balle = Balle()

    def gestion_evenements(self):
        # Gestion des evenements
        for event in pygame.event.get():
            if event.type == pygame.QUIT: sys.exit() # Pour quitter

    def mise_a_jour(self):
        self.balle.deplacer()

    def affichage(self):
        screen.fill(NOIR) # on efface l'écran
        self.balle.afficher()

Cette classe servira à gérer les actions du joueur, les interactions entre les éléments et à afficher la nouvelle image. Pour l'instant la seule action que peut faire le joueur est de quitter en cliquant sur la croix de la fenêtre. La balle qui rebondit sur les bords de la fenêtre est le seul élément à l'écran.

La fin du programme

Pour finir le programme, il faut rajouter les lignes suivantes :

jeu = Jeu()

while True:
    jeu.gestion_evenements()
    jeu.mise_a_jour()
    jeu.affichage()

    pygame.display.flip() # envoi de l'image à la carte graphique
    clock.tick(60) # on attend pour ne pas dépasser 60 images/seconde
Exercice 1

Recopier les différentes parties dans votre fichier et vérifier que la balle rebondit bien contre les bords.