Gérer une collision avec Python

Fermé
Lulila - Modifié le 30 mars 2022 à 14:08
mamiemando Messages postés 33346 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 8 novembre 2024 - 30 mars 2022 à 14:11
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.
A voir également:

1 réponse

mamiemando Messages postés 33346 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 8 novembre 2024 7 803
Modifié le 30 mars 2022 à 14:12
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