Erreur 'pressed' n'est pas attribuer à 'Game'

Résolu
Vieux_hibou -  
 Vieux_hibou -
Bonjour,

En faisant ce programme (code en dessous) j'ai commencé essaye de faire bouger mon Joueur mais...

La console m'affiche :

Traceback (most recent call last):
File "main.py", line 35, in <module>
Game.pressed[event.key] = True
AttributeError: type object 'Game' has no attribute 'pressed'

Le code :
import pygame
pygame.init()

class Game:
  def __init__(self):  
   self.pressed = {}

from Player import Player



pygame.display.set_caption("jeu")
screen = pygame.display.set_mode((1080, 720))
running = True
print("Programme démaré")


background = pygame.image.load('sprite/BG.png')
Player = Player()

while running:
  
  screen.blit(background, (0, 100))
  screen.blit(Player.image, Player.rect)

 
  
  pygame.display.flip()
  
  for event in pygame.event.get():
   if event.type == pygame.QUIT:
     running = False

   elif event.type == pygame.KEYDOWN:
    Game.pressed[event.key] = True
   
   elif event.type == pygame.KEYUP:
    Game.pressed[event.key] = False


Merci d'avance à tous ceux qui voudront bien m'aider

5 réponses

  1. stoic
     
    Bonsoir,

    Game est une classe qui contient la méthode __init__
    Tu as simplement mal compris comment cela fonctionne, une classe, généralement, on l'instancie afin d'obtenir un objet, d'autant plus lorsque des attributs sont déclarés lors de cette instance.

    Donc, il faudrait d'abord faire au préalable
    game = Game()
    par exemple à la suite de
    Player = Player()
    , d'ailleurs attention ici, car tu écrases ta classe Player, il faudrait revoir ça en faisant
    player = Player()
    , et enfin changer Game par game
    elif event.type == pygame.KEYDOWN:
        game.pressed[event.key] = True
    elif event.type == pygame.KEYUP:
        game.pressed[event.key] = False
    0
    1. Vieux_hibou
       
      @stoic

      Bonjour,

      N'ayant sûrement pas bien réussi à suivre l'explication que je te remercie de m'avoir fournie, la console m'affiche l'erreur suivante :

      Traceback (most recent call last):
      File "main.py", line 20, in <module>
      game = Game()
      NameError: name 'Game' is not defined

      Encore une fois je remets le code :

      import pygame
      pygame.init()
      
      class game:
        def __init__(self):  
         self.pressed = {}
      
      from Player import Player
      
      
      
      pygame.display.set_caption("jeu")
      screen = pygame.display.set_mode((1080, 720))
      running = True
      print("Programme démaré")
      
      
      background = pygame.image.load('sprite/BG.png')
      Player = Player()
      game = Game()
      
      while running:
        
        screen.blit(background, (0, 100))
        screen.blit(Player.image, Player.rect)
      
       
        
        pygame.display.flip()
        
        for event in pygame.event.get():
         if event.type == pygame.QUIT:
           running = False
      
         elif event.type == pygame.KEYDOWN:
          game.pressed[event.key] = True
         elif event.type == pygame.KEYUP:
          game.pressed[event.key] = False


      Merci de l'aide que tu as bien voulu me donner et merci d'avance à ceux qui voudront bien m'aider.
      0
      1. stoic > Vieux_hibou
         
        Bonjour,

        En python, par convention, on écrit le nom d'une classe avec sa 1ère lettre en majuscule, et cette écriture est réservée à la déclaration de classe uniquement.

        class Game: # Bien
            # reste du code
        
        class game: # Pas bien
            # reste du code
        
        nombre = 1 # Bien
        Nombre = 1 # Pas bien


        Admettons ta classe Game, et une instanciation

        class Game:
            def __init__(self):
                self.info = 'Je suis la classe Game'
        
        Game = Game()


        Cela va fonctionner, et tout roule, sauf qu'admettons tu as besoin de faire plus d'une instance

        class Game:
            def __init__(self):
                self.info = 'Je suis la classe Game'
        
        Game = Game()
        Game2 = Game()


        Tu auras une erreur du genre

        TypeError: 'Game' object is not callable


        Car la classe Game aura été écrasée, voilà pourquoi on utilise des conventions.
        Et la bonne façon de faire est :

        class Game: # Nom de classe avec une majuscule, toujours ! Et seulement elles.
            def __init__(self):
                self.info = 'Je suis la classe Game'
        
        game = Game() # 1ère lettre de la variable en minuscule, toujours !


        def une_fonction(): # 1ère lettre en minuscule, toujours !
            return 'je suis une fonction inutile !'


        Il y a aussi les constantes en python, là la 1ère lettre est aussi en majuscules, mais tout est en majuscules.

        FPS = 30


        En respectant ces conventions, tu n'auras plus ce genre de problème, il te reste à corriger ton code en respectant ces règles =)
        0
      2. georges97 Messages postés 14627 Date d'inscription   Statut Contributeur Dernière intervention   2 944 > Vieux_hibou
         
        Bonjour,

        Je parle sous le contrôle des premiers intervenants sur ce sujet, à qui je laisse bien entendu la main.

        Les messages d'erreur sont un moyen incontournable pour débugger un programme. Il faut apprendre à les déchiffrer.

        Ici, c'est explicite, sauf erreur de ma part:

        File "main.py", line 20, in <module>
        game = Game()
        NameError: name 'Game' is not defined

        vous instanciez un objet game qui appartiendrait à la classe Game() mais après avoir créé en ligne 4 une classe nommée game (avec un g minuscule, contrairement à votre premier script).

        Le python ne sait plus où il habite.

        edit: je laisse mon message,mas à la lecture des précédentes réponses, je ne suis pas sûr de mes explications. Je demande l'indulgence des autres intervenant, sachant que je suis un faux débutant en python et ne maîtrise pas (encore) les classes, comme le demandeur.

        N'hésitez donc pas à m'indiquer si ma suggestion est erronée, d'autan que ma réponse s'est croisée avec celles de stoic à 9h15, bien plus complète.

        Cordialement.
        0
  2. Vieux_hibou
     
    Premièrement merci à vous deux @george97 et @stoic,
    Vous m'avez aidé à comprendre un peu mieux comment marche pygame et python MAIS comme je suis un véritable boulet :

    J'ai essayé de continuer et la console m'affiche ENCORE une erreur :

    Traceback (most recent call last):
    File "main.py", line 31, in <module>
    Player.move_left()
    AttributeError: type object 'Player' has no attribute 'move_left'


    Le code du fichier main :

    import pygame
    pygame.init()
    
    class Game:
      def __init__(self):  
       self.pressed = {}
    
    from Player import Player
    
    
    
    pygame.display.set_caption("jeu")
    screen = pygame.display.set_mode((1080, 720))
    running = True
    print("Programme démaré")
    
    
    background = pygame.image.load('sprite/BG.png')
    player = Player()
    game = Game()
    
    while running:
      
      screen.blit(background, (0, 100))
      screen.blit(player.image, player.rect)
    
      if game.pressed.get(pygame.K_RIGHT):
        Player.move_right()
    
      elif game.pressed.get(pygame.K_LEFT):
        Player.move_left()
      
      pygame.display.flip()
      
      for event in pygame.event.get():
       if event.type == pygame.QUIT:
         running = False
    
       elif event.type == pygame.KEYDOWN:
        game.pressed[event.key] = True
        
       elif event.type == pygame.KEYUP:
        game.pressed[event.key] = False


    Et celui du fichier Player :

    import pygame
    pygame.init()
    
    
    class Player(pygame.sprite.Sprite):
      def __init__(self):
    
        self.image = pygame.image.load('sprite/Player.png')
        self.health = 100
        self.max_health = 100
        self.attack = 10
        self.velocity = 10
        self.rect = self.image.get_rect()
        self.rect.y = 275
    
        def move_right(self):
         self.rect.x += self.velocity
    
        def move_left(self):
         self.rect.x -= self.velocity


    Encore merci,
    Moi-même
    0
    1. georges97 Messages postés 14627 Date d'inscription   Statut Contributeur Dernière intervention   2 944
       
      soic m'excusera de tenter:

      dans les attributs de la classe Player() ne figure pas, à l'instar de self.rect.y=275 (ligne 14) de self.rect.x... qui dit initialiser la propriété. Cela pourrait explique qu'une propriété non-initialisée provoque une erreur.

      Ce que je voulais surtout vous dire, Vieux_hibou, c'est qu'il ne faut surtout pas vous sous-estimer ou même vous comparer. Je souscris au jugement parfois émis qui considère que la moitié de la programmation est matière de débogage, même chez les plus doués. Après, c'est une question de logique, et de persévérance à nettoyer son code.

      Je dirais même que c'est la parie la plus jouissive du code (quand on trouve bien sûr, pas quand on reste bloqué).

      Par ailleurs, les classes ne sont pas la partie la plus simple de ce langage. Certains n'y accéderont jamais. Vous êtes donc sur la bonne voie.
      0
  3. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     
    Bonjour

    Player c'est la classe

    player en est une instance

    donc il faut écrire player.move_left(), et non Player.move_left() ...
    0
    1. georges97 Messages postés 14627 Date d'inscription   Statut Contributeur Dernière intervention   2 944
       
      Bonjour Phil,

      J'avais "presque" bon. A nouveau une question de majuscule/minuscule. Il faut faire attention à tout.



      Cordialement,
      Georges
      0
  4. Vieux_hibou
     
    Bonjour,

    J'ai pourtant essayé :

    code main :
    import pygame
    pygame.init()
    
    class Game:
      def __init__(self):  
       self.pressed = {}
    
    from Player import Player
    
    
    
    pygame.display.set_caption("jeu")
    screen = pygame.display.set_mode((1080, 720))
    running = True
    print("Programme démaré")
    
    
    background = pygame.image.load('sprite/BG.png')
    player = Player()
    game = Game()
    
    while running:
      
      screen.blit(background, (0, 100))
      screen.blit(player.image, player.rect)
    
      if game.pressed.get(pygame.K_RIGHT):
        player.move_right()
    
      elif game.pressed.get(pygame.K_LEFT):
        player.move_left()
      
      pygame.display.flip()
      
      for event in pygame.event.get():
       if event.type == pygame.QUIT:
         running = False
    
       elif event.type == pygame.KEYDOWN:
        game.pressed[event.key] = True
        
       elif event.type == pygame.KEYUP:
        game.pressed[event.key] = False


    code Joueur :
    import pygame
    pygame.init()
    
    
    class Player(pygame.sprite.Sprite):
      def __init__(self):
    
        self.image = pygame.image.load('sprite/Player.png')
        self.health = 100
        self.max_health = 100
        self.attack = 10
        self.velocity = 10
        self.rect = self.image.get_rect()
        self.rect.x = 50
        self.rect.y = 275
    
        def move_right(self):
         self.rect.x += self.velocity
    
        def move_left(self):
         self.rect.x -= self.velocity


    mais ma console m'affiche toujours la même erreur :
    Traceback (most recent call last):
    File "main.py", line 28, in <module>
    player.move_right()
    AttributeError: 'Player' object has no attribute 'move_right'
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      bonjour,
      regarde bien l'indentation des def dans ta classe Player.
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Vieux_hibou
     
    Merci à toi @yg_be (sans toi je m'en serais rendu compte 6 jours plus tard)…
    Un grand merci aussi a @stoic, @Phil_1857 et a @georges97

    J'ai le grand plaisir de déclarer ce problème comme résolu !
    0