Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Pygame] Problème avec animations et événements

Sujet résolu
    10 août 2018 à 20:27:23

    Bonjour,

    Je n'avais pas beaucoup de place dans le titre, je m'explique.
    J'ai fini le TP du jeu Donkey Kong sur Pygame, et je voudrais l'améliorer, par exemple en y rajoutant des animations faites à partir de boucles whiles, de time.sleep() et de sprites.

    Voyez par exemple cet écran d'accueil, je voudrais faire une animation des flèches pour la sélection du niveau, qui s'écartent et se rapprochent toutes les 0,5 secondes.

    Mais je voudrais que Pygame continue à recevoir les événements (donc celui où la touche "Entrée" est appuyée), pendant qu'il fasse l'animation des flèches, que je fais donc grâce à des boucles while. Des idées ? Merci d'avance ! (Une fois terminé je mettrais le projet sur Github pour ceux qui veulent jouer ou regarder le code)

    Pour mieux comprendre ce que je recherche à faire, vous pouvez aussi imaginer un timer, qui s'incrémente en même temps qu'on joue.

    La boucle du menu :

    (J'ai un peu tout commenté pour mieux comprendre :D)

    import pygame
    import constants
    import classes
    from pygame import *
    from constants import *
    
    pygame.init()
    
    pygame.display.set_icon(icon) #D'ailleurs l'icône ne veut pas s'afficher et je ne comprends absolument pas pourquoi 
    pygame.display.set_caption("DK's Maze !")
    
    window = pygame.display.set_mode(size)
    Game = classes.Game(window)
    
    Game.home() #Affichage du menu
    
    pygame.key.set_repeat(400, 30) #On permet la répétition de touches, si on reste appuyé dessus
    run = 1
    ingame = 0
    level = 1
    while run:
        while ingame == 0:
            pygame.time.Clock().tick(30) #On évite de surchauffer le processeur
            Game.select(level)
            for event in pygame.event.get():
                if event.type == QUIT:
                    run = 0
                if event.type == KEYDOWN:
                    if event.key == K_RETURN: #Si l'on séléctionne un niveau, on fait une instance de Donkey et on initialise le niveau
                        Donkey = classes.Donkey(window, level)
                        Game.initlevel(level)
                        pos_donkey = [0, 0]
                        home = 0
                        ingame = 1
                        Game.level()
                    if event.key == K_DOWN or event.key == K_UP: #On bouge les flèches si l'on appuie sur la touche Bas ou Haut
                        if level == 1:
                            level = 2
                        else:
                            level = 1
                    if event.key == K_ESCAPE:
                        exit()


    La classe Game :

    import pygame
    import constants
    from pygame import *
    from constants import *
    from time import sleep
    
    pygame.init()
    
    
    class Game:
        def __init__(self, window):
            self.lines = []
            self.window = window
    
        def home(self):
        #Affiche le menu
            self.window.blit(home, (0, 0))
            pygame.display.flip()
    
        def select(self, level):
        #On déplace les flèches en fonction de la touche appuyée (Haut / Bas)
            if level == 1:
                self.home()
                self.window.blit(select1, (0, 0)) #select1 = Flèches écartées sur le choix du niveau 1
                sleep(0.5)
                self.window.blit(select1b, (0, 0)) #select1b = Flèches rapprochées sur le choix du niveau 1
            if level == 2:
                self.home()
                self.window.blit(select2, (0, 0)) #select2 = Flèches écartées sur le choix du niveau 2
                sleep(0.5)
                self.window.blit(select2b, (0, 0)) #select2b = Flèches rapprochées sur le choix du niveau 2
            pygame.display.flip()
    
        def initlevel(self, level):
        #On lit les lignes du fichier de niveau en fonction du niveau choisi, pour les réutiliser après
            name = "levels/lev" + str(level)
            with open(name, "r") as file:
                self.lines = file.readlines()
            file.close()
            self.dkstart = True
            return self.lines
    
        def level(self):
        #On affiche le niveau grâce aux lignes du fichier de niveau
            self.window.blit(background, (0, 0))
            y = 0
            for line in self.lines:
                x = 0
                for chara in line:
                    if chara == "d":
                        self.window.blit(start, (x, y))
                    if chara == "w":
                        self.window.blit(brick, (x, y))
                    if chara == "a":
                        self.window.blit(end, (x, y))
                    x += 30
                y += 30
            if self.dkstart == True:
            #Permet d'initialiser Donkey Kong sur la case de départ seulement au début
                self.window.blit(dkdown, (0, 0))
            self.dkstart = False
            pygame.display.flip()



    -
    Edité par fokushy 11 août 2018 à 13:28:55

    • Partager sur Facebook
    • Partager sur Twitter
      11 août 2018 à 18:31:40

      Salut :)

      Solution radicale : arrêter les boucles while et for ainsi que les time.sleep() quand on construit une interface graphique.

      Pourquoi ? Ces manipulations sont bloquantes : tant que la boucle ou le temps inscrit dans sleep n'est pas fini, le programme se fige.

      Comment y remédier ? Utiliser les méthodes de temps fournies par l'outil de création d'interface et gérer ce temps avec une condition if. Ça fait un moment que je n'ai plus touché à pygame, mais, avec mes infos et quelques recherches tu trouveras rapidement des tutos expliquant cela. Je te mâche un peu ce travail de recherche, va sur le profil de Dan737 sur ce forum, il a une FAQ sur tkinter concernant la gestion du temps, et même, des vidéos tutos de  pygame, dont une, justement, sur la gestion du temps.

      • Partager sur Facebook
      • Partager sur Twitter
        12 août 2018 à 2:27:41

        Salut Le Cobreiste, merci de ton conseil, néanmoins j'ai trouvé la solution à mon problème, il fallait utiliser la méthode pygame.time.set_timer().   :D

        Je vous renvoie donc sur le topic qui m'a aidé à résoudre mon problème : https://www.developpez.net/forums/d1882165/autres-langages/python-zope/bibliotheques-tierces/pygame-probleme-animer-recevoir-evenements-meme-temps/#post10412203

        -
        Edité par fokushy 12 août 2018 à 2:28:40

        • Partager sur Facebook
        • Partager sur Twitter

        [Pygame] Problème avec animations et événements

        × 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