Du mal avec Pygame et les collisions

Résolu
Lulila -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -
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. georges97 Messages postés 14564 Date d'inscription   Statut Contributeur Dernière intervention   2 919
     
    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
  2. lulila
     
    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. Lulila
       
      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
      1. georges97 Messages postés 14564 Date d'inscription   Statut Contributeur Dernière intervention   2 919 > Lulila
         
        Merci 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
  3. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    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