Problème avec un attribut Pygame [Python]

Résolu
Enz0lanterne828 Messages postés 50 Statut Membre -  
 MYRLY -
Bonsoir,

Je débute en programmation du python et en ce moment j'utilise le module Pygame.
J'ai créer une classe qui s'appelle BluePlayer:
# Créer le joueur bleu
class BluePlayer(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.vie = 250
        self.kick = 5
        self.max_vie = 250
        self.attack = 10
        self.speed = 5
        self.image = pygame.image.load('archerbleu.png')
        self.rect = self.image.get_rect()
        self.rect.x = 50
        self.rect.y = 500

    def move_right(self):
        self.rect.x += self.speed

    def move_left(self):
        self.rect.x -= self.speed


Tout est normal pour le moment j'arrive à faire apparaître le joueur sur la fenêtre mais quand je veux créer un autre joueur comma par exemple une classe RedPlayer:
# Créer le joueur rouge
class RedPlayer(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.vie = 250
        self.kick = 5
        self.max_vie = 250
        self.attack = 10
        self.speed = 5
        self.photo = pygame.image.load('archerrouge.png')
        self.rect = self.photo.get_rect()
        self.rect.x = 400
        self.rect.y = 500

Lorsque je lance mon programme une erreur apparaît disant:
screen.blit(game.red_player.photo, game.red_player.rect)
AttributeError: type object 'RedPlayer' has no attribute 'photo'

Python me dit que la classe RedPlayer n'as pas d'attribut photo alors que si...
self.photo = pygame.image.load('archerrouge.png')


Je ne comprend pas...

Si vous savez pourquoi cela fait cela, pouriez-vous me le dire ?

Merci, Cordialement

4 réponses

  1. trifou
     
    Bonsoir,

    Tu as forcément fait une erreur quelque part.
    Comment est instancié ta classe et où ? Même fichier ? Tu n'aurais pas déclaré une autre classe de même nom que tu utiliserais au lieu de celle-là ?

    Tu peux déjà regarder ce que contient ton objet game.red_player en utilisant dir
    print(dir(game.red_player))
    .

    Toutefois, dans ton code, tu devrais avoir une classe Player héritant de Sprite, tes 2 classes players (bleu, rouge) héritant de Player, ici l'héritage est plus que judicieux puisque il y a exactement les mêmes propriétés dans tes classes.
    1
  2. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Quand j’exécute la commande avec dire, j'obtiens ce-ci:
    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'add', 'add_internal', 'alive', 'groups', 'kill', 'remove', 'remove_internal', 'update']
    


    Donc ce que vous voulez dire c'est que je peux créer une spuerclasse contenant BluePlayer et RedPlayer ?

    Voilà mon programme en entier au cas ou (Personnellement je ne vois pas d’erreur mais l'erreur doit être au moment ou il y a:)
    # Appliquer l'image du joueur rouge
        screen.blit(game.red_player.photo, game.red_player.rect)


    Sinon voilà le programme en entier:
    Main:
    import pygame
    import time
    from game import Game
    
    pygame.init()
    
    # Générer la fenêtre du jeu
    pygame.display.set_caption("ArcherWars")
    screen = pygame.display.set_mode((1080, 720))
    logo = pygame.image.load("icon.png").convert()
    pygame.display.set_icon(logo)
    
    # Importer l'arrière plan du jeu
    fond = pygame.image.load('fond.jpg')
    
    # Charger le jeu
    game = Game()
    
    
    run = True
    
    # Boucle qui s'éxécute tant que run = True
    while run:
    
    
    
        # Appliquer l'arière plan du jeu
        screen.blit(fond, (0, -77))
    
        # Appliquer l'image du joueur bleu
        screen.blit(game.blue_player.image, game.blue_player.rect)
    
        # Appliquer l'image du joueur rouge
        screen.blit(game.red_player.photo, game.red_player.rect)
    
        # Vérifier si le joueur shouaite aller à gauche ou à droite
        if game.pressed.get(pygame.K_f) and game.blue_player.rect.x + game.blue_player.rect.width < screen.get_width():
            game.blue_player.move_right()
        elif game.pressed.get(pygame.K_d) and game.blue_player.rect.x > 0:
            game.blue_player.move_left()
    
        # Mettre à jour l'écran
        pygame.display.flip()
    
        # Si le joueur ferme cette fenêtre
        for event in pygame.event.get():
            # Vérifier que l'évenement est fermeture de fenêtre
            if event.type == pygame.QUIT:
                run = False
                pygame.quit()
                print("Fermeture du jeu en cours veuillez patienter...")
                time.sleep(2.5)
                print("Le jeu à bien été fermé !")
            # Détecter si un joueur lache une touche du clavier
            elif event.type == pygame.KEYDOWN:
                game.pressed[event.key] = True
            elif event.type == pygame.KEYUP:
                game.pressed[event.key] = False
    

    Game:
    import pygame
    from blue_player import BluePlayer
    from red_player import RedPlayer
    
    
    # Créer une seconde classe qui va représenter le jeu
    class Game:
    
        def __init__(self):
            # Générer le joueur quand une partie est créer
            self.blue_player = BluePlayer()
            self.red_player = RedPlayer
            self.pressed = {}
    

    Blue_Player:
    import pygame
    
    
    # Créer le joueur bleu
    class BluePlayer(pygame.sprite.Sprite):
    
        def __init__(self):
            super().__init__()
            self.vie = 250
            self.kick = 5
            self.max_vie = 250
            self.attack = 10
            self.speed = 5
            self.image = pygame.image.load('archerbleu.png')
            self.rect = self.image.get_rect()
            self.rect.x = 50
            self.rect.y = 500
    
        def move_right(self):
            self.rect.x += self.speed
    
        def move_left(self):
            self.rect.x -= self.speed
    

    red_player:
    import pygame
    
    
    # Créer le joueur rouge
    class RedPlayer(pygame.sprite.Sprite):
    
        def __init__(self):
            super().__init__()
            self.vie = 250
            self.kick = 5
            self.max_vie = 250
            self.attack = 10
            self.speed = 5
            self.photo = pygame.image.load('archerrouge.png')
            self.rect = self.photo.get_rect()
            self.rect.x = 400
            self.rect.y = 500
    


    Merci pour la réponse, cordialement
    0
    1. trifou
       
      Bonjour,

      Tu n'as pas instancié ton objet (omission des parenthèses).

      self.red_player = RedPlayer


      > Donc ce que vous voulez dire c'est que je peux créer une spuerclasse contenant BluePlayer et RedPlayer ?

      Non, une classe PLayer dont BluePlayer et RedPlayer dériveront.
      0
      1. MYRLY > trifou
         
        Merci, j'ai fais la même erreur.
        0
  3. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Bonjour,

    Si j'ai instancié mon objet dans la classe game:
    mport pygame
    from blue_player import BluePlayer
    from red_player import RedPlayer
    
    
    # Créer une seconde classe qui va représenter le jeu
    class Game:
    
        def __init__(self):
            # Générer le joueur quand une partie est créer
            self.blue_player = BluePlayer()
            self.red_player = RedPlayer
            # Ci dessus j’instancie ma classe red_player et blue_player


    Et pour la classe Player dont RedPlayer et BluePlayer dériveront, comme ça ça marche ?
    import pygame
    import game
    
    
    # Créer la super classe de joueur
    class Player(pygame.sprite.Sprite):
        def __init__(self):
            super().__init__()
            self.vie = 250
            self.kick = 5
            self.max_vie = 250
            self.attack = 10
            self.speed = 5
            self.saut = 5
    
    # Puis quand je créer la classe RedPlayer et BluePlayer je fais ça:
    
    import pygame
    import player
    
    
    # Créer le joueur rouge
    class RedPlayer(player.Player):
    
         # Ci dessus je fais dériver la classe RedPlayer de la classe Player et pareil pour la classe                      BluePlayer puis j'ajoute les composants supplémentaires
        def __init__(self):
            super().__init__()
            self.photo = pygame.image.load('archerrouge.png')
            self.rect = self.photo.get_rect()
            self.rect.x = 400
            self.rect.y = 500


    Je ne sais pas d'où vient le problème si tous les codes fonctionnent bien...
    Merci pour vos réponses, cordialement
    0
    1. trifou
       
      Pas bien réveillé ?

      # Créer une seconde classe qui va représenter le jeu
      class Game:
      
          def __init__(self):
              # Générer le joueur quand une partie est créer
              self.blue_player = BluePlayer()
              self.red_player = RedPlayer # «««««« IL MANQUE LES PARENTHÈSES !
              # Ci dessus j’instancie ma classe red_player et blue_player


      Oui c'est ça pour ta classe Player, sachant que seuls le nom d'image et pos x, y varient alors ça pourrait faire

      class Player(class Player(pygame.sprite.Sprite):
          def __init__(self, image_file, x, y):
              super().__init__()
              self.vie = 250
              self.kick = 5
              self.max_vie = 250
              self.attack = 10
              self.speed = 5
              self.photo = pygame.image.load(image_file)
              self.rect = self.photo.get_rect()
              self.rect.x = x
              self.rect.y = y


      Puis
      class BluePlayer(Player):
          def __init__(self):
              super().__init__('archerbleu.png', 50, 500)
      
          def move_right(self):
              self.rect.x += self.speed
      
          def move_left(self):
              self.rect.x -= self.speed


      Et
      class RedPlayer(Player):
          def __init__(self):
              super().__init__('archerrouge.png', 400, 500)


      Si RedPlayer doit aussi implémenter les méthodes move_* alors il faudrait les déclarer dans Player.
      0
  4. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Merci, je n'avais pas remarqué !

    Je test le programme et...

    Tout fonctionne bien, merci :-)
    0