Les mécaniques de jeu⚓︎
Game Over⚓︎
Modification pour rajouter les Game Overs
Actuellement, le sol est considéré comme n'importe quel autre mur. Nous allons modifier le comportement pour que la balle revienne sur la raquette et qu'elle soit lancée en appuyant sur le bouton gauche de la souris. Pour cela, on rajoute un attribut à la balle indiquant si elle est collée à la raquette ou pas.
class Balle:
...
def __init__(self):
self.x, self.y = (400, 400)
self.vitesse = 8 # vitesse initiale
self.vitesse_par_angle(60) # vecteur vitesse
self.sur_raquette = True # rajouter cette ligne
def deplacer(self, raquette):
if self.sur_raquette: # rajouter cette ligne
self.y = raquette.y - 2*RAYON_BALLE # rajouter cette ligne
self.x = raquette.x # rajouter cette ligne
else: # rajouter cette ligne
self.x += self.vx # décaler toutes les lignes
self.y += self.vy # suivantes
if raquette.collision_balle(self) and self.vy > 0:
self.rebond_raquette(raquette)
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.sur_raquette = True
if self.y - RAYON_BALLE < YMIN:
self.vy = -self.vy
class Jeu:
...
def gestion_evenements(self): # rajouter la partie après le elif
# Gestion des evenements
for event in pygame.event.get():
if event.type == pygame.QUIT: sys.exit() # Pour quitter
elif event.type == pygame.MOUSEBUTTONDOWN: # On vient de cliquer
if event.button == 1: # Bouton gauche
if self.balle.sur_raquette:
self.balle.sur_raquette = False
self.balle.vitesse_par_angle(60)
Exercice 5
Faire les modifications et tester votre programme.
Les briques⚓︎
Le rebond sur les briques
Il faut maintenant ajouter les briques. Contrairement à la raquette, il faut regarder de quel côté tape la balle pour savoir s'il faut faire un rebond horizontal ou un rebond vertical. Pour cela, nous allons définir 4 zones autour de la brique afin de déterminer où se trouve la balle au niveau du rebond.
On commence par regarder si la balle se trouve à droite ou à gauche de la brique. On se place ensuite sur le point du côté correspondant de la brique se trouvant à égale distance du haut, du bas et du côté de la brique. On regarde l'écart qu'il y a entre ce point et le centre de la balle. Selon la coordonnée la plus grande de ce vecteur, en valeur absolue, on peut déterminer si la balle se trouve sur les côtés ou en haut ou en bas de la brique.
La classe Brique
Il faut insérer cette classe avant la classe Jeu
.
class Brique: # Rajouter cette classe avant Jeu
def __init__(self, x, y):
self.x = x
self.y = y
self.vie = 1
self.longueur = 5 * RAYON_BALLE
self.largeur = 3 * RAYON_BALLE
def en_vie(self):
return self.vie > 0
def afficher(self):
pygame.draw.rect(screen, BLANC, (int(self.x-self.longueur/2),
int(self.y-self.largeur/2),
self.longueur, self.largeur), 0)
def collision_balle(self, balle):
# on suppose que largeur<longueur
marge = self.largeur/2 + RAYON_BALLE
dy = balle.y - self.y
touche = False
if balle.x >= self.x: # on regarde a droite
dx = balle.x - (self.x + self.longueur/2 - self.largeur/2)
if abs(dy) <= marge and dx <= marge: # on touche
touche = True
if dx <= abs(dy):
balle.rebondx = True
else: # a droite
balle.rebondy = True
else: # on regarde a gauche
dx = balle.x - (self.x - self.longueur/2 + self.largeur/2)
if abs(dy) <= marge and -dx <= marge: # on touche
touche = True
if -dx <= abs(dy):
balle.rebondx = True
else: # a gauche
balle.rebondy = True
if touche:
self.vie -= 1
return touche
Modification de la classe Balle
Il faut aussi modifier la balle pour qu'elle effectue le rebond indiqué au prochain déplacement. Cela permet de bien faire rebondir la balle correctement lorsqu'elle rentre en collision avec plusieurs briques en même temps.
class Balle:
...
def __init__(self):
...
self.rebondx = False
self.rebondy = False
def deplacer(self, raquette):
if self.sur_raquette:
self.y = raquette.y - 2*RAYON_BALLE
self.x = raquette.x
else:
if self.rebondx:
self.vy = -self.vy
self.rebondx = False
if self.rebondy:
self.vx = -self.vx
self.rebondy = False
self.x += self.vx
self.y += self.vy
...
Modification de la classe Jeu
Pour l'instant nous n'allons mettre qu'une seule brique afin de vérifier que cela fonctionne.
class Jeu:
def __init__(self):
self.balle = Balle()
self.raquette = Raquette()
self.briques = [Brique(400, 100)] # rajouter cette ligne
def mise_a_jour(self):
x, y = pygame.mouse.get_pos()
self.balle.deplacer(self.raquette)
for brique in self.briques: # rajouter ces 3 lignes
if brique.en_vie():
brique.collision_balle(self.balle)
self.raquette.deplacer(x)
def affichage(self):
screen.fill(NOIR) # on efface l'écran
self.balle.afficher()
self.raquette.afficher()
for brique in self.briques: # rajouter ces 3 lignes
if brique.en_vie():
brique.afficher()
Exercice 6
Rajouter la classe Brique
et tester la nouvelle version du jeu.
Précision des collisions
Il se peut que les rebonds ne soient pas ceux attendus, surtout lorsque la balle arrive presque perpendiculairement à un des angles. Il faudrait utiliser une méthode plus précise pour déterminer le côté de la brique qui est tapé en premier.