Pour mon écran de niveaux, j'utilise des images pour chaque bouton de niveau, il y en a 15 sur une page. J'ai pu tous les afficher à l'écran dans une belle mise en page en utilisant des itérations et des mathématiques, j'ai essayé de trouver un moyen de le faire avec la détection de clic . Mais je ne veux pas taper "var = get_rect" 15 fois par page.

Toutes les images sont dans une liste pour l'itération,

self.levels_p1 = [self.l1, self.l2, self.l3, self.l4, self.l5,
                     self.l6, self.l7, self.l8, self.l9, self.l10,
                     self.l11, self.l12, self.l13, self.l14, self.l15,]

Et sont ajoutés à l'écran dans un 5 x 3 comme celui-ci,

            for i, lvl in enumerate(self.levels_p1, start=1):
                x = ((WIDTH - 100) * (i % 5) // 6) + 17
                y = HEIGHT // 10 + ((i // 5) * 125)
                if i % 5 == 0:
                    x = ((WIDTH - 100) * 5 // 6) + 17
                    y = HEIGHT // 10 + (((i // 5) - 1) * 125)
                self.screen.blit(lvl, (x, y))
                if self.level_unlocked < i:
                    self.screen.blit(self.level_shade, (x, y))

Et j'ai détecté des clics comme celui-ci,

            mousepos = pg.mouse.get_pos()

            for event in pg.event.get():
                if event.type == pg.QUIT:
                    pg.quit()
                if event.type == pg.MOUSEBUTTONDOWN:
                    #to menu
                    if self.back_rect.collidepoint(*mousepos):
                        on_levels = False
                        self.swipe.play()
                        self.start()
                    #to levels2 page
                    if self.arrow_rect.collidepoint(*mousepos):
                        on_levels = False
                        self.swipe.play()
                        self.levels_page2()
                    #to level 1
                    if self.l1_rect.collidepoint(*mousepos):
                        on_levels = False
                        self.swipe.play()
                        self.load_level(1)

Mais cela ne fonctionnera pour tous les niveaux que si je définis manuellement un rect pour tous les boutons, ce que j'essaie d'éviter.

Je me demandais s'il existe un bon moyen de détecter les clics sur chacun de ces boutons? De la même manière que je les ai affichés dans le 2ème bit de code.

Très appréciée.

4
Grave 30 août 2020 à 11:41

3 réponses

Meilleure réponse

pygame.Surface.blit renvoie un rectangle avec la zone des pixels affectés:

self.rect = self.screen.blit(self.level_shade, (x, y))

Vous pouvez également obtenir le rectangle englobant d'un pygame.Surface par < a href = "https://www.pygame.org/docs/ref/surface.html#pygame.Surface.get_rect" rel = "nofollow noreferrer"> get_rect() . L'emplacement de ce rectangle est (0, 0). Par conséquent, vous devez définir la position par un argument de mot-clé:

self.rect = self.level_shade.get_rect(topleft = (x, y)) 
2
Tomerikoo 30 août 2020 à 09:06
        mousepos = pg.mouse.get_pos()
        lvls = []

        for i, lvl in enumerate(self.levels_p1):
            #x, y topleft for 5x3 grid with easement and centered
            x = ((WIDTH - 100) * (i % 5) // 5) + 110
            y = HEIGHT // 10 + ((i // 5) * 125)
            #add to screen
            temp = self.screen.blit(lvl, (x, y))
            #if not unlocked
            if self.level_unlocked < i:
                #darken
                self.screen.blit(self.level_shade, (x, y))
            #if unlocked
            else:
                #enlarged version if hovering over and unlocked
                if temp.collidepoint(*mousepos):
                    self.screen.blit(self.levels_1l[i], (x-6, y-6))
                #rect list for click detection
                lvls.append(temp)

        #back button interactive
        if self.back_rect.collidepoint(*mousepos):
            self.screen.blit(self.t_back2, self.back_rect2)  # bigger
        else:
            self.screen.blit(self.t_back, self.back_rect)  # normal
        #arrow button interactive
        if self.arrow_rect.collidepoint(*mousepos):
            self.screen.blit(self.arrowr2, self.arrow_rect2)  # bigger
        else:
            self.screen.blit(self.arrowr, self.arrow_rect)  # normal

        pg.display.flip()
        #all button presses
        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
            if event.type == pg.MOUSEBUTTONDOWN:
                #to menu
                if self.back_rect.collidepoint(*mousepos):
                    on_levels = False
                    self.swipe.play()
                    self.start()
                #to levels2 page
                if self.arrow_rect.collidepoint(*mousepos):
                    on_levels = False
                    self.swipe.play()
                    self.levels_page2()
                #to level
                for i, val in enumerate(lvls):
                    #if clicked pos = level pos
                    if lvls[i].collidepoint(*mousepos):
                        on_levels = False
                        self.swipe.play()
                        #level to load
                        self.load_level(i+1)
1
Grave 30 août 2020 à 21:59
if self.arrow_rect.collidepoint(*mousepos)

Je ne sais pas ce que tu emballes sur la ligne ci-dessus. Si vous voulez détecter les clics, je pense que vous devriez d'abord obtenir la position de la souris. Je vais faire quelque chose comme ça:

for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
            if event.type == pg.MOUSEBUTTONDOWN:
                #to menu
                mousepos = pg.mouse.get_pos() #Here lies the magic and no need to unpack
                if self.back_rect.collidepoint(mousepos):
                    on_levels = False
                    self.swipe.play()
                    self.start()
                #to levels2 page
                if self.arrow_rect.collidepoint(mousepos):
                    on_levels = False
                    self.swipe.play()
                    self.levels_page2()
                #to level 1
                if self.l1_rect.collidepoint(mousepos):
                    on_levels = False
                    self.swipe.play()
                    self.load_level(1) 

Si cela résout votre problème s'il vous plaît laissez-moi savoir et ne le faites pas encore savoir!

Modifier: essayez si / elif bloque au lieu de juste si.

1
Anya Precious 30 août 2020 à 09:36