Python AttributeError

Résolu/Fermé
PY2019 Messages postés 17 Date d'inscription mercredi 24 avril 2019 Statut Membre Dernière intervention 29 avril 2019 - Modifié le 24 avril 2019 à 13:51
quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 - 26 avril 2019 à 15:51
Bonjour à tous,

Débutante avec Python et plus précisément avec la bibliothèque pygame, j'essaie de créer un jeu qui consiste à faire bouger une voiture sur une route, (accélérer, ralentir, se déplacer sur les cotés), de façon à éviter les obstacles qui sont ici des animaux.

Seulement, je rencontre une difficulté depuis quelques jours :
Pour gérer la collision entre la voiture et un obstacle, je souhaite utiliser la formule 'pygame.sprite.spritecollide' suivie des paramètres entre parenthèse.


 """collision voiture obstacle"""
        hit_list = pygame.sprite.spritecollide(Voiture,Obstacles_sprite_list, False)
        for hit in hit_list:
            son_boum.play()
            fondgameover=pygame.image.load('ecrangameover.png').convert_alpha()
            screen.blit(fondgameover, (0, 0))
            pygame.display.update()
            pygame.time.delay(4000)
            main()


Mais rien à faire, j'ai toujours la même erreur : "AttributeError: type object 'Voiture' has no attribute 'rect'"...
Il me semble pourtant avoir correctement paramétré la 'class Voiture':

