Du mal avec Pygame et les collisions

Résolu/Fermé
Lulila - 19 mars 2022 à 10:46
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 - 21 mars 2022 à 11:05
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

georges97 Messages postés 12578 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 24 novembre 2024 2 410
19 mars 2022 à 11:37
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
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
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
georges97 Messages postés 12578 Date d'inscription lundi 31 janvier 2011 Statut Contributeur Dernière intervention 24 novembre 2024 2 410 > Lulila
19 mars 2022 à 13:38
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
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802
21 mars 2022 à 11:05
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