Problème avec l'affichage d'un sprite avec PyGame

Résolu
Enz0lanterne828 Messages postés 50 Statut Membre -  
Enz0lanterne828 Messages postés 50 Statut Membre -
Bonjour,

J'ai 12 ans et je débute en python.
En ce moment je m'entraine à créer des jeux avec le module PyGame.

J'ai créer un jeu où j'aimerais ajouter un bouton jouer sur la fenêtre et faire en sorte que lorsque qu'on clique sur le bouton, le bouton change de couleur pendant 0.1 secondes puis qu'il disparaisse et que 2 autres bouton apparaissent.

J'ai commencé mon projet avec une fenêtre en plein écran mais lorsque j’essaye de faire apparaitre le bouton, il n’apparait pas...

Voilà les parties du code ou j'essaye de faire apparaître le bouton:
# Créer le bouton jouer
class BoutonJouer(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('bouton/jouer.png')
        self.rect = self.image.get_rect()
        self.rect.x = 400
        self.rect.y = 250*


# Bouton jouer du menu principale
bouton_jouer_menu_pricipale = bouton_jouer.BoutonJouer()


# Appliquer le bouton jouer sur le menu principale
    screen.blit(bouton_jouer_menu_pricipale.image, bouton_jouer_menu_pricipale.rect)



Je ne comprends pas pourquoi le bouton ne veux pas s'afficher alors que tout est correcte normalement...

Merci d'avance, cordialement

9 réponses

  1. trifou
     
    Bonsoir,

    As-tu fait la mise à jour de la fenêtre après le blit avec
    pygame.display.flip()
    ou
    pygame.display.update()
    ?
    4
  2. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Bon, je suis plutôt fière de moi :-)

    J'ai réussi à faire en sorte que le bouton change quand on clique dessus et qu'il disparaisse en suite, mais le problème c'est que je n'arrive pas à faire les deux en même temps...

    Je m'explique, j’arrive à changer l'image du bouton quand on clique dessus mais j'aimerai mettre un temps de latence avant que le bouton ne disparaisse sinon on ne pourra pas voir le bouton changer de couleur (tout ça est esthétique mais j'aime quand c'est beau donc j'ai pris une heure de mon temps pour finir le menu principale.)

    Et là viens le problème, j'ai essayer d'ajouter la commande
    pygame.time.delay(500)
    mais ça ne faisait pas comme je le voulais voici ce que j'ai écris en détaille:
    # Vérifier si le bouton jouer est cliqué
            if event.type == pygame.MOUSEBUTTONDOWN:
                if menu.bouton_jouer_menu_pricipale.rect.collidepoint(event.pos):
    
                    # Changer l'image du bouton
                    menu.bouton_jouer_menu_pricipale.image = menu.bouton_jouer_menu_pricipale.image_clique
                    pygame.time.delay(500)
    
                    # Passer au menu suivant (retirer le bouton, le texte et l'arrière-plan)
                    menu.menu_principale = False
                    menu.menu_2 = True
    


    PyGame fait le temps de latence après; lorsque je cliques sur le bouton à ce moment là la commande
    pygame.time.delay(500)
    s'exécutait (alors que moi je voulais qu'elle s'exécute une fois que le bouton à changer de couleur...

    Sinon merci d'avoir pris du temps pour me répondre, cordialement :-)
    1
    1. trifou
       
      Bonsoir,

      Je n'ai pas compris pourquoi si c'est un bouton de menu, il doit disparaître si on clique dessus.

      Plutôt que pygame.time.delay qui est comme un time.sleep, sers-toi de
      pygame.time.set_timer()
      qui permet de gérer un événement personnel.

      Lorsque l'utilisateur clique sur ton bouton, tu définis un event avec pygame.time.set_timer(), ainsi lors des prochains tours, si ce type d'event est dans l'event de ta boucle, tu supprimes ton bouton et tu annules ton event.
      0
  3. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Je pense que je me suis mal expliqué...

    Je veux faire en sorte que, une fois le bouton cliqué il change de couleur puis que 0.5 secondes après il disparaisse et laisse place à deux autre boutons.
    Sauf que le
    time.sleep(x)
    ne me conviens pas car il met en pause tout le programme alors que je voudrais mettre en pause seulement le bouton une fois qu'il a changé de couleur puis 0.5 secondes après, qu'il disparaisse. /-:

    Pour la commande
    pygame.time.set_timer()
    je n'ai pas bien compris son utilité et de ce que j'ai compris ce n'est pas ce que je recherche...

    Merci, cordialement
    1
    1. trifou
       
      pygame.time.set_timer sert à programmer un event personnel dans le temps.

      Voici un simple exemple avec une simple surface pour bouton.

      import pygame as pg
      
      SCREEN_COLOR = (25, 255, 255)
      
      class Button(pg.sprite.Sprite):
          def __init__(self):
              super().__init__()
              self.image = pg.Surface((100, 50))
              self.image.fill((255, 0, 0))
              self.rect = self.image.get_rect()
      
      
      screen = pg.display.set_mode((400, 400))
      screen.fill(SCREEN_COLOR)
      
      button = Button()
      button.rect.center = 200, 200
      
      screen.blit(button.image, button.rect)
      pg.display.update()
      
      clock = pg.time.Clock()
      running = True
      # identifiant de l'event pour la suppression du bouton
      BUTTON_DELETE_EVENT = pg.USEREVENT
      
      while running:
          clock.tick(30)
          for evt in pg.event.get():
              if evt.type == pg.QUIT or (
                  evt.type == pg.KEYUP and evt.key == pg.K_ESCAPE
              ):
                  running = False
                  break
              elif evt.type == pg.MOUSEBUTTONDOWN:
                  if button.rect.collidepoint(evt.pos):
                      # Changement de le couleur du bouton
                      button.image.fill((255, 255, 0))
                      # Création d'un event qui sera envoyé par pygame dans event.get
                      # après 1,5 secondes
                      pg.time.set_timer(BUTTON_DELETE_EVENT, 1500)
                      screen.blit(button.image, button.rect)
                      pg.display.update(button.rect)
              elif evt.type == BUTTON_DELETE_EVENT:
                  # On attrape notre event et on le désactive en le redéfinissant
                  # avec 0 ms
                  pg.time.set_timer(BUTTON_DELETE_EVENT, 0)
                  # Remplissage de la couleur de l'écran dans le rect du bouton
                  screen.fill(SCREEN_COLOR, button.rect)
                  pg.display.update(button.rect)


      Comme tu utilises des sprites, il faudra t'intéresser plus tard aux groupes de sprites.
      0
  4. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Merci beaucoup, mon programme fonctionne à merveille j'ai galéré à trouver comment ça marche mais au bout d'une heure j'ai compris, merci beaucoup !!
    1
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Ha non j'avais oublié, merci !

    Mais est-ce normal que le bouton clignote ?
    0
    1. trifou
       
      Non ce n'est pas normal, il faudrait que tu montres ton code pour voir ce qui cloche.
      0
  7. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Voilà mon code:

    *FICHIER MAIN: *
    
    import pygame
    import time
    from bouton import bouton_jouer
    
    pygame.mixer.init()
    
    pygame.init()
    
    # Fenêtre du jeu
    pygame.display.set_caption("ElementaryQuest")
    icon = pygame.image.load('window/icon.png')
    pygame.display.set_icon(icon)
    screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
    
    # Son du jeu
    menu_music = pygame.mixer.Sound('music/menu_music.wav')
    menu_music.play(loops=1000, fade_ms=5000)
    
    # Arrière-plan du menu principale
    background = pygame.image.load('window/background.jpg')
    
    # Bouton jouer du menu principale
    bouton_jouer_menu_pricipale = bouton_jouer.BoutonJouer()
    
    running = True
    menu = True
    
    
    # Boucle du jeu
    while running:
    
        # Boucle du menu pricipale
        # Applique l'arrière-plan du menu principale
        screen.blit(background, (0, 0))
        pygame.display.flip()
    
        # Appliquer le bouton jouer sur le menu principale
        screen.blit(bouton_jouer_menu_pricipale.image, bouton_jouer_menu_pricipale.rect)
        pygame.display.update()
    
        # Si le joueur ferme la fenêtre
        for event in pygame.event.get():
    
            # Vérifier que l'événement est fermeture de fenêtre
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    time.sleep(0.25)
                    running = False
                    pygame.quit()
                    print("Fermeture du jeu en cours, veuillez patienter...")
                    time.sleep(3)
                    print("Le jeu à bien été fermé !")
    
            # Vérifier que l'événement est clique
            if event.type == pygame.MOUSEBUTTONDOWN:
                print('Souris cliqué')
    
    
    *FICHIER BOUTON_JOUER: *
    
    import pygame
    
    
    # Créer le bouton jouer
    class BoutonJouer(pygame.sprite.Sprite):
        def __init__(self):
            super().__init__()
            self.image = pygame.image.load('bouton/bouton_jouer.png')
            self.rect = self.image.get_rect()
            self.rect.x = 550
            self.rect.y = 600
    
    0
    1. trifou
       
      Bonjour,

      J'ai répondu hier, mais mon message n'a pas été pris en compte :/

      Il faut s'arranger à n'avoir qu'un seul update (ou flip) dans la boucle, donc faire un update après avoir fait tous les blit sur la fenêtre.
      0
  8. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Ha oui merci tout fonctionne !
    0
  9. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Mais j'ai une petite question pour le bouton:

    Comment faire pour que PyGame détecte le fait que je clique sur le sprite ?

    Merci, cordialement
    0
    1. trifou
       
      Bonsoir,

      C'est avec le rect du sprite que tu dois faire cette vérification.
      Jette un oeil dans les méthodes de Rect (les méthodes collide*)

      Pour la coordonnée du clic, tu dois pouvoir récupérer ça avec
      event.pos
      dans ta boucle.
      0
  10. Enz0lanterne828 Messages postés 50 Statut Membre 8
     
    Ok merci, je vais regarder ça !
    0