class Voiture(pygame.sprite.Sprite):

    # initialisation
    def __init__(self):
        super().__init__()

        #chargement des images
        self.image=pygame.image.load('voiture1.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.change_x =0
        self.change_y =0
    def update(self):
        """Mouvement de la voiture"""
        self.rect.x += self.change_x
        if self.rect.x<250:
            self.rect.x-=self.change_x

        if self.rect.x>550:
            self.rect.x-=self.change_x

        self.rect.y += self.change_y
        if self.rect.y<0:
            self.rect.y-= self.change_y

        if self.rect.y>450:
            self.rect.y-=self.change_y

    def mvtgauche(self):
        """Mouvement gauche """
        self.change_x = -1
        self.change_y = 0

    def mvtdroit(self):
        """Mouvement droite"""
        self.change_x = 1
        self.change_y = 0

    def mvthaut(self):
        """Mouvement haut """
        self.change_x = 0
        self.change_y = -1

    def mvtbas(self):
        """Mouvement bas"""
        self.change_x = 0
        self.change_y = 1

    def stop(self):
        """arret"""
        self.change_x=0
        self.change_y=0

Si quelqu'un qui s'y connais mieux que moi peut m'aider je lui en serais reconnaissante.

EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.

2 réponses

quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 344
24 avril 2019 à 13:47
Bonjour,
tout d'abord, merci d'utiliser les balises de code (explications ici : https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code) car sinon le site ne conserve pas les indentations, or elles sont indispensables en Python. De plus cela permet d'avoir la coloration syntaxique qui permet de rendre le code plus lisible.

Pour réponde à votre question, lorsque vous faites
pygame.sprite.spritecollide(Voiture, ...)
, vous utilisez la classe Voiture au lieu d'utiliser un objet de type Voiture. Il faut donc instancier cette classe en faisant
pygame.sprite.spritecollide(Voiture(), ...)
.
1
PY2019 Messages postés 17 Date d'inscription mercredi 24 avril 2019 Statut Membre Dernière intervention 29 avril 2019
24 avril 2019 à 14:34
C'est la première fois que j'écris un message ici, mais la prochaine fois je penserai à utiliser les balises de codes. Merci pour votre réponse, c'était la bonne explication. Je n'y aurais jamais pensé seule..
0
PY2019 Messages postés 17 Date d'inscription mercredi 24 avril 2019 Statut Membre Dernière intervention 29 avril 2019
Modifié le 24 avril 2019 à 16:54
Je rencontre un nouveau problème. Python n'affiche plus de message d'erreur, mais il n'applique pas pour autant la collision voiture-obstacles. J'ai pensé que ça pouvait être dû à l'emplacement de mon paragraphe collision dans mon programme principal... Pourriez vous me donner votre avis ?

def main():
    """programme principal"""
    pygame.init()

    #definition de la fenetre
    screen= pygame.display.set_mode((900, 600),0,32)
    pygame.display.set_caption("josette en voiture")
    fond=pygame.image.load('fondforet.png').convert_alpha() #chargement et collage du fond
    son_fond.play()

    #creation des listes de sprites
    active_sprite_list = pygame.sprite.Group()
    liste_lignes=pygame.sprite.Group()
    Obstacles_sprite_list= pygame.sprite.Group()

    # creation voiture
    voiture = Voiture()
    voiture.rect.x = 300
    voiture.rect.y = 300
    active_sprite_list.add(voiture)

    # lignes centrales
    compteurligne=0
    ligne=Line()
    ligne.rect.y=0
    liste_lignes.add(ligne)
    ligne=Line()
    ligne.rect.y=250
    liste_lignes.add(ligne)
    ligne=Line()
    ligne.rect.y=500
    liste_lignes.add(ligne)

    compteurbarriere1=0
    compteurbarriere2=0
    compteurdecors1=0
    compteurdecors2=0
    compteurobstacle=0

    # Boucle principale
    continuer=1
    while continuer:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                continuer=0

            # touches enfoncees
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    voiture.mvtgauche()
                if event.key == pygame.K_RIGHT:
                    voiture.mvtdroit()
                if event.key == pygame.K_UP:
                    voiture.mvthaut()
                if event.key == pygame.K_DOWN:
                    voiture.mvtbas()

              # touches relevees
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    voiture.stop()
                if event.key == pygame.K_RIGHT:
                    voiture.stop()
                if event.key == pygame.K_UP:
                    voiture.stop()
                if event.key == pygame.K_DOWN:
                    voiture.stop()
        #mise a jour des sprites
        active_sprite_list.update()
        liste_lignes.update()
        Obstacles_sprite_list.update()

        #lignes centrales
        compteurligne+=1
        if compteurligne>250:
           ligne=Line()
           liste_lignes.add(ligne)
           compteurligne=0

        compteurbarriere1+=1
        if compteurbarriere1>45:
           barriere1=fence1()
           active_sprite_list.add(barriere1)
           compteurbarriere1=0
        compteurbarriere2+=1
        if compteurbarriere2>45:
           barriere2=fence2()
           active_sprite_list.add(barriere2)
           compteurbarriere2=0

        compteurdecors1+=1
        if compteurdecors1>250:
            decors=decorsforet()
            active_sprite_list.add(decors)
            compteurdecors1=0

        compteurdecors2+=1
        if compteurdecors2>100:
            sapin=sapins()
            active_sprite_list.add(sapin)
            compteurdecors2=0

        compteurobstacle+=randint(1,10)*0.1
        if compteurobstacle>200:
            choix=randint(1,3)
            if choix==1:
                vache1=vache()
                vache1.rect.x=randint(250,560)
                active_sprite_list.add(vache1)
            if choix==2:
                cheval1=cheval()
                cheval1.rect.x=randint(250,560)
                active_sprite_list.add(cheval1)
            compteurobstacle=0

        #mise a jour des sprites
        active_sprite_list.update()
        liste_lignes.update()
        Obstacles_sprite_list.update()

        #Gestion des collisions
        """collision voiture obstacle"""
        hit_list = pygame.sprite.spritecollide(voiture,Obstacles_sprite_list,False)
        for hit in hit_list:
            son_boum.play()
            fondgameover=pygame.image.load('ecrangameover.png').convert_alpha()
            screen.blit(fondgameover,(0, 0))
            pygame.display.update()
            pygame.time.delay(4000)
            main()

        # affichage
        screen.blit(fond,(0,0))
        liste_lignes.draw(screen)
        active_sprite_list.draw(screen)

        pygame.display.flip()
0
quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 344
24 avril 2019 à 17:49
Je n'ai pas encore eu l'occasion de tester votre code mais en le regardant rapidement, j'ai l'impression que vous n'ajoutez jamais rien dans Obstacles_sprite_list, ce qui explique pourquoi aucune collision n'est détectée.
0
PY2019 Messages postés 17 Date d'inscription mercredi 24 avril 2019 Statut Membre Dernière intervention 29 avril 2019 > quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024
24 avril 2019 à 18:27
En effet je n'avais pas fais attention à ça... Merci beaucoup. Maintenant mon écran game over s'affiche mais sans même qu'il y ait eu contact entre la voiture et un obstacle.. Et cet écran s'affiche même lorsque j'essaie de fermer la fenêtre. Mais merci pour le temps que vous avez accordé à mon projet.
0
PY2019 Messages postés 17 Date d'inscription mercredi 24 avril 2019 Statut Membre Dernière intervention 29 avril 2019 > quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024
24 avril 2019 à 18:42
Finalement j'ai parlé un peu trop vite, mon écran s'affiche bien lorsque la voiture entre en collision avec un obstacle. Il me reste plus qu'a comprendre pourquoi il s'affiche quand j'essaie de fermer la fenêtre et pourquoi mes obstacles défilent trois fois plus vite qu'avant .. :)
0
quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 344 > PY2019 Messages postés 17 Date d'inscription mercredi 24 avril 2019 Statut Membre Dernière intervention 29 avril 2019
24 avril 2019 à 19:34
Pouvez-vous partager à nouveau votre code car je ne sais pas comment vous avez corrigé votre erreur précédente ?
0
PY2019 Messages postés 17 Date d'inscription mercredi 24 avril 2019 Statut Membre Dernière intervention 29 avril 2019
24 avril 2019 à 19:42
Je l'ai sûrement corrigée assez maladroitement :

