Partage
  • Partager sur Facebook
  • Partager sur Twitter

retard pygame

    26 janvier 2015 à 21:09:07

    bonjour, je debute sur pygame et je me suis mis a la création d'un petit jeu de combat, cependant, je bloque pour créer une attaque:

    je souhaite que quand mon perso met un coup de poing, l'animation du coup de poing dure 0.5sec avant que le perso ne revienne a sa position d'origine. cependant, je pensais que mettre un retard entre l'apparition des 2 images fonctionnerais, ce n'est malheureusement pas le cas. pouvez vous m'aider svp?

    voici mon code

            if event.type==KEYDOWN:
                if event.key==K_d:
                    perso = pygame.image.load("perso_poing.png")
                    pygame.time.delay(500)
                    perso = pygame.image.load("perso.png")



    • Partager sur Facebook
    • Partager sur Twitter
      26 janvier 2015 à 21:55:39

      pygame.image.load ne fait que charger l'image en mémoire et la place dans une Surface. C'est à faire durant l'initialisation de ton jeu. Pour afficher qqch à l'écran, tu dois le blitter sur la surface de ton écran.

      -
      Edité par Dan737 26 janvier 2015 à 21:55:58

      • Partager sur Facebook
      • Partager sur Twitter
        26 janvier 2015 à 22:02:19

        je sais, je n'ai posté que l'endroit qui me pose probleme, mais comme il semblerait que ca ne soit pas suffisant, je vais mettre tout le code
        import pygame
        from pygame import*
        
        clock= pygame.time.Clock()
        pygame.init()
        screen = pygame.display.set_mode((1280, 720), RESIZABLE)
        
        fond = pygame.image.load("fond.png")
        screen.blit(fond,(0,0))
        
        poing = pygame.mixer.Sound("poing.wav")
        
        x_perso=100
        y_perso=400
        perso = pygame.image.load("perso.png")
        
        pygame.key.set_repeat(1, 15)
        
        while not pygame.key.get_pressed() [K_ESCAPE]:
            for event in pygame.event.get():
                #limites
                if y_perso<=0:
                    y_perso=0
                if y_perso>=400:
                    y_perso=400
                    perso = pygame.image.load("perso.png")
                if x_perso>=1100:
                    x_perso=1100
                if x_perso<=0:
                    x_perso=0
                #deplacement droite-gauche
                if event.type==KEYDOWN:
                    if event.key==K_RIGHT:
                        perso = pygame.image.load("perso_move1.png")
                        x_perso=x_perso+30
                        print("x_perso=", x_perso)
                if event.type==KEYDOWN:
                    if event.key==K_LEFT:
                        x_perso=x_perso-30
                        perso = pygame.image.load("perso_move2.png")
                        print("x_perso=", x_perso)
                #voler
                if event.type==KEYDOWN:
                    if event.key==K_UP:
                        y_perso=y_perso-30
                        perso = pygame.image.load("perso_saut.png")
                        print("y_perso=", y_perso)
                if event.type==KEYDOWN:
                    if event.key==K_DOWN:
                        y_perso=y_perso+30
                        print("y_perso=", y_perso)
                        perso = pygame.image.load("perso_saut.png")
                #coups
                if event.type==KEYDOWN:
                    if event.key==K_d:
                        poing.play()
                        pygame.key.set_repeat(1, 15)
                        perso = pygame.image.load("perso_poing.png")
                        pygame.time.delay(1000)
                        perso = pygame.image.load("perso.png")
        
        
            clock.tick(60)
            screen.blit(fond,(0,0))
            screen.blit(perso,(x_perso,y_perso))
            pygame.display.flip()
        
        
        
        
        pygame.quit()
        
        • Partager sur Facebook
        • Partager sur Twitter
          26 janvier 2015 à 22:15:38

          ethir60 a écrit:

          je sais

          Ah oui? ;)

          Je vais me répéter alors. pygame.image.load ne fait que charger l'image en mémoire et la place dans une Surface. C'est à faire durant l'initialisation de ton jeu. Pour afficher qqch à l'écran, tu dois le blitter sur la surface de ton écran.

          Tu blites à la ligne 64 - 65.

          Donc si je pousse sur la touche 'flèche du bas', il joue le son poing. Il charge en mémoire le fichier perso_poing.png qu'il met dans une surface appelée perso. On attend 1 seconde. On écrase l'image qu'on vient de charger par une autre image perso.png (mais on n'a jamais rien affiché sur l'écran).

          Seulement on arrive en ligne 63. Le pauvre, on lui dit qu'il faut 60 images à la seconde et on vient de passer 1000ms à attendre juste avant... Enfin il se dit qu'il est bien en retard alors il passe à la suite.

          On blit le fond. On blit le perso (donc perso.png) On flip, donc on voit ce qu'on vient de blitter.

          Tu vois le problème?

          -
          Edité par Dan737 26 janvier 2015 à 22:16:59

          • Partager sur Facebook
          • Partager sur Twitter
            26 janvier 2015 à 22:33:53

            Aaaaaaah, je comprends pouquoi ca ne marchait pas... desolé pour les "je sais" qui peut parraitre arrogant :s.j avais deja esseyer en mettant le blit juste apres mais ca ne fonctionnait tjrs pas mais je pense que c est justement parceque je n ai pas mis le flip apres :s. Merci de ton aide :)
            • Partager sur Facebook
            • Partager sur Twitter
              26 janvier 2015 à 22:55:52

              Pas de soucis, j'ai pas pris ça pour de l'arrogance. C'est juste qu'en venant demander de l'aide, il faut bien lire ce qu'on t'écrit.

              Sinon ton problème de base ne va pas être résolu juste en mettant un blit et un flip. Car avec ton delay(1000), le programme ne va vraiment RIEN faire du tout pendant toute une seconde.

              Il te faut en fait récupérer le temps à chaque tour de boucle dans la boucle while. En ligne 63, tu pourrais faire dt = clock.tick(60). Donc dt contiendra le temps en ms depuis la dernière fois que clock.tick() a été appelé. Tu peux alors utiliser ce temps pour faire incrémenter un compteur. Une fois un certain temps passé, tu fais qqch d'autre (genre tu changes d'image).

              Voici un exemple (non testé !!! car j'ai pas d'image et pas le temps de m'en faire pour tester :) ). Mais ça te donnera une idée très basique. En plus propre, il faut mettre tout ça dans des classes, sinon ça va vite devenir le bordel. ;)

              !/usr/bin/env python3

              -- coding: utf-8 --

              import pygame from pygame import*

              clock= pygame.time.Clock() pygame.init() screen = pygame.display.set_mode((1280, 720), RESIZABLE)

              fond = pygame.image.load("fond.png").convert_alpha()

              poing = pygame.mixer.Sound("poing.wav")

              x_perso=100 y_perso=400

              perso_normal = pygame.image.load("perso.png").convert_alpha() perso_droit = pygame.image.load("perso_move1.png").convert_alpha() perso_gauche = pygame.image.load("perso_move2.png").convert_alpha() perso_saut = pygame.image.load("perso_saut.png").convert_alpha() perso_poing = pygame.image.load("perso_poing.png").convert_alpha()

              perso = perso_normal

              pygame.key.set_repeat(1, 15)

              running = True frame_counter = None

              while running:

              dt = clock.tick(60)
              # Check pour l'animation du poing
              if frame_counter is not None:
                  frame_counter += dt
                  if frame_counter > 1000:
                      perso = perso_normal
                      frame_counter = None
              
              for event in pygame.event.get():
                  
                  #deplacement droite-gauche
                  if event.type==KEYDOWN:
                      if event.key==K_ESCAPE:
                          running = False
                          
                      elif event.key==K_RIGHT:
                          perso = perso_droit
                          x_perso=x_perso+30
                          print("x_perso=", x_perso)
              
                      elif event.key==K_LEFT:
                          x_perso=x_perso-30
                          perso = perso_gauche
                          print("x_perso=", x_perso)
                      #voler
                      elif event.key==K_UP:
                          y_perso=y_perso-30
                          perso = perso_saut
                          print("y_perso=", y_perso)
              
                      elif event.key==K_DOWN:
                          y_perso=y_perso+30
                          print("y_perso=", y_perso)
                          perso = perso_saut
                      #coups
                      elif event.key==K_d:
                          poing.play()
                          perso = perso_poing
                          frame_counter = 0
              
              #limites
              if y_perso<=0:
                  y_perso=0
              if y_perso>=400:
                  y_perso=400
                  perso = perso_normal
              if x_perso>=1100:
                  x_perso=1100
              if x_perso<=0:
                  x_perso=0
              
              screen.blit(fond,(0,0))
              screen.blit(perso,(x_perso,y_perso))
              pygame.display.flip()
              

              pygame.quit()

              </pre>
              • Partager sur Facebook
              • Partager sur Twitter
                27 janvier 2015 à 19:21:06

                merci de ton aide, cependant, je n'ai pas fais comme toi car je ne sais pas utiliser les clock, j'ai mis une valeur a une variable "coup" pourque ca se rapporte a un if apres mon actualisation, ainsi il actualiste tout et me remet mon image apres et ca marche tres bien :D

                import pygame
                from pygame import*
                
                coup=0
                special=0
                kamehameha=0
                
                clock= pygame.time.Clock()
                pygame.init()
                screen = pygame.display.set_mode((1280, 720), RESIZABLE)
                fond = pygame.image.load("fond.png")
                pygame.key.set_repeat(1, 15)
                
                #sons
                poing = pygame.mixer.Sound("poing.wav")
                
                #perso
                x_perso=100
                y_perso=400
                perso_normal= pygame.image.load("perso.png")
                perso_droite=pygame.image.load("perso_move1.png")
                perso_gauche=pygame.image.load("perso_move2.png")
                perso_vol= pygame.image.load("perso_saut.png")
                
                perso_poing=pygame.image.load("perso_poing.png")
                perso_pied=pygame.image.load("perso_pied.png")
                perso_charge=pygame.image.load("charge.png")
                perso_kamehameha=pygame.image.load("kamehameha.png")
                
                while not pygame.key.get_pressed() [K_ESCAPE]:
                    for event in pygame.event.get():
                        #limites
                        if y_perso<=0:
                            y_perso=0
                        if y_perso>=390:
                            y_perso=400
                            perso = perso_normal
                        if x_perso>=1100:
                            x_perso=1100
                        if x_perso<=0:
                            x_perso=0
                        if event.type==KEYDOWN:
                            if event.key==K_RIGHT:
                                perso = perso_droite
                                x_perso=x_perso+30
                                print("x_perso=", x_perso)
                        if event.type==KEYDOWN:
                            if event.key==K_LEFT:
                                x_perso=x_perso-30
                                perso = perso_gauche
                                print("x_perso=", x_perso)
                        #voler
                        #diagonales
                        if key.get_pressed() [K_RIGHT] and key.get_pressed() [K_UP]:
                            x_perso=x_perso+20
                            y_perso=y_perso-20
                        if key.get_pressed() [K_LEFT] and key.get_pressed() [K_UP]:
                            x_perso=x_perso-20
                            y_perso=y_perso-20
                        if key.get_pressed() [K_RIGHT] and key.get_pressed() [K_DOWN]:
                            x_perso=x_perso+20
                            y_perso=y_perso+20
                        if key.get_pressed() [K_LEFT] and key.get_pressed() [K_DOWN]:
                            x_perso=x_perso-20
                            y_perso=y_perso+20
                        #haut-bas
                        if event.type==KEYDOWN:
                            if event.key==K_UP:
                                y_perso=y_perso-30
                                perso = perso_vol
                                print("y_perso=", y_perso)
                        if event.type==KEYDOWN:
                            if event.key==K_DOWN:
                                y_perso=y_perso+30
                                print("y_perso=", y_perso)
                                perso = perso_vol
                        #coups
                        if event.type==KEYDOWN:
                            if event.key==K_d:
                                poing.play()
                                pygame.key.set_repeat(1, 15)
                                perso = perso_poing
                                coup=1
                        if event.type==KEYDOWN:
                            if event.key==K_f:
                                poing.play()
                                pygame.key.set_repeat(1, 15)
                                perso = perso_pied
                                coup=1
                        if event.type==KEYDOWN:
                            if event.key==K_g:
                                pygame.key.set_repeat(1, 15)
                                perso= perso_charge
                                kamehameha=1
                
                    clock.tick(60)
                    screen.blit(fond,(0,0))
                    screen.blit(perso,(x_perso,y_perso))
                    pygame.display.flip()
                    if coup==1:
                        pygame.display.flip()
                        pygame.time.delay(250)
                        perso=perso_normal
                        coup=0
                    if kamehameha==2:
                        pygame.display.flip()
                        pygame.time.delay(1000)
                        perso=perso_normal
                        kamehameha=0
                    if kamehameha==1:
                        pygame.display.flip()
                        pygame.time.delay(1000)
                        perso=perso_kamehameha
                        kamehameha=2
                
                pygame.quit()
                

                comme tu peux le voir, j'ai suivis ton conseil concernant le rangement de mes images

                • Partager sur Facebook
                • Partager sur Twitter
                  27 janvier 2015 à 19:45:31

                  Avec ton exemple, tu ne pourras pas en même temps avoir un autre personnage qui bouge ou répondre à des inputs de l'utilisateur. Le delay va bloquer ton programme, et tu ne pourras plus lire les événements claviers ou autre. Tu ne pourras même pas quitter le jeu en poussant sur la touche Escape.

                  L'utilisation de clock est vraiment simple. Lorsque tu appelles tick, la fonction te renvoit le temps passé depuis le dernier appel à tick. Le fait de passer le paramètre 60 fait que si le temps passé depuis le dernier appel est trop court, il fait une pause pour arriver à 60 tour de boucle par seconde. La doc l'explique assez bien.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    27 janvier 2015 à 19:59:48

                    mmm je comprends ce que tu veux dire, je n'y avais pas pensé : , du moins je ne vois pas a quoi correspond le +=s. mais sinon je ne vois pas a quoi correspond le frame_counter +=dt , du moins je ne vois pas a quoi correspond le +=
                    • Partager sur Facebook
                    • Partager sur Twitter
                      27 janvier 2015 à 20:01:26

                      oups petite erreur dans le message : mmm je comprends ce que tu veux dire, je n'y avais pas pensé :s. mais sinon je ne vois pas a quoi correspond le frame_counter +=dt , du moins je ne vois pas a quoi correspond le +=
                      • Partager sur Facebook
                      • Partager sur Twitter
                        27 janvier 2015 à 21:42:14

                        J'avoue que le nom de ma variable frame_counter n'est vraiment pas approprié. Tu pourrais le remplacer par animation_timer par exemple.

                        Imagine que nous somme dans la boucle while en ligne 31, et imagine qu'on a appuyé sur la touche 'd'. En ligne 67, on vérifie si on a un appuis de touche 'd' dans la queue des événements. Ce qui est le cas. Donc on joue le son, on change l'image du perso et on initialise la variable frame_counter (que tu pourrais renommer animation_timer à 0). A partir de maintenant on va continuer à tourner dans la boucle while, mais on fait tenir compte du temps qui passe et attendre qu'une seconde soit écoulée (1000 ms donc). Lorsque ce sera le cas, on remplacera à nouveau le personnage par son image normale et on sera revenu à l'état initial du programme.

                        En ligne 32, dt contient le nombre de milliseconde depuis la dernière fois qu'on a fait un tour de boucle. Imaginons qu'il se soit passé 20 ms. Donc dt vaut 20. Ligne 34 on regarde si frame_counter n'est pas None. Non, car c'est 0. Ligne 35, on incrémente frame_counter de la valeur de dt. Cette notation revient à écrire: frame_counter = frame_counter + dt. frame_countervaut 0 et dt vaut 20. Donc maintenant frame_counter vaut 20. Ligne 36 on vérifie si frame_counter vaut plus que 1000. Non ce n'est que 20. On continue. On regarde les événements pygame (imaginons qu'il n'y a rien) et ensuite en ligne 83-85 on blit le fond, le perso et on affiche le tout à l'écran.

                        On retourne en ligne 31 où running vaut toujours True. Donc on refait un tour de boucle. Ligne 32, dt va maintenant contenir le nombre de ms depuis le dernier passage. Imaginons 25 ms. Tout le reste est le même et frame_counter qui valait 20 est incrémenté de 25. Donc ça vaut 45. Et ainsi de suite jusqu'à ce qu'on ait fait assez de tour de boucle while pour que frame_counter soit supérieur à 1000. Et ça se passera donc 1 seconde (et quelques millièmes de secondes) après qu'on ait appuyé sur la touche 'd'. Là on est en ligne 36 qui est vérifiée. Ligne 37, on remet le personnage normal dans la variable perso. Note que perso ne sera blitté qu'en ligne 84! En ligne 38 on assigne à frame_counter la valeur None, ainsi au prochain tour de boucle la condition en ligne 34 ne sera plus réalisée.

                        Est-ce plus clair?

                        Bien entendu, ceci est un exemple simpliste pour te montrer les mécanismes de base. Il est évident que le timing de l'animation devrait faire partie d'une classe Animation ou autre.

                        • Partager sur Facebook
                        • Partager sur Twitter

                        retard pygame

                        × 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