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.