def main():
    """programme principal"""
    pygame.init()

    #definition de la fenetre
    screen= pygame.display.set_mode((900, 600),0,32)
    pygame.display.set_caption("josette en voiture")
    fond=pygame.image.load('fondforet.png').convert_alpha() #chargement et collage du fond
    son_fond.play()

    #creation des listes de sprites
    active_sprite_list = pygame.sprite.Group()
    liste_lignes=pygame.sprite.Group()
    Obstacles_sprite_list= pygame.sprite.Group()

    # creation voiture
    voiture = Voiture()
    voiture.rect.x = 300
    voiture.rect.y = 300
    active_sprite_list.add(voiture)

    #lignes centrales
    compteurligne=0
    ligne=Line()
    ligne.rect.y=0
    liste_lignes.add(ligne)
    ligne=Line()
    ligne.rect.y=250
    liste_lignes.add(ligne)
    ligne=Line()
    ligne.rect.y=500
    liste_lignes.add(ligne)

    compteurbarriere1=0
    compteurbarriere2=0
    compteurdecors1=0
    compteurdecors2=0
    compteurobstacle=0

    # Boucle principale
    continuer=1
    while continuer:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                continuer=0

            # touches enfoncees
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    voiture.mvtgauche()
                if event.key == pygame.K_RIGHT:
                    voiture.mvtdroit()
                if event.key == pygame.K_UP:
                    voiture.mvthaut()
                if event.key == pygame.K_DOWN:
                    voiture.mvtbas()

              # touches relevees
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    voiture.stop()
                if event.key == pygame.K_RIGHT:
                    voiture.stop()
                if event.key == pygame.K_UP:
                    voiture.stop()
                if event.key == pygame.K_DOWN:
                    voiture.stop()
        #mise a jour des sprites
        active_sprite_list.update()
        liste_lignes.update()
        Obstacles_sprite_list.update()

        #lignes centrales
        compteurligne+=1
        if compteurligne>250:
           ligne=Line()
           liste_lignes.add(ligne)
           compteurligne=0

        compteurbarriere1+=1
        if compteurbarriere1>45:
           barriere1=fence1()
           active_sprite_list.add(barriere1)
           compteurbarriere1=0
        compteurbarriere2+=1
        if compteurbarriere2>45:
           barriere2=fence2()
           active_sprite_list.add(barriere2)
           compteurbarriere2=0

        compteurdecors1+=1
        if compteurdecors1>250:
            decors=decorsforet()
            active_sprite_list.add(decors)
            compteurdecors1=0

        compteurdecors2+=1
        if compteurdecors2>100:
            sapin=sapins()
            active_sprite_list.add(sapin)
            compteurdecors2=0

        compteurobstacle+=randint(1,10)*0.1
        if compteurobstacle>200:
            choix=randint(1,3)
            if choix==1:
                vache1=vache()
                vache1.rect.x=randint(250,560)
                active_sprite_list.add(vache1)
                Obstacles_sprite_list.add(vache1)
            if choix==2:
                cheval1=cheval()
                cheval1.rect.x=randint(250,560)
                active_sprite_list.add(cheval1)
                Obstacles_sprite_list.add(cheval1)
            compteurobstacle=0

        #mise a jour des sprites
        active_sprite_list.update()
        liste_lignes.update()
        Obstacles_sprite_list.update()

        #Gestion des collisions
        """collision voiture obstacle"""
        hit_list = pygame.sprite.spritecollide(voiture,Obstacles_sprite_list,False)
        for hit in hit_list:
         son_boum.play()
         fondgameover=pygame.image.load('ecrangameover.png').convert_alpha()
         screen.blit(fondgameover,(0, 0))
         pygame.display.update()
         pygame.time.delay(4000)
         main()

        # affichage
        screen.blit(fond,(0,0))
        liste_lignes.draw(screen)
        active_sprite_list.draw(screen)

        pygame.display.flip()


J'avoue que je ne maîtrise pas vraiment le programme. J'ai donc ajouté les obstacles à deux listes... C'est le seul moyen que j'ai trouvé pour voir défiler les animaux qui n'apparaissaient plus.
0