Gérer une collision avec Python

Bonjour,

Je me tourne vers vous car j'ai encore du mal avec mon programme. J'aimerais utiliser le principe de collision avec Pygame. J'ai déjà défini ma collision comme ceci:

def check_collision(self, sprite, group):
          return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask)


Mais je ne parviens pas à l'utiliser avec des classes héritées. Je vous mets le programme ci-dessous (il est assez conséquent) :

import pygame
import math
import random
pygame.init()

#creer une classe qui represente le jeu
class Game:
     def __init__(self):
          #gerer le son
          self.sound_manager = SoundManager()
          #définir si le jeu a commencé
          self.is_playing = False
          #générer notre joueur
          self.all_players = pygame.sprite.Group()
          self.player = Player(self)
          self.all_players.add(self.player)
          #generer l'evenement
          self.comet_event = CometFallEvent(self)
          #groupe de monstre
          #metre le score à 0
          self.font = pygame.font.Font('images/Ramaraja-Regular.ttf',30)
          self.score = 0
          self.pressed = {}

     def start(self):
          self.is_playing = True
          #pygame.mixer.pause()
          #self.sound_manager.play('jeu_fond')
          
     def add_score(self, points):
          self.score += points
     
     def game_over(self):
          #remettre le jeu à neuf
          self.player.health = self.player.max_health
          self.is_playing = False
          self.score = 0
          #jouer le son
          pygame.mixer.pause()
          self.sound_manager.play('game_over')

     def update (self, screen):
          #afficher le score sur l'ecran
          score_text = self.font.render(f"Score : {self.score}",1,(255,255,255))

          screen.blit(score_text, (20, 20))
          #appliquer l'image du joueur sur la fenetre de jeu
          screen.blit(self.player.image, self.player.rect)

          #actualiser la barre d'evenement du jeu
          self.comet_event.update_bar(screen)
         
          #récupérer les projectiles de mon joueur
          for nucleotide in self.player.all_nucleotides:
               nucleotide.move()

          #recuperer les comètes du jeu
          for comet in self.comet_event.all_comets:
               comet.fall()

          #actualiser la barre de vie du joueur
          self.player.update_health_bar(screen)

          #appliquer l'ensemble des images de mon groupe de projectile
          self.player.all_nucleotides.draw(screen)

          #appliquer l'ensemble des image du groupe de cometes
          self.comet_event.all_comets.draw(screen)

          #verifier si mon joueur souhaite aller à gauche ou à droite
          if self.pressed.get(pygame.K_RIGHT) and self.player.rect.x + self.player.rect.width < 1080:
               self.player.move_right()
          elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0:
               self.player.move_left()
          #verifier que les bons nucleotides se touchent
          if self.check_collision(
                self.player.ARNAdenine, self.comet_event.Thymine
          ):
               self.remove()
     
     def check_collision(self, sprite, group):
          return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask)

#definir une classe de généralité
class AnimateSprite (pygame.sprite.Sprite):
     #définir les choses à faire à la création de l'entité
     def __init__(self, sprite_name):
          super().__init__()
          self.image = pygame.image.load(f'images/{sprite_name}.png')

class SoundManager:
     def __init__(self):
          self.sounds = {
               'click' : pygame.mixer.Sound('images/click.ogg'),
               'game_over' : pygame.mixer.Sound('images/game_over.ogg'),
               'jeu_fond' : pygame.mixer.Sound('images/jeu.wav'),
               'demarrage' : pygame.mixer.Sound('images/fond Chris Brown.wav')
               }

     def play(self, name):
          self.sounds[name].play()

class Nucleotide (AnimateSprite):
     #definir le constructeur de la classe
     def __init__(self, player, name):
          super().__init__(name)
          self.velocity = 5
          self.player = player
          self.image = pygame.transform.scale(self.image,(150,150))
          self.rect = self.image.get_rect()
          self.rect.x = player.rect.x + 50
          self.rect.y = player.rect.y - 100
          self.game = Game ()            

     def remove(self):
          self.game.player.all_nucleotides.remove(self)

     def move(self):
          self.rect.y -= self.velocity

          if self.rect.x > 1000:
               #supprimer le projectile (en dehors de l'ecran)
               self.remove()
               self.player.damage(15)

