Aller au contenu

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.