Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Tkinter] Binding

Sujet résolu
    17 août 2014 à 18:36:34

    Bonsoir,

    Je reprend un vieux programme de Pong en Pygame pour le transformer en Tkinter, et voilà qu'un problème survient, je n'ai malheureusement pas trouvé d'aide sur l'internet à ce propos.

    Pour faire déplacer la raquette à l'utilisateur, j'utilise évidemment bind, le fait de rester appuyer dessus lui permet automatiquement de la bouger, mais il y a un temps d'attente non négligeable entre le premier appui qui déplace donc la raquette, puis les déplacements effectués pendant que l'utilisateur garde la touche enfoncée. Ceci rend le jeu totalement injouable, car ce temps d'attente ruine tout.

    Comment puis-je enlever ce temps d'attente ? J'avais pensé à regarder l'état des touches sur clavier plutôt que de passer par bind, mais je n'ai pas trouvé. Merci pour vos réponses.

    • Partager sur Facebook
    • Partager sur Twitter
      17 août 2014 à 20:18:39

      Salut,

      si tu veux qu'on t'aide, merci de poster ton code^^

      • Partager sur Facebook
      • Partager sur Twitter
      Bevet Breizh! Breizh dizalc'h! Betek an trec'h! Ha mallozh ruz d'ar c'hallaoued! Trouvez votre voie
        17 août 2014 à 20:36:25

        Ben je ne vois pas vraiment comment le code pourrait t'aider plus, puisque je cherche juste à contrôler la répétition d'une touche bindée. Enfin, si tu penses que ce sera plus simple.

        #!/usr/bin/env python3.2
        
        
        from tkinter import *
        from random import randrange
        from random import choice
        
        
        class Item:
            def __init__(self, x, y, w, h, id = 0):
                self.__id = id;
                self.__x = x;
                self.__y = y;
                self._width = w;
                self._height = h;
                
            def getId(self): return self.__id;
            def getCoords(self): return (self.__x, self.__y, self.__x + self._width, self.__y + self._height);
            def setCoords(self, x, y):
                self.__x = x;
                self.__y = y;
        
            def move(self, dx = 0, dy = 0, **limits):
                self.__x += dx;
                self.__y += dy;
                
                if (self.__x < 0): self.__x = 0;
                if (self.__x + self._width > limits['width']): self.__x = limits['width'] - self._width;
                if (self.__y < 0): self.__y = 0;
                if (self.__y + self._height > limits['height']): self.__y = limits['height'] - self._height;
        
        
        class Ball(Item):
            __SPEED = 4;
            
            def __init__(self, x, y, w, h, id = 0):
                Item.__init__(self, x, y, w, h, id);
                self.__dx = 0;
                self.__dy = 0;
                
            def setDeltax(self, dx): self.__dx = dx;
            def setDeltay(self, dy): self.__dy = dy;
            
            def evolve(self, **limits):
                self.move(self.__dx * Ball.__SPEED, self.__dy * Ball.__SPEED, width=limits['width'], height=limits['height']);
                
                (x1, y1, x2, y2) = self.getCoords();
                if (y1 <= 0 or y2 >= limits['height']): self.__dy = -self.__dy;
                
                xmiddle = x1 + self._width / 2;
                ymiddle = y1 + self._height / 2;
                
                for player in limits['players'].values():
                    xpmiddle = (player['xmax'] - player['xmin']) / 2 + player['xmin'];
                    ypmiddle = (player['ymax'] - player['ymin']) / 2 + player['ymin'];
                    pwidth = player['xmax'] - player['xmin'];
                    pheight = player['ymax'] - player['ymin'];
                    
                    if ((abs(xmiddle - xpmiddle) <= (self._width + pwidth) / 2) and (abs(ymiddle - ypmiddle) <= (self._height + pheight) / 2)):
                        self.__dx = -self.__dx;
                        if (self.__dy < 0): self.__dy -= -(ymiddle - player['ymax']) / (2 * pheight) + 0.75;
                        else: self.__dy += (ymiddle - player['ymin']) / (2 * pheight) + 0.75;
        
        class Game(Tk):
            __MOVE_WAIT = 1;
            
            def __init__(self, w, h):
                Tk.__init__(self);
                
                self.__width = w;
                self.__height = h;
                self.__move = 0;
                self.__canvas = Canvas(self, width=w, height=h);
                self.__canvas.pack();
                self.__canvas.create_rectangle(0, 0, w, h, width=0, fill="black");
                
                self.__player = Item(10, h // 2 - 20, 10, 40, self.__canvas.create_rectangle(0, 0, 0, 0, width=0, fill="white"));
                self.__ia = Item(w - 20, h // 2 - 20, 10, 40, self.__canvas.create_rectangle(0, 0, 0, 0, width=0, fill="white"));
                self.__ball = Ball(0, 0, 10, 10, self.__canvas.create_rectangle(0, 0, 0, 0, width=0, fill="white"));
                
                self.geometry(str(w) + "x" + str(h));
                self.resizable(False, False);
                self.title("Pong");
                
                self.bind("<Key-z>", lambda event: self.playerMove(event, -10));
                self.bind("<Key-s>", lambda event: self.playerMove(event, 10));
                self.newGame();
                self.evolve();
                self.mainloop();
                
            def playerMove(self, event, dy):
                self.__player.move(0, dy, width=self.__width, height=self.__height);
                
            def newGame(self):
                x = randrange(0, self.__width);
                self.__ball.setCoords(x, randrange(0, self.__height));
                
                if (x <= self.__width // 2): self.__ball.setDeltax(1);
                else: self.__ball.setDeltax(-1);
                self.__ball.setDeltay(choice([-1, 1]));
                
            def evolve(self):
                (x11, y11, x12, y12) = self.__player.getCoords();
                (x21, y21, x22, y22) = self.__ia.getCoords();
                self.__canvas.coords(self.__player.getId(), x11, y11, x12, y12);
                self.__ball.evolve(width=self.__width, height=self.__height,
                                   players={'first': {'xmin': x11, 'xmax': x12, 'ymin': y11, 'ymax': y12},
                                            'second': {'xmin': x21, 'xmax': x22, 'ymin': y21, 'ymax': y22}});
                (x1, y1, x2, y2) = self.__ball.getCoords();
                
                if (self.__move == Game.__MOVE_WAIT):
                    if (y1 < y21): self.__ia.move(0, -10, width=self.__width, height=self.__height);
                    if (y2 > y22): self.__ia.move(0, 10, width=self.__width, height=self.__height);
                    self.__move = 0;
                else: self.__move += 1;
                self.__canvas.coords(self.__ia.getId(), x21, y21, x22, y22);
                
                if (x1 <= 0 or x2 >= self.__width): self.newGame();
                self.__canvas.coords(self.__ball.getId(), self.__ball.getCoords());
        
                self.after(10, self.evolve);
            
                
        if (__name__ == "__main__"):
            Game(640, 480);

        Au moins, tu comprendras plus facilement de quoi je parle.

        • Partager sur Facebook
        • Partager sur Twitter
          18 août 2014 à 13:15:57

          Ok, j'ai compris ce que tu voulais dire.

          Ce que je te propose, c'est d'utiliser deux bind pour chaque touche: un bind pour détecter l'appui de la touche, et un autre pour détecter le relâchement de la touche.

          à l'appui de la touche, tu lance une boucle while qui tournera tant que une variable self.flag sera à true, et au relâchement de la touche, tu passes  cette variable à false.

          Les "bindings" correspondants sont:

          • Keypress-z
          • KeyRelease-z
          • KeyPress-s
          • KeyRelease-s
          • Partager sur Facebook
          • Partager sur Twitter
          Bevet Breizh! Breizh dizalc'h! Betek an trec'h! Ha mallozh ruz d'ar c'hallaoued! Trouvez votre voie
            18 août 2014 à 13:36:51

            Merci bien, j'ai essayé car j'ai trouvé cette solution sur le net, sauf que le relâchement de la touche est détecté alors que l'on reste appuyé dessus. En fait, j'ai l'impression que Tkinter considère le fait de rester appuyé comme un série de pression/relâchement.

            Bon, je vais quand même tenter, je verrais bien.

            EDIT: Etrangement, Tkinter ne répond plus de la même manière aujourd'hui, et la touche est effectivement considérée comme relâchée au moment attendu, j'ai dû me gourer hier. Merci bien pour ta solution.

            Ah oui, et quelle est la différence entre <Key> et <KeyPress> ?

            -
            Edité par raphaeljorel 18 août 2014 à 14:04:38

            • Partager sur Facebook
            • Partager sur Twitter
              18 août 2014 à 17:40:51

              raphael_m4a1 a écrit:

              Ah oui, et quelle est la différence entre <Key> et <KeyPress> ?

              Aucune, mais ça rend ton code clair et concis quand tu utilise <KeyPress>;)

              Si c'est résolu, Indique-le avec le bouton résolu:)

              • Partager sur Facebook
              • Partager sur Twitter
              Bevet Breizh! Breizh dizalc'h! Betek an trec'h! Ha mallozh ruz d'ar c'hallaoued! Trouvez votre voie
                19 août 2014 à 23:07:21

                Ok merci beaucoup, le problème est résolu maintenant.
                • Partager sur Facebook
                • Partager sur Twitter

                [Tkinter] Binding

                × 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