Partage
  • Partager sur Facebook
  • Partager sur Twitter

Gestion de thead et pygame

    11 janvier 2023 à 14:44:57

    Bonjour, je m'aide au possible d'autres ressources pour avancer mais là je suis bloqué de chez bloqué !
    à deux doigts de rebrousser chemin et de virer mon thread qui est là juste pour la gestion des event souris (survol).

    Donc, si vous souhaitez bien m'aider, avec grand plaisir.

    Je vais essayé de simplifier mon code, mais en gros c'est un programme de simulation d'interactions entre entités (des pixels).

    Donc y a des pixels qui se baladent sur l'écran, au survol avec la souris, c'est sensé donné les infos sur l'entité, ça fonctionnait bien sans le thread.

    Mais depuis que j'ai voulu le mettre, le curseur, de une, est en mode chargement constamment, les pixels bougent bien etc, jusque ce que je clique gauche et là ça fige tout.

    Merci d'avance pour les réponses je vous laisse des parties du code :

    import random
    import pygame
    import sys
    import colorsys
    import math
    import threading
    
    # Dimensions de la fenêtre
    WIDTH = 100
    HEIGHT = 100
    
    [...]
    
    # Dictionnaire des entites
    entites = {}
    
    # Initialisation de pygame
    pygame.init()
    pygame.display.init()
    # Création de la fenêtre
    screen = pygame.display.set_mode((WIDTH * PIXEL_SIZE, HEIGHT * PIXEL_SIZE))
    
    # Horloge pour limiter la fréquence de rafraîchissement
    clock = pygame.time.Clock()
    
    done = False
    
    [...]
    # initialisations des entités
    init_entites()
    
    # Initialisez un verrou
    lock = threading.Lock()
    
    # évènements de la souris
    def mouse_event_thread():
        global done
        global entites
        global text_entite
        global screen
        global lock
        while not done:
            for event in pygame.event.get():
                if event.type == pygame.MOUSEMOTION:
                    x, y = event.pos
                    x //= PIXEL_SIZE
                    y //= PIXEL_SIZE
                    mouse_pos = (x,y)
                    
                    if mouse_pos[0] > 0 and mouse_pos[0] < WIDTH and mouse_pos[1] > 0 and mouse_pos[1] < HEIGHT:
                        with lock:
                            entite_surbrillante = None
                            for coord, entite in entites.items():
                                if entite.rect.collidepoint(mouse_pos):
                                    entite_surbrillante = entite
                                    break
                            for coord, entite in entites.items():
                                if entite == entite_surbrillante:
                                    temp_rect = entite.rect.copy()
                                    temp_rect = pygame.Rect(entite.rect.x - 9, entite.rect.y - 9, entite.rect.width + 18, entite.rect.height + 18)
                                    temp_rect.center = entite.rect.center
    
                                    temp_rect.inflate_ip(-6, -6)
                                    text_entite = font.render("Entité {} : {} de coopération, {} points et {} interactions".format(determine_color(entite.color), str(entite.coop), str(entite.pts), str(entite.nb_d_interactions)), True, entite.color)
                                    
                                    # bordures du pixel affichées
                                    temp_rect.center = entite.rect.center
                                    pygame.draw.rect(screen, YELLOW, temp_rect, 2)
                                    screen.blit(text_entite, (0, 48))
                                    pygame.display.update()
                                    clock.tick(80/1000) # to prevent the loop from running too fast
                                    break
                    if (event.type == pygame.QUIT or event.key == pygame.K_q):
                        done = True
                        main_thread.join()
                        threading.current_thread().join()


    déjà j'ai mis les valeurs en global mais je sais pas si c'est nécessaire car elles sont en dehors des fonctions.

    ensuite j'ai fais du coup un thread principal et fin du prog :

    def main_loop():
        global done
        global lock
        paused = False
        time_counter = 0
        key_right_down = False
        
        while not done:
            with lock:
                pygame.event.pump()
                # Traitement des événements
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        done = True
                        main_thread.join()
                        mouse_event_thread.join()
                    elif event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_p:
                            paused = not paused
                        elif event.key == pygame.K_q:
                            highest_pts_pixel = get_highest_pts_pixel()
                            print(f"Le pixel ayant le plus de points est {highest_pts_pixel[0]} avec {highest_pts_pixel[1]} pts et {highest_pts_pixel[2]} de coopération.")
                            done = True
                            main_thread.join()
                            mouse_event_thread.join()
                        elif event.key == pygame.K_RIGHT:
                            key_right_down = True
                    elif event.type == pygame.KEYUP:
                        if event.key == pygame.K_RIGHT:
                            key_right_down = False
                        
                if paused:
                    continue
    
                time_counter += 1
                
                # update les positions des "entite.rect" avant de draw
                update()
                # dessine les pixels
                draw()
                
                # interactions 
                for entite in entites.values():
                    entite.interact()
                
                # Affichage du temps et du nombre d'entités
                font = pygame.font.Font(None, 36)
                time_text = font.render("Cycle " + str(time_counter), 1, WHITE)
                nb_entites_text = font.render("{} entités".format(len(entites)), 1, WHITE)
                screen.blit(time_text, (0, 0))
                screen.blit(nb_entites_text, (0, 26))
                
                # mise à jour de l'écran
                pygame.display.flip()
                
                # fonction de mouvements des entités
                move_entities()
                
                if key_right_down == True:
                    clock.tick(4)
                else: 
                    clock.tick(800/1000)
                    
    # init des threads
    mouse_event_thread = threading.Thread(target=mouse_event_thread)
    main_thread = threading.Thread(target=main_loop)
    # start 
    main_thread.start()
    mouse_event_thread.start()
    
    if done:
        main_thread.join()
        mouse_event_thread.join()
        pygame.quit()
        sys.exit()





    • Partager sur Facebook
    • Partager sur Twitter
      11 janvier 2023 à 15:00:17

      Alors déjà , faut filtrer la file d'événements si elle est partagée , sinon la plupart seront perdus .

      Ensuite , pourquoi un thread ?

      Poste tout le code pour que je puisse tester .

      • Partager sur Facebook
      • Partager sur Twitter

      Python c'est bon, mangez-en. 

        11 janvier 2023 à 15:15:45

        un thread parce que le programme gérait justement moyen le curseur et l'affichage selon celui-ci.

        Bon, ba voici le code complet :

        """ Programme sur les différentes interactions entre entités dont le comportement CRP (Coopération - Réciprocité - pardon) """
        
        import random
        import pygame
        import sys
        import colorsys
        import math
        import threading
        
        # Dimensions de la fenêtre
        WIDTH = 100
        HEIGHT = 100
        
        # Taille des pixels
        PIXEL_SIZE = 10
        
        # Couleurs
        BLACK = pygame.Color(0, 0, 0)
        WHITE = pygame.Color(255, 255, 255)
        RED = pygame.Color(240, 0, 32)
        BLUE = pygame.Color(14, 75, 239)
        YELLOW = pygame.Color(255, 255, 0)
        
        NB_DE_BLEU = 5
        NB_DE_ROUGE = 5
        NB_DE_BLANC = 5
        
        # Dictionnaire des entites
        entites = {}
        
        # Initialisation de pygame
        pygame.init()
        pygame.display.init()
        # Création de la fenêtre
        screen = pygame.display.set_mode((WIDTH * PIXEL_SIZE, HEIGHT * PIXEL_SIZE))
        
        # Horloge pour limiter la fréquence de rafraîchissement
        clock = pygame.time.Clock()
        
        done = False
        
        # Créez une police et un texte à afficher
        font = pygame.font.Font(None, 32)
        text_entite = font.render(" Entité : ", True, WHITE)
        
        def get_adjacent_entites(x, y):
            """Retourne les entites adjacents à (x, y)"""
            adjacent_entities = []
            for key in entites:
                entite = entites[key]
                for dx in (-1, 0, 1):
                    for dy in (-1, 0, 1):
                        if dx == 0 and dy == 0:
                            continue
                        if entite.x == x + dx and entite.y == y + dy:
                            adjacent_entities.append(entite)
            return adjacent_entities
            
        def get_adjacent_entites_tlrb(x, y):
            """Retourne les entites adjacents strict à (x, y)"""
            adjacent_entities = []
            for key in entites:
                entite = entites[key]
                for dx in (-1, 0, 1):
                    for dy in (-1, 0, 1):
                        if (dx == 0 and dy == 0) or (dx == 1 and dy == 1) or (dx == 1 and dy == -1) or (dx == -1 and dy == 1) or (dx == -1 and dy == -1):
                            continue
                        if entite.x == x + dx and entite.y == y + dy:
                            adjacent_entities.append(entite)
            return adjacent_entities
        
        def has_adjacent_tlrb(x, y):
            """Vérifie si un pixel a des entites adjacents"""
            adjacent_entities = get_adjacent_entites_tlrb(x, y)
            return len(adjacent_entities) > 0
        
        def has_adjacent(x, y):
            """Vérifie si un pixel a des entites adjacents"""
            adjacent_entities = get_adjacent_entites(x, y)
            return len(adjacent_entities) > 0
        
        class Entity:
            def __init__(self, name, color, x, y, coop=5, list_coop=[], pts=2):
                self.name = name
                self.color = color
                self.x = x
                self.y = y
                self.x_souhaite = 0
                self.y_souhaite = 0
                self.pts = pts
                self.coop = coop
                self.list_coop = list_coop  #
                self.dernier_contact = None
                self.nb_d_interactions = 0
                
                self.rect = pygame.Rect(self.x*PIXEL_SIZE, self.y*PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE)
                self.surface = pygame.Surface((PIXEL_SIZE, PIXEL_SIZE))
                self.surface.fill(self.color)
            
            def move(self, dx, dy):
                if not (self.x_souhaite == 0 and self.y_souhaite == 0):
                    new_x = self.x + dx
                    new_y = self.y + dy
                    for entite in entites.values():
                        if entite.x == new_x and entite.y == new_y:
                            return False
                    self.x = max(0, min(new_x, WIDTH - PIXEL_SIZE))
                    self.y = max(0, min(new_y, HEIGHT - PIXEL_SIZE))
                return True
                
            def distance_to_other(self, other):
                # return math.sqrt((other.x - self.x)**2 + (other.y - self.y)**2)
                return abs(other.x - self.x) + abs(other.y - self.y)
            
            def move_intel(self):
                # On calcul la distance minimale ainsi que les coordonnées
                # de la future entité la plus proche à celles de l'entité actuelle
                entities = list(entites.values())  # convert the dict to list
                entities.remove(self)
                closest_ent = min(entities, key=(self.distance_to_other)) 
                min_distance = self.distance_to_other(closest_ent)
               
                min_x = closest_ent.x
                min_y = closest_ent.y
                
                #print(str((min_x, min_y)) + ", distance de self : " + str(min_distance))
        
                if self.x == min_x:
                    x = 0
                else:
                    x = (min_x - self.x) // abs(min_x - self.x)
                if self.y == min_y:
                    y = 0
                else:
                    y = (min_y - self.y) // abs(min_y - self.y)
        
                # Si l'entité est collée à une autre entité, elle se déplace dans une autre direction
                if min_distance < 2:
                    available_positions = [(self.x + dx, self.y + dy) for dx in range(-1, 2) for dy in range(-1, 2) if (self.x + dx, self.y + dy) not in [(e.x, e.y) for e in entities]]
                    if available_positions:
                        self.x_souhaite = random.choice(available_positions)[0] - self.x
                        self.y_souhaite = random.choice(available_positions)[1] - self.y
                    else:
                        self.x_souhaite = 0
                        self.y_souhaite = 0
                else:
                    self.x_souhaite = x
                    self.y_souhaite = y
        
            def draw(self):
                screen.blit(self.surface, self.rect)
                
            def interact(self):
                a_deja_interagit = False
                # Mise à jour en fonction du comportement des entités
                for entite in self.list_coop:
                    if entite in get_adjacent_entites(self.x, self.y):
                        # effectuer l'interaction avec entite
                        
                        self.dernier_contact = entite.name
                        self.nb_d_interactions += 1
                        a_deja_interagit = True
                        break
                        
                # aucune entité de list_coop n'est adjacente
                if a_deja_interagit == False:
                    for entite in get_adjacent_entites(self.x, self.y):
                        # effectuer l'interaction avec la première entité adjacente trouvée
                        if self.color == WHITE and entite.color == WHITE:
                            self.pts += 1
                            entite.pts += 1
                            self.coop = min(self.coop+1, 10)
                            entite.coop = min(self.coop+1, 10)
                        elif self.color == BLUE and entite.color == WHITE:
                            self.pts += 1
                            entite.pts += 1
                            self.coop = min(self.coop+1, 10)
                            entite.coop = min(self.coop+1, 10)
                        elif self.color == WHITE and entite.color == BLUE:
                            self.pts += 1
                            entite.pts += 1
                            self.coop = min(self.coop+1, 10)
                            entite.coop = min(self.coop+1, 10)
                        elif self.color == RED and entite.color == WHITE:
                            self.pts += 1
                            entite.pts = max(0, entite.pts-1)
                            self.coop = max(0, self.coop-1)
                            entite.coop = max(0, entite.coop-1)
                        elif self.color == WHITE and entite.color == RED:
                            self.pts = max(0, self.pts-1)
                            entite.pts += 1
                            self.coop = max(0, self.coop-1)
                            entite.coop = max(0, entite.coop-1)
                        elif self.color == RED and entite.color == BLUE:
                            self.pts = max(0, self.pts-1)
                            entite.pts = max(0, entite.pts-1)
                            self.coop = max(0, self.coop-1)
                            entite.coop = max(0, entite.coop-1)
                        elif self.color == BLUE and entite.color == RED:
                            self.pts = max(0, self.pts-1)
                            entite.pts = max(0, entite.pts-1)
                            self.coop = max(0, self.coop-1)
                            entite.coop = max(0, entite.coop-1)
                        
                        #animation blanchiement à revoir après les comportements.
                        self.surface = pygame.transform.scale(self.surface, (PIXEL_SIZE + 5, PIXEL_SIZE + 5))
                        color = self.surface.get_at((0, 0))
                        #print(str(color))
                        new_color = (min(255, color[0] + 128), min(255, color[1] + 128), min(255, color[2] + 128), 255)
                        self.surface.fill(new_color, None, pygame.BLEND_RGBA_MULT)
                        self.draw()
                        entite.surface = pygame.transform.scale(entite.surface, (PIXEL_SIZE + 5, PIXEL_SIZE + 5))
                        color = entite.surface.get_at((0, 0))
                        #print(str(color))
                        new_color = (min(255, color[0] + 128), min(255, color[1] + 128), min(255, color[2] + 128), 255)
                        entite.surface.fill(new_color, None, pygame.BLEND_RGBA_MULT)
                        entite.draw()
                        pygame.display.flip()
                        pygame.time.wait(130)
                        self.surface = pygame.transform.scale(self.surface, (PIXEL_SIZE, PIXEL_SIZE))
                        entite.surface = pygame.transform.scale(entite.surface, (PIXEL_SIZE, PIXEL_SIZE))
                        
                        self.dernier_contact = entite.name
                        self.nb_d_interactions += 1
                        a_deja_interagit = True
                        break
                        
                if a_deja_interagit == True:
                    # Déplacement de l'entité vers une nouvelle position
                    while True:                                              # POURQUOI le déplacement ici ?
                        dx = random.randint(-1, 1)
                        dy = random.randint(-1, 1)
                        if self.move(dx, dy):
                            break
                # return a_deja_interagit  
            
        def init_entites():
            for i in range(NB_DE_BLANC):
                entite = Entity(i, WHITE, random.randint(0, WIDTH-PIXEL_SIZE), random.randint(0, HEIGHT-PIXEL_SIZE), 10)
                entites[(entite.x, entite.y)] = entite
            for i in range(NB_DE_BLEU): 
                entite = Entity(i + NB_DE_BLANC, BLUE, random.randint(0, WIDTH-PIXEL_SIZE), random.randint(0, HEIGHT-PIXEL_SIZE), 10)
                entites[(entite.x, entite.y)] = entite
            for i in range(NB_DE_ROUGE): 
                entite = Entity(i + NB_DE_BLANC + NB_DE_BLEU, RED, random.randint(0, WIDTH-PIXEL_SIZE), random.randint(0, HEIGHT-PIXEL_SIZE), 0)
                entites[(entite.x, entite.y)] = entite
                
        def update():
            for entite in entites.values():
                entite.rect.topleft = (entite.x*PIXEL_SIZE, entite.y*PIXEL_SIZE)
        
        def move_entities():
            for entite in entites.values():
                entite.move_intel()
                if entite.move(entite.x_souhaite, entite.y_souhaite) == False:
                    print("Un mouvement qui s'est mal passé")
        
        def get_highest_pts_pixel():
            """Retourne le pixel ayant le plus grand nombre de points de vie"""
            highest_pts = 0
            highest_pts_pixel = None
            coop = 0
            for entite in entites.values():
                if entite.pts > highest_pts:
                    highest_pts = entite.pts
                    highest_pts_pixel = entite.color
                    coop = entite.coop
            return determine_color(highest_pts_pixel), highest_pts, coop
            
        def determine_color(color):
            r, g, b = color.r, color.g, color.b
            h, l, s = colorsys.rgb_to_hls(r/255, g/255, b/255)
            # define threshold for "dominant" color
            threshold = 0.5
        
            if l > 0.9:
                return "blanche"
            elif s < threshold:
                return "grise"
            elif (h >= 0/360 and h <= 30/360) or (h >= 330/360 and h <= 360/360):
                return "rouge"
            elif h > 30/360 and h <= 60/360:
                return "orange"
            elif h > 60/360 and h <= 90/360:
                return "jaune"
            elif h > 90/360 and h <= 150/360:
                return "verte"
            elif h > 150/360 and h <= 210/360:
                return "cyan"
            elif h > 210/360 and h <= 270/360:
                return "bleue"
            elif h > 270/360 and h <= 330/360:
                return "magenta"
            else:
                return "de couleur intermédiaire"
        
        def draw():
            """Dessine les entites on the screen"""
            screen.fill(BLACK)
            for entite in entites.values():
                entite.draw()
        
        
        # initialisations des entités
        init_entites()
        
        # Initialisez un verrou
        lock = threading.Lock()
        
        # évènements de la souris
        def mouse_event_thread():
            global done
            global entites
            global text_entite
            global screen
            global lock
            while not done:
                for event in pygame.event.get():
                    if event.type == pygame.MOUSEMOTION:
                        x, y = event.pos
                        x //= PIXEL_SIZE
                        y //= PIXEL_SIZE
                        mouse_pos = (x,y)
                        
                        if mouse_pos[0] > 0 and mouse_pos[0] < WIDTH and mouse_pos[1] > 0 and mouse_pos[1] < HEIGHT:
                            with lock:
                                entite_surbrillante = None
                                for coord, entite in entites.items():
                                    if entite.rect.collidepoint(mouse_pos):
                                        entite_surbrillante = entite
                                        break
                                for coord, entite in entites.items():
                                    if entite == entite_surbrillante:
                                        temp_rect = entite.rect.copy()
                                        temp_rect = pygame.Rect(entite.rect.x - 9, entite.rect.y - 9, entite.rect.width + 18, entite.rect.height + 18)
                                        temp_rect.center = entite.rect.center
        
                                        temp_rect.inflate_ip(-6, -6)
                                        text_entite = font.render("Entité {} : {} de coopération, {} points et {} interactions".format(determine_color(entite.color), str(entite.coop), str(entite.pts), str(entite.nb_d_interactions)), True, entite.color)
                                        
                                        # bordures du pixel affichées
                                        temp_rect.center = entite.rect.center
                                        pygame.draw.rect(screen, YELLOW, temp_rect, 2)
                                        screen.blit(text_entite, (0, 48))
                                        pygame.display.update()
                                        clock.tick(80/1000) # to prevent the loop from running too fast
                                        break
                        if (event.type == pygame.QUIT or event.key == pygame.K_q):
                            done = True
                            main_thread.join()
                            threading.current_thread().join()
        
        def main_loop():
            global done
            global lock
            paused = False
            time_counter = 0
            key_right_down = False
            
            while not done:
                with lock:
                    pygame.event.pump()
                    # Traitement des événements
                    for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                            done = True
                            main_thread.join()
                            mouse_event_thread.join()
                        elif event.type == pygame.KEYDOWN:
                            if event.key == pygame.K_p:
                                paused = not paused
                            elif event.key == pygame.K_q:
                                highest_pts_pixel = get_highest_pts_pixel()
                                print(f"Le pixel ayant le plus de points est {highest_pts_pixel[0]} avec {highest_pts_pixel[1]} pts et {highest_pts_pixel[2]} de coopération.")
                                done = True
                                main_thread.join()
                                mouse_event_thread.join()
                            elif event.key == pygame.K_RIGHT:
                                key_right_down = True
                        elif event.type == pygame.KEYUP:
                            if event.key == pygame.K_RIGHT:
                                key_right_down = False
                            
                    if paused:
                        continue
        
                    time_counter += 1
                    
                    # update les positions des "entite.rect" avant de draw
                    update()
                    # dessine les pixels
                    draw()
                    
                    # interactions 
                    for entite in entites.values():
                        entite.interact()
                    
                    # Affichage du temps et du nombre d'entités
                    font = pygame.font.Font(None, 36)
                    time_text = font.render("Cycle " + str(time_counter), 1, WHITE)
                    nb_entites_text = font.render("{} entités".format(len(entites)), 1, WHITE)
                    screen.blit(time_text, (0, 0))
                    screen.blit(nb_entites_text, (0, 26))
                    
                    # mise à jour de l'écran
                    pygame.display.flip()
                    
                    # fonction de mouvements des entités
                    move_entities()
                    
                    if key_right_down == True:
                        clock.tick(4)
                    else: 
                        clock.tick(800/1000)
                        
        # init des threads
        mouse_event_thread = threading.Thread(target=mouse_event_thread)
        main_thread = threading.Thread(target=main_loop)
        # start 
        main_thread.start()
        mouse_event_thread.start()
        
        if done:
            main_thread.join()
            mouse_event_thread.join()
            pygame.quit()
            sys.exit()



        • Partager sur Facebook
        • Partager sur Twitter
          11 janvier 2023 à 16:06:45

          tu peux expliquer en détails ce que ce code simule comme comportement car là ça lag grave.
          • Partager sur Facebook
          • Partager sur Twitter

          Python c'est bon, mangez-en. 

            11 janvier 2023 à 16:31:40

            Le programme n'est pas fini, mais en soit pour l'instant les pixels vont vers l'entité (pixel) la plus proche. Et à chaque iteration, il y a un move de 1 case, et si contact, une interaction (échange de points selon le comportement). Mais dans mon souci, le hic c'est surtout le fait que au survol de la souris sur un pixel : les informations ne s'affichent plus depuis que j'ai mis en thread, et un clic gauche fige le programme.
            • Partager sur Facebook
            • Partager sur Twitter
              11 janvier 2023 à 16:54:50

              à 1ère vue, la bloc des lignes 348-351 est trop indenté, il devrait être au même niveau que le 1er if event.type (je me demande d'ailleurs si ça ne devrait pas juste être un else)

              Ta boucle for en ligne 332 ne sert à rien, il y a juste le test if entite_surbrillance != None à faire à la place du test de la ligne 333. Inutile de reparcourir à nouveau les entités; il faudra alors renommer entite par entite_surbrillance dans le bloc du if.

              Comme les autres, je doute de l'utilité du thread supplémentaire qui risque de poser plus de souci qu'il n'en résout (la preuve :p )

              • Partager sur Facebook
              • Partager sur Twitter
                11 janvier 2023 à 17:03:40

                bon, en gros, partager la file d'événements avec un thread c'est faisable mais c'est galère, je pense que le thread n'apporte rien de plus que des complications.
                • Partager sur Facebook
                • Partager sur Twitter

                Python c'est bon, mangez-en. 

                  11 janvier 2023 à 17:29:31

                  # évènements de la souris
                  def mouse_event_thread():
                      global done
                      global entites
                      global text_entite
                      global screen
                      global lock
                      while not done:
                          for event in pygame.event.get():
                              if event.type == pygame.MOUSEMOTION:
                                  x, y = event.pos
                                  x //= PIXEL_SIZE
                                  y //= PIXEL_SIZE
                                  mouse_pos = (x,y)
                                  
                                  if mouse_pos[0] > 0 and mouse_pos[0] < WIDTH and mouse_pos[1] > 0 and mouse_pos[1] < HEIGHT:
                                      with lock:
                                          entite_surbrillante = None
                                          for coord, entite in entites.items():
                                              if entite.rect.collidepoint(mouse_pos):
                                                  entite_surbrillante = entite
                                                  break
                                         
                                          if entite_surbrillance != None:
                                              temp_rect = entite_surbrillante.rect.copy()
                                              temp_rect = pygame.Rect(entite_surbrillante.rect.x - 9, entite_surbrillante.rect.y - 9, entite_surbrillante.rect.width + 18, entite_surbrillante.rect.height + 18)
                                              temp_rect.center = entite_surbrillante.rect.center
                  
                                              temp_rect.inflate_ip(-6, -6)
                                              text_entite = font.render("Entité {} : {} de coopération, {} points et {} interactions".format(determine_color(entite_surbrillante.color), str(entite_surbrillante.coop), str(entite_surbrillante.pts), str(entite_surbrillante.nb_d_interactions)), True, entite_surbrillante.color)
                                              
                                              # bordures du pixel affichées
                                              temp_rect.center = entite_surbrillante.rect.center
                                              pygame.draw.rect(screen, YELLOW, temp_rect, 2)
                                              screen.blit(text_entite, (0, 48))
                                              pygame.display.update()
                                              clock.tick(80/1000) # to prevent the loop from running too fast
                                              break
                              if (event.type == pygame.QUIT or event.key == pygame.K_q):
                                  done = True
                                  main_thread.join()
                                  threading.current_thread().join()
                  
                  Merci du coup, ce sont effectivement de bonnes rectifications.
                  Et je me demande comment les développeurs font pour utiliser les threads en vrai car c'est vraiment casse ***.
                  Ca ne règle pas le problème. Le clic gauche de la souris fait toujours un plantage. Je me demande pourquoi ma gestion de souris de base était pas opti, (lenteur dans la détection).

                  de base c'était comme ça :
                  ...
                  if event.type == pygame.MOUSEBUTTONUP:
                              x, y = event.pos
                              x //= PIXEL_SIZE
                              y //= PIXEL_SIZE
                              
                      if paused:
                          continue
                  
                      time_counter += 1
                      
                      # update les positions pixels
                      update()
                      # dessine les pixels
                      draw()
                      
                      # interactions 
                      for entite in entites.values():
                          entite.interact()
                      
                      # Affichage du temps et du nombre de pixels
                      font = pygame.font.Font(None, 36)
                      time_text = font.render("Cycle " + str(time_counter), 1, WHITE)
                      pixels_text = font.render("{} pixels".format(len(entites)), 1, WHITE)
                      screen.blit(time_text, (0, 0))
                      screen.blit(pixels_text, (0, 26))
                      
                      # Récupérez la position du curseur de la souris
                      mouse_pos = pygame.mouse.get_pos()
                      
                      # Vérifiez si le curseur est sur l'entité
                      for coord, entite in entites.items():
                          temp_rect = entite.rect.copy()
                          temp_rect = pygame.Rect(entite.rect.x - 9, entite.rect.y - 9, entite.rect.width + 18, entite.rect.height + 18)
                          temp_rect.center = entite.rect.center
                          # Vérification de la collision avec la souris
                          if temp_rect.collidepoint(mouse_pos):
                              temp_rect.inflate_ip(-6, -6)
                              text_entite = font.render("Entité : {} de coopération et {} points".format(str(entite.coop), str(entite.pts)), True, entite.color)
                              
                              # bordures du pixel affichées
                              temp_rect.center = entite.rect.center
                              pygame.draw.rect(screen, YELLOW, temp_rect, 2)
                              screen.blit(text_entite, (0, 48))
                              break
                      
                      # mise à jour de l'écran
                      pygame.display.flip()
                  ...


                  -
                  Edité par AuréLeBlé 11 janvier 2023 à 17:30:47

                  • Partager sur Facebook
                  • Partager sur Twitter
                    11 janvier 2023 à 17:37:12

                    quand tu dis "ça plante" il y a un message d'erreur ? si oui, lequel ?

                    Sinon, as-tu vraiment besoin de faire tout ce code quand la souris bouge ? parce que tu vas quasi en permanence faire la boucle des lignes 18-19 qui doit prendre pas de temps dans ce cas (dans le code d'origine).

                    • Partager sur Facebook
                    • Partager sur Twitter
                      11 janvier 2023 à 17:43:25

                      Déjà cette ligne c'est pas possible 

                       if (event.type == pygame.QUIT or event.key  == pygame.K_q):

                      Ça lève forcément une erreur car pas tous les évènements ont un attribut key.

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Python c'est bon, mangez-en. 

                        11 janvier 2023 à 18:40:33

                        Oui, nan mais c'est rectifié pour les parenthèses. Et pas de message d'erreur sinon.

                        Par contre, un truc de fou c'est que dans là mes entités bougent jusqu'à ce que je clic quelque part. (la fenêtre ne répond pas)

                        Mais là j'ai changé ça dans les mouvements de mes entités :

                        def move_entities():
                            for entite in entites.values():
                                entite.move_intel()
                                #if entite.move(entite.x_souhaite, entite.y_souhaite) == False:
                                    #print("Un mouvement qui s'est mal passé")

                        j'ai mis en commentaire cette condition qui me fait juste un print si le mouvement renvoie False. Et là au lancement du programme, mes entités ne bougent plus. :waw: Je crois que je vais virer les threads ...

                        • Partager sur Facebook
                        • Partager sur Twitter
                          11 janvier 2023 à 19:27:15

                          ta condition fait aussi appel à entite.move, donc si en commentaire, le move ne se fait pas, logique.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            12 janvier 2023 à 9:13:43

                            Tu peux détailler le comportement des entités , je trouve cet exo intéressant .

                            En attendant j'ai fait une class Entity qui suit le clic de la souris. Le code génère 1000 points. Tu peux voir que pygame gère 1000 points sans problème, pas besoin de thread donc.

                            from pygame import *
                            from random import randint
                            
                            class Entity(Rect):
                                
                                def __init__(self,x,y,w,h):
                                    Rect.__init__(self,x,y,w,h)
                                    self._x     = x
                                    self._y     = y
                                    self.tau_vx = 0
                                    self.tau_vy = 0
                                    self.vs     = 0    
                                
                                def setVect(self,x2,y2):
                                    delta_x     = x2 - self._x
                                    delta_y     = y2 - self._y
                                    hyp         = (delta_x*delta_x + delta_y*delta_y)**.5
                                    self.tau_vx = hyp and delta_x / hyp
                                    self.tau_vy = hyp and delta_y / hyp
                                
                                def distance(self,other):
                                    delta_x = other._x - self._x
                                    delta_y = other._y - self._y
                                    return (delta_x*delta_x + delta_y*delta_y)**.5
                                    
                                def move(self):
                                    self.x += self.vx
                                    self.y += self.vy
                                
                                @property
                                def x(self):
                                    return self._x
                                
                                @x.setter
                                def x(self,value):
                                    self._x = value
                                    Rect.x.__set__(self,value)
                                
                                @property
                                def y(self):
                                    return self._y
                                
                                @y.setter
                                def y(self,value):
                                    self._y = value
                                    Rect.y.__set__(self,value)
                                    
                                @property
                                def vx(self):
                                    return self.tau_vx * self.vs
                                    
                                @property
                                def vy(self):
                                    return self.tau_vy * self.vs
                            
                            scr = display.set_mode((800,800))
                            
                            a = [Entity(randint(300,500),randint(300,500),3,3)for i in range(1000)]
                            for i in a: i.vs = 5
                            t = time.Clock()
                            
                            while True:
                                
                                for ev in event.get():
                                    if ev.type == QUIT: break
                                    elif ev.type == MOUSEBUTTONUP and ev.button == 1:
                                        for i in a: i.setVect(*ev.pos)
                                
                                else:
                                    scr.fill(0)
                                    for i in a:
                                        i.move()
                                        scr.fill((255,255,255),i)
                                    display.flip()
                                    t.tick(25)
                                    continue
                                break



                            -
                            Edité par josmiley 12 janvier 2023 à 20:01:00

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Python c'est bon, mangez-en. 

                            Gestion de thead et 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