Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Python PYGAME] Probleme d'affichage casse brique

jeu clone de casse brique arkanoÏd

Sujet résolu
    28 mars 2015 à 14:02:11

    salut à tous pythoneurs et pygameurs, depuis 2 jours j'essaye de faire une copie du gameplay du jeu de casse brique arkanoïd, j'ai reussi à implémenter le gameplay de base. comme sur l'image suivant:

    coregameplay

    Comme je veux gérer les états de mon jeu (pause, partie, menu, ... etc) dans une classe 'Game' au moment où je changes l’état d'une partie par un autre état et que je remet une autre partie j'ai les objets des la parties précedentes qui s'affichent encore à l'écran comme suit:

    Dans ma classe Game j'initialise une variable qui se nomme self.currentState  pour designer l'état courant avec une instance de la classe GameplayState qui contient la logique du gameplay:

    self.currentState = GameplayState()

    lorsque le joueur perd on met la variable self.leaveState de la classe GameplayState à True et on fait un changement d'état dans la classe Game comme suit:

    def switchState(self):
            """Switch the states"""
            if self.currentState.name == "GAME STATE":
                if self.currentState.win:
                    self.currentState = WinState()
            elif self.currentState.name == "WIN STATE":
                    self.currentState = GameplayState()

    pour voir plus, voici les fichiers:

    http://www.mediafire.com/download/hh6h3i7nr886hps/Arkanoid.zip

    MERCI d'avance!

     



    -
    Edité par israel93 28 mars 2015 à 14:09:51

    • Partager sur Facebook
    • Partager sur Twitter
      28 mars 2015 à 15:16:54

      Ton problème vient du fait que tu définis des pygame.group comme attribut de classe et non d'instance. Donc lorsque tu changes ton currentState, et bien les sprites sont toujours dedans, car les instances sont jetées à la poubelle, mais pas la définition de la classe!

      Plusieurs solutions s'offrent à toi. Si tu veux malgré tout conserver cette structure, tu pourrais ajouter dans la méthode leaving de GamePlayState

      def leaving(self):
          Ball.group.empty()
          Block.group.empty()
          Paddle.group.empty()
      
      </pre>

      Bien entendu il faut penser à appeler cette méthode lorsque tu changes d'état.

      Ta machine à état n'est pas tout à fait au point. L'idée est plutôt de passer aux états une référence vers Game. Pour éviter des références circulaires (Game à une référence vers GameplayState et GameplayState a maintenant une référence vers Game) on utilise un weakref.

      Ce détail mis à part, cette structure te permet de mettre la logique pour changer d'état dans les classes états. Donc au revoir les variables comme leaveState. Lorsque la condition pour changer d'état est présente, c'est l'état lui-même qui demande au Game de faire un switchState. Et ça fait disparaître une chiée de if de switchState. Pour le moment c'est simple, mais si t'avais 15 états différents, avec pour chacun 3 possibilités d'aller vers un autre état, t'imagines le bazar...

      PS: Essaie de renommer tes variables et classes pour suivre un peu les conventions de la PEP8. Donc on aura switch_state. :)

      -
      Edité par Dan737 28 mars 2015 à 15:20:57

      • Partager sur Facebook
      • Partager sur Twitter
        29 mars 2015 à 14:29:48

        Merci Dan737, je comprends mieux le problème maintenant. En ce qui concerne la machine à état j'aimerais bien suivre ton conseil mais je sais pas comment je vais m'y prendre, surtout quand tu parles de weakref.

        -
        Edité par israel93 29 mars 2015 à 14:37:39

        • Partager sur Facebook
        • Partager sur Twitter
          29 mars 2015 à 15:52:05

          Le weakref n'est qu'un détail. Et de plus, en poussant un peu plus loin mes recherches, le garbage collector de Python arriverait malgré tout à supprimer tes objets pour autant que tu n'aies pas déclarer une méthode __del__ pour une de ces classes, ce qui n'est pas ton cas. Donc laisse ça de côté.

          L'idée est que tes états prennent comme argument de construction l'instance de Game. Donc quand tu crées dans la classe Game une instance de GameplayState, tu ferais self.currentState = GameplayState(self). GameplayState conserverait cet argument dans (par exemple) self.game. Ca veut dire que maintenant GameplayState peut appeler des méthodes de Game, et en particulier la méthode switchState. Cette méthode d'ailleurs devrait prendre en argument le nouvel état vers lequel aller. L'idée étant que Game sait changer d'état, mais il prend n'importe quel état qu'on lui passe. Il ne connait pas la logique pour passer d'un état donné à un autre. Ce sont les états qui ont cette logique.

          class Game(object):
          
          def switchState(self, new_state):
              """Switch the states"""
              self.currentState.leaving()
              self.currentState = new_state
              self.currentState.entered()
          
          </pre>
          class class GameplayState(object):
          
          """This class represent the in-game screen"""
          
          def update(self, dt):
              # Tout ce qui vient avant ...
          
              if len(self.level.blockList) == 0:
                  self.game.switchState(WinState(self.game))
          
          </pre> Et même principe si on perd. Comme tu vois, la logique pour passer de GameplayState vers WinState est contenue dans la classe GameplayState même.
          • Partager sur Facebook
          • Partager sur Twitter
            29 mars 2015 à 16:01:03

            Je comprends mieux maintenant, Merci! :D
            • Partager sur Facebook
            • Partager sur Twitter

            [Python PYGAME] Probleme d'affichage casse brique

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown