Du mal avec Pygame et les collisions

Résolu
Bonjour,
J’ai un projet à rendre pour demain qui consiste à programmer un jeu donc j’ai utilisé le module pygame. Sauf que je rencontre un problème, alors que tout marchait très bien avant, le logiciel me demande sans cesse de mettre des arguments de position mais quand je les mets il y a quand même des erreurs. Je n’arrive pas trop aussi à gérer la notion de collision. Le programme est long donc je ne peux pas le mettre dans ce message. Mais si une personne a l’aimabilite de m’aider je lui enverrais

Configuration: iPhone / Safari 15.0

3 réponses

  1. Contributeur
    Bonjour,

    A moins que le programme fasse 10 000 lignes (et même dans ce cas), je vous conseillerais de le poster quand même parce que sur ce forum, l'aide se pratique sur les fils de posts et non en message privé (d'ailleurs inaccessible aux non-membres, ce qui est votre cas).

    voir la charte:

    https://www.commentcamarche.net/infos/25845-charte-d-utilisation-de-commentcamarche-net/

    Par ailleurs, veillez à utiliser les balises de code pour que les intervenants n'aient pas à recopier votre script (surtout s'il est long) et le cas échéant joignez le(s) message(s) d'erreur(s) que vous avez relevé(s).

    https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code

    Enfin, pour demain laisse peu de latitude car les bénévoles spécialistes de pygame ou python ne sont peut-être pas connectés ou disponibles en permanence.
    0
    1. Effectivement je ne savais pas qu'il était impossible de communiquer par message privé lorsqu'on est pas membre.
      Je vous joins donc le code:
      import pygame
      import math
      import random
      pygame.init()
      
      #creer une classe qui represente le jeu
      class Game:
      
          def __init__(self, player):
              #définir si le jeu a commencé
              self.is_playing = False
              #générer notre joueur
              self.player = Player()
              #generer l'evenement
              self.comet_event = CometFallEvent(self)
              self.nucleotide = Nucleotide()
           
              self.pressed = {}
      
          def start(self):
              self.is_playing = True
      
          def game_over(self):
              #remettre le jeu à neuf
              self.player.health = self.player.max_health
              self.is_playing = False
      
          def check_collision(self, sprite, group):
              return pygame.sprite.spritecollide(sprite, group, dokill, pygame.sprite.collide)
          
      
      
          def update(self, screen):
              #appliquer l'image de mon joueur
              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 game.player.all_nucleotides:
                  nucleotide.move()
      
              #recuperer les comètes du jeu
              for comet in self.comet_event.all_comets:
                  comet.fall()
      
              #appliquer l'ensemble des images de mon grouoe 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()
                          
          
              
              
      
      #créer une première classe qui représente le joueur
      class Player (pygame.sprite.Sprite):
      
          def __init__(self):
              super().__init__()
              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):
              self.health -= amount
      
      
      
          def launch_nucleotide(self):
              #creer une nouvelle instance de la classe projectile
              self.all_nucleotides.add(Nucleotide(self))
              
          def launch_nucleotideb(self):
              #creer une nouvelle instance de la classe projectile
              self.all_nucleotides.add(Nucleotideb(self))
      
          def launch_nucleotidec(self):
              #creer une nouvelle instance de la classe projectile
              self.all_nucleotides.add(Nucleotidec(self))
      
          def launch_nucleotided(self):
              #creer une nouvelle instance de la classe projectile
              self.all_nucleotides.add(Nucleotided(self))
      
          def launch_nucleotidee(self):
              #creer une nouvelle instance de la classe projectile
              self.all_nucleotides.add(Nucleotidee(self))
      
      
          def start(self):
              self.is_playing = True
      
          def game_over(self):
              #remettre le jeu à neuf
              self.player.health = self.player.max_health
              self.is_playing = False
      
          #verifier si le nombre de point de vie est superieure ou egal a 0
              if self.health <=0:
                  self.is_playing = False
                  self.player.health = self.player.max_health
      
          
      
          def move_right(self):
              self.rect.x += self.velocity
      
          def move_left(self):
              self.rect.x -= self.velocity
      
          def update_health_bar(self, surface):
              #la barre noire
              pygame.draw.rect(surface, (0,0,0), [self.rect.x + 65, self.rect.y +20, self.max_health, 5] )
              #faire la barre verte
              pygame.draw.rect(surface, (111,210,46), [self.rect.x + 65, self.rect.y + 20, self.health,5 ] )
          
             
              
      
      #creer une classe pour gerer les boules de feu 
      class Comet (pygame.sprite.Sprite) :
      
          def __init__(self,comet_event):
              super().__init__()
              #definir quelle est l'image associé à cette comète
              name=0
              alea = random.randint(1,4)
              if alea ==1:
                  self.image1 = pygame.image.load('images/thymine ciel.png')
                  name1 = 'ttombe'
              elif alea==2:
                  self.image2 = pygame.image.load('images/adenine ciel.png')
                  name2 = 'ctombe'
              elif alea==3:
                  self.image3 = pygame.image.load('images/cytosine ciel.png')
                  name3 = 'gtombe'
              elif alea==4:
                  self.image4 = pygame.image.load('images/guanine ciel.png')
                  name4 = 'atombe'
              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 = comet_event
      
          def remove (self):
              self.comet_event.all_comets.remove(self)
              
      
          def fall(self):
              self.rect.y +=self.velocity
      
      
                  #verifier si la boule de feu touche  le joueur
         # if self.comet_event.check_collision(self, self.comet_event.game.all_nucleotides):
              #print ("joueur touché")
              #retirer la boule de feu
              #self.remove()
              #subir 20 points de degats
              #self.comet_event.game.player.damage(20)
      
                       
                  
                  
      
      #creer une classe pou gerer cet evenement 
      class CometFallEvent:
          #lors du chargement on doit creer un compteur
          def __init__(self, game):
              self.percent = 0
              self.game = Game()
      
              #definir un groupe pour stocker les comètes
              self. all_comets = pygame.sprite.Group()
      
          def add_percent(self):
              self.percent+= 1
      
          def is_full_loaded(self):
              return self.percent>=100
      
          def reset_percent (self):
              self.percent = 0
      
          def check_collision(self, sprite, group):
              return pygame.sprite.spritecollide(sprite, group, dokill, pygame.sprite.collide)
      
          def meteor_fall(self):
              #faire apparaitre une premiere boule de feu
              self.all_comets.add(Comet(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
              ])
          
      
      #definir la classe qui va gerer les nucleotides de l'Arn
      class Nucleotide (pygame.sprite.Sprite):
      
          #definir le constructeur de la classe
          def __init__(self, player):
              super().__init__()
              self.velocity = 5
              self.player = player
              self.image = pygame.image.load("images/adenine arn.png")
              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 check_collision(self, sprite, group):
              return pygame.sprite.spritecollide(sprite, group, dokill, pygame.sprite.collide)
      
          def abandon(self):
              if not self.game.check.collision(self, self.comet) or self.rect.x> 1080:
                   self.remove()
      
                  
      
          def remove(self):
              self.player.all_nucleotides.remove(self)
      
          def move(self):
              self.rect.y -= self.velocity
      
             
      class Nucleotideb (pygame.sprite.Sprite):
      
          #definir le constructeur de la classe
          def __init__(self, player):
              super().__init__()
              self.velocity = 5
              self.player = player
              self.image = pygame.image.load("images/thymine arn.png")
              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
      
          def remove(self):
              self.player.all_nucleotides.remove(self)
      
          def move(self):
              self.rect.y -= self.velocity
      
              #verifier si le projectile n'est plus present sur l'écran
              if self.rect.x > 1080:
                  #supprimer le projectile
                  self.remove()
      
      class Nucleotidec (pygame.sprite.Sprite):
      
          #definir le constructeur de la classe
          def __init__(self, player):
              super().__init__()
              self.velocity = 5
              self.player = player
              self.image = pygame.image.load("images/cytosine arn.png")
              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
      
          def remove(self):
              self.player.all_nucleotides.remove(self)
      
          def move(self):
              self.rect.y -= self.velocity
      
              #verifier si le projectile n'est plus present sur l'écran
              if self.rect.x > 1080:
                  #supprimer le projectile
                  self.remove()
      
      class Nucleotided (pygame.sprite.Sprite):
      
          #definir le constructeur de la classe
          def __init__(self, player):
              super().__init__()
              self.velocity = 5
              self.player = player
              self.image = pygame.image.load("images/uracile arn.png")
              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
      
          def remove(self):
              self.player.all_nucleotides.remove(self)
      
          def move(self):
              self.rect.y -= self.velocity
      
              #verifier si le projectile n'est plus present sur l'écran
              if self.rect.x > 1080:
                  #supprimer le projectile
                  self.remove()
      
      class Nucleotidee (pygame.sprite.Sprite):
      
          #definir le constructeur de la classe
          def __init__(self, player):
              super().__init__()
              self.velocity = 5
              self.player = player
              self.image = pygame.image.load("images/guanine arn.png")
              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
      
          def remove(self):
              self.player.all_nucleotides.remove(self)
      
          def move(self):
              self.rect.y -= self.velocity
      
              #verifier si le projectile n'est plus present sur l'écran
              if self.rect.x > 1080:
                  #supprimer le projectile
                  self.remove()
      
      
      #générer la fenêtre du jeu
      pygame.display.set_caption("Comet Fall Game")
      screen = pygame.display.set_mode((1080,720))
      
      #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))
      
      # 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)
      
      
      #charger notre jeu
      
      game = Game()
      
      running = True
      
      
      #boucle tant que cette condition est vraie
      while running:
          
          #appliquer l'arrière plan du jeu
          screen.blit(background,(0, 0))
      
          #verifier si notre jeu a commencé ou non
          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)
      
      
          #actualiser la barre de vie du joueur
          game.player.update_health_bar(screen)
      
          #mettre a jour l'écran
          pygame.display.flip()
      
      
           #si le joueur ferme cette fenêtre
          for event in pygame.event.get():
              #que l'évènement est fermeture de fenêtre
              if event.type== pygame.QUIT:
                  running=False
                  pygame.quit()
              #detecter si un joueur lache une touche du clavier   
              elif event.type==pygame.KEYDOWN:
                  game.pressed[event.key] = True
      
                  #detecter si la touche espace est enclencher pour lancer
                  if event.key == pygame.K_a:
                      game.player.launch_nucleotide()
                  elif event.key == pygame.K_t:
                      game.player.launch_nucleotideb()
                  elif event.key == pygame.K_c:
                      game.player.launch_nucleotidec()
                  elif event.key == pygame.K_u:
                      game.player.launch_nucleotided()
                  elif event.key == pygame.K_g:
                      game.player.launch_nucleotidee()
      
                  
              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()        
      


      Pour ce qui est du lapse de temps, c'est une préférence mais j'ai conscience que tout le monde n'est pas toujours disponible.
      0
      1. Et donc le message d'erreur est :

        Traceback (most recent call last):
        File "D:\Première\SVT\PROJET ART\ArN polymérase\réelle version.py", line 391, in <module>
        game = Game()
        TypeError: __init__() missing 1 required positional argument: 'player'

        Mais quand je mets player dans les parenthèses, d'autres messages d'erreurs s'affichent et au bout d'un moment la console spam.
        Pour ce qui est des collisions, j'aimerais que par exemple lorsque le nucleotide avec name2='ctombe' tombe du ciel, et bien s'il tombe au sol il s'efface, s'il touche un autre nucleotide que le nucleotidee, le player subisse des dommages mais que si du coup il touche le nucleotidee il s'efface aussi. Je ne sais pas si je suis claire...
        0
      2. Contributeur
        @LulilaMerci pour votre retour. Comme je le laissais entendre, un spécialiste (je ne suis que faux-débutant) viendra sans doute prendre connaissance de ces éléments (espérons que cela soit cet après-midi)et vous apportera des pistes de réflexion ou les corrections à implémenter. Et c'est bien d'avoir également donné les explications complémentaires.

        Juste une dernière précision, même entre membres, l'échange en MP doit rester exceptionnel et réservé aux infos confidentielles, la résolution des problèmes devant bénéficier à tous les lecteurs. Ceci dit, je vous encourage à vous inscrire, il n'y a aucun inconvénient à être membre.

        Cordialement
        0
    2. Modérateur
      Bonjour,

      La première chose à faire, c'est prendre le temps de comprendre le message d'erreur, qui te dit que tu ne passes pas le bon nombre d'arguments.

      Si tu fais appel à
      game = Game()
      alors la signature du constructeur doit être de la forme :

      class Game:
          def __init__(self):
              ...


      Pour le moment il est de la forme class Game:

      class Game
          def __init__(self, player):
              ...


      ... ce qui signifie que l'appel doit être du genre :

      player = Player()
      game = Game(player)


      Une solution intermédiaire consisterait, si on veut pouvoir sous-entendre
      player
      à la construction de
      game
      d'avoir une valeur par défaut pour ce paramètre.

      Exemple :

      class Game:
          def __init__(self, player = None):
              if not player:
                  player = Player()
              ...


      Bonne chance
      0