A way to blit multiple buttons from a list with working alpha and color?

Viewed 35

I wanted to blit several button choices depending on the number that a list gives, but putting them in a for loop makes the alpha() and fill() function stop working. Is there a way to fix this or there's a better alternative to code multiple buttons?

Starting code:

import pygame, sys
pygame.init()

WIDTH, HEIGHT = 900, 600
screen = pygame.display.set_mode((WIDTH,HEIGHT),0,32)
clock = pygame.time.Clock() 
font = pygame.font.Font('freesansbold.ttf', 32) 

Button and Scene class:

class Button():
    def __init__(self, text, x, y):
        self.rect = pygame.Rect(x, y, 0, 0)
        self.updateText(text)
        self.clicked = False  

    def updateText(self, text):
        self.text = text   
        self.render = font.render(self.text, True, 'white')
        self.text_width = self.render.get_width()
        self.text_height = self.render.get_height()
        self.box = pygame.Surface((self.text_width, self.text_height)) 
        self.rect = self.render.get_rect(topleft = self.rect.topleft)

    def draw(self):
        action = False
        screen.blit(self.box, (self.rect.x, self.rect.y))
        screen.blit(self.render, (self.rect.x, self.rect.y))   

        pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(pos):
            self.box.set_alpha(100) 
            self.box.fill((255, 255, 255))

            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                action = True

            if pygame.mouse.get_pressed()[0] == 0:
                action = False
                self.clicked = False
        else:
            self.box.set_alpha(0) 

        return action


class Scene():
    def __init__(self):
        pass

    def on_start(self):
        self.count = 0
        self.blitcount = 0
        self.optionList = []

        for button in range(5): 
            self.optionList.append(Button("button", WIDTH/3*2, 60 *(button + 1)))
            self.count += 1

        self.altButton = Button("Button without for loop", 100, 100)
        self.buttons = None

    def update(self, events):
        screen.fill('gray')

        for i in range(4):

            self.buttons = self.optionList[self.blitcount]
            self.buttons.updateText(str(i))        

            if self.buttons.draw():
                 print(i)

            self.blitcount += 1

        if self.altButton.draw():
            print("Alt")

        self.blitcount = 0

        return self

The rest of the code:

game = Scene()
game.on_start()

while True:
    clock.tick(30)

    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            pygame.quit() 
            sys.exit() 

    game.update(events)

    pygame.display.update()
1 Answers

You have to change the order. You need to set the alpha channel of the box before drawing the box. Note that the box is drawn with the currently set alpha channel.
(See also the answer to your previous question How do I change the text in a Button class for Pygame?)

class Button():
    # [...]

    def draw(self):
        action = False
        
        pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(pos):
            self.box.set_alpha(100) 
            self.box.fill((255, 255, 255))

            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                action = True

            if pygame.mouse.get_pressed()[0] == 0:
                action = False
                self.clicked = False
        else:
            self.box.set_alpha(0) 

        screen.blit(self.box, (self.rect.x, self.rect.y))
        screen.blit(self.render, (self.rect.x, self.rect.y))  

        return action
Related