Problème avec un attribut Pygame [Python]

Résolu/Fermé
Enz0lanterne828 Messages postés 50 Date d'inscription mercredi 8 janvier 2020 Statut Membre Dernière intervention 21 mars 2020 - 25 janv. 2020 à 21:01
 MYRLY - 13 nov. 2020 à 19:56
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

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
Enz0lanterne828 Messages postés 50 Date d'inscription mercredi 8 janvier 2020 Statut Membre Dernière intervention 21 mars 2020 8
Modifié le 25 janv. 2020 à 23:08
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
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
MYRLY > trifou
13 nov. 2020 à 19:56
Merci, j'ai fais la même erreur.
0
Enz0lanterne828 Messages postés 50 Date d'inscription mercredi 8 janvier 2020 Statut Membre Dernière intervention 21 mars 2020 8
26 janv. 2020 à 11:03
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
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
Enz0lanterne828 Messages postés 50 Date d'inscription mercredi 8 janvier 2020 Statut Membre Dernière intervention 21 mars 2020 8
Modifié le 26 janv. 2020 à 11:28
Merci, je n'avais pas remarqué !

Je test le programme et...

Tout fonctionne bien, merci :-)
0