#définir unr classe pour la thymine lancée
class ARNUracile (Nucleotide):
     def __init__(self, player):
          super().__init__(player, "uracile arn")
#définir unr classe pour la thymine lancée
class ARNGuanine (Nucleotide):
     def __init__(self, player):
          super().__init__(player, "guanine arn")
#définir unr classe pour la thymine lancée
class ARNAdenine (Nucleotide):
     def __init__(self, player):
          super().__init__(player, "adenine arn")
#définir unr classe pour la thymine lancée
class ARNCytosine (Nucleotide):
     def __init__(self, player):
          super().__init__(player, "cytosine arn")
       
#créer une première classe qui représente le joueur
class Player (pygame.sprite.Sprite):
     def __init__(self, game):
        super().__init__()
        self.game = game
        self.health = 100
        self.max_health = 100
        self.attack = 10
        self.velocity = 5
        self.all_nucleotides = pygame.sprite.Group()
        self.image = pygame.image.load("images/personnage.png")
        self.rect = self.image.get_rect()
        self.rect.x = 400
        self.rect.y = 400

     def damage(self, amount):
          if self.health - amount > amount :
               self.health -= amount
          else:
               #si le joueur a plus de point de vie
               self.game.game_over()
          
     def update_health_bar(self, surface):
          #la barre noire
          pygame.draw.rect(surface, (0,0,0), [self.rect.x + 80, self.rect.y +20, self.max_health, 5] )
          #faire la barre verte
          pygame.draw.rect(surface, (111,210,46), [self.rect.x + 80, self.rect.y +20, self.health,5 ] )

     def launch_projectile(self, nucleotide_name):
          self.all_nucleotides.add(nucleotide_name.__call__(self))
          
     def move_right(self):
          self.rect.x += self.velocity

     def move_left(self):
          self.rect.x -= self.velocity

class CometFallEvent:
    #lors du chargement on doit creer un compteur
    def __init__(self, game):
        self.percent = 0
        self.percent_speed = 5
        self.game = game
        global Thymine
        comet = Thymine(CometFallEvent)
        Thymine = Thymine(comet)

        #definir un groupe pour stocker les comètes
        self.all_comets = pygame.sprite.Group()

    def add_percent(self):
        self.percent+= self.percent_speed/ 10

    def is_full_loaded(self):
        return self.percent>=100

    def reset_percent (self):
        self.percent = 0

    def meteor_fall(self):
        #faire apparaitre une premiere boule de feu
        type_comet = random.randint(1, 4)
        if type_comet == 4:
             self.all_comets.add(Thymine(self))
        if type_comet == 3:
             self.all_comets.add(Adenine(self))
        if type_comet == 2:
             self.all_comets.add(Guanine(self))
        if type_comet == 1:
             self.all_comets.add(Cytosine(self))

    def attempt_fall(self):
        #la jauge d'evenement est totalement chargée
        if self.is_full_loaded():
             self.meteor_fall()
             self.reset_percent()

    def update_bar(self, surface):

        #ajouter du pourcentage à la barre
        self.add_percent()

        # appelle de la methode pour essayer de declencher la pluie de comete
        self.attempt_fall()
        
        #la barre noir d'arriere plan
        pygame.draw.rect(surface, (0,0,0), [
            0,
            surface.get_height()-40, 
            surface.get_width(),  
            10
        ])

        #la barre rouge en jauge
        pygame.draw.rect(surface, (187,11,11), [
            0,
            surface.get_height()-40, 
            (surface.get_width()/ 100) * self.percent, 
        10
        ])

    
#creer une classe pour gerer les boules de feu 
class Comet (AnimateSprite) :

    def __init__(self, CometFallEvent, name):
        super().__init__(name)
        #definir quelle est l'image associé à cette comète
        self.image = pygame.transform.scale(self.image, (150,150))
        self.rect = self.image.get_rect()
        self.velocity = random.randint(1,3)
        self.rect.x = random.randint(20, 800)
        self.rect.y = - random.randint(0, 800)
        self.comet_event = CometFallEvent 

    def remove (self):
        self.comet_event.all_comets.remove(self)
        

    def fall(self):
        self.rect.y +=self.velocity

        #ne tombe pas sur le sol
        if self.rect.y >= 500:
             #supprimer la comète
             self.remove()
             self.comet_event.game.player.damage(15)

         #verifier si la boule de feu touche le nucléotide
        if self.comet_event.game.check_collision(
              self, self.comet_event.game.player.all_nucleotides
        ):
           self.remove()
           #ajouter les points
           self.comet_event.game.add_score(20)
           

#definir une classe pour chaque nucleotide qui tombe du ciel
class Thymine(Comet):

     def __init__(self, game):
          super().__init__(game,"thymine ciel")
          if self.comet.comet_event.game.check_collision(
              self, self.game.player.ARNAdenine
          ):
               self.remove()
class Cytosine(Comet):

     def __init__(self, game):
          super().__init__(game,"cytosine ciel")

class Guanine(Comet):

     def __init__(self, game):
          super().__init__(game,"guanine ciel")
class Adenine(Comet):

     def __init__(self, game):
          super().__init__(game,"adenine ciel")


#charger notre jeu
game= Game()
sound_manager = SoundManager()

#generer la fenetre de jeu
pygame.display.set_caption("Arn Polymérase")
screen = pygame.display.set_mode((1080,720))

# importer charger notre bouton  pour lancer la partie
play_button = pygame.image.load("images/bouton play.jpg")
play_button = pygame.transform.scale(play_button, (400,150))
play_button_rect = play_button.get_rect()
play_button_rect.x = math.ceil(screen.get_width() / 3.33)
play_button_rect.y = math.ceil(screen.get_height() / 2)

#importer de charger l'arrière plan de notre plan
background = pygame.image.load("images/fond.jpg")

#modifier la taille de l'arrière plan
background = pygame.transform.scale(background, (1080, 720))


running = True

#boucle tant que cette condition est vrai
while running:

     #appliquer l'arrière plan du jeu
     screen.blit(background,(0, 0))

     #verifier si le jeu a commence 
     if game.is_playing == True:
        #déclencher les instructions de la partie
        game.update(screen)
     #verifier si notre jeu n'a pas commencé
     else:
        #ajouter mon écran de bienvenue
        screen.blit (play_button, play_button_rect)
        
     #mettre a jour l'écran
     pygame.display.flip()

     #si le joueur ferme cette fenêtre
     for event in pygame.event.get():
          #que l'evenement est fermeture de fenetre
          if event.type == pygame.QUIT:
             running = False
             pygame.mixer.pause()
             pygame.quit()
          #detecter si un joueur lache une touche du clavier   
          elif event.type == pygame.KEYDOWN:
               game.pressed[event.key] = True
               if event.key == pygame.K_a:
                    game.player.launch_projectile(ARNAdenine)
               if event.key == pygame.K_g:
                    game.player.launch_projectile(ARNGuanine)
               if event.key == pygame.K_c:
                    game.player.launch_projectile(ARNCytosine)
               if event.key == pygame.K_u:
                    game.player.launch_projectile(ARNUracile)
                
          elif event.type == pygame.KEYUP:
               game.pressed[event.key] = False

          elif event.type ==pygame.MOUSEBUTTONDOWN:
            #verification pour savoir si la souris touche le bouton play
            if play_button_rect.collidepoint(event.pos):
                #mettre le jeu en mode joué
                game.start()
                #jouer le son
                game.sound_manager.play('click')
                pygame.mixer.pause()


J'aimerais par exemple enlever l'image de ARNAdenine et de Thymine quand ils sont en collision. Mais je ne sais pas vraiment comment m'y prendre

Merci d'avance de votre aide.

1 réponse

  1. Modérateur
    Bonjour,

    Merci d'essayer de partager un code reproductible : ici une large partie de ton code n'a rien à voir avec ton problème et on ne peut pas reproduire ce que fait ton programme car on n'a pas les fichiers nécessaire à son lancement (images, son...).

    Pour démarrer tu peux regarder cette vidéo.

    Bonne chance
    0