Jak zaimplementować przyciski opcji i zmienić kolor przycisków w PyGame?

Nov 29 2020

Pls podpowiadają, jak mogę zmienić kolor przycisku, gdy go nacisnąłem, a kolor pierwszego przycisku zostanie zmieniony na kolor domyślny, gdy naciśnę drugi przycisk.

Na przykład, po kliknięciu przycisku PROSTA, przycisk zmieni kolor na zielony, a kiedy kliknę LEWY przycisk, LEWY przycisk zmieni kolor na zielony, a przycisk PROSTY stanie się domyślnym kolorem białym. Z góry dziękuję :)

KOD:

def draw_button(self):

    global clicked
    action = False

    # get mouse position
    pos = pygame.mouse.get_pos()

    # create pygame Rect object for the button
    button_rect = Rect(self.x, self.y, self.width, self.height)

    # check mouseover and clicked conditions
    if button_rect.collidepoint(pos):
        if pygame.mouse.get_pressed()[0] == 1:
            clicked = True
            pygame.draw.rect(screen, self.click_col, button_rect)
        elif pygame.mouse.get_pressed()[0] == 0 and clicked == True:
            clicked = False
            action = True
           
        else:
            pygame.draw.rect(screen, self.hover_col, button_rect)
    else:
        pygame.draw.rect(screen, self.button_col, button_rect)

Odpowiedzi

1 Rabbid76 Nov 29 2020 at 19:01

Kiedy rysujesz przycisk, musisz ustawić kolor zależny od zmiennej globalnej clicked:

def draw_button(self):

    global clicked
    
    # get mouse position
    pos = pygame.mouse.get_pos()

    # create pygame Rect object for the button
    button_rect = Rect(self.x, self.y, self.width, self.height)

    # check mouseover and clicked conditions
    hover = button_rect.collidepoint(pos)
    if hover and pygame.mouse.get_pressed()[0] == 1:
        clicked = not clicked

    color = self.button_col
    if clicked:
        color = self.click_col
    elif hover:
        color = self.hover_col

    pygame.draw.rect(screen, color, button_rect)

W każdym razie to Cię nie zadowoli, ponieważ pygame.mouse.get_pressed()zwraca listę wartości logicznych, które reprezentują stan ( Truelub False) wszystkich przycisków myszy. Stan przycisku trwa Truetak długo, jak długo przycisk jest wciśnięty.
Musisz użyć MOUSEBUTTONDOWNwydarzenia. MOUSEBUTTONDOWNZdarzenie raz po kliknięciu przycisku myszy, a MOUSEBUTTONUPzdarzenie raz, gdy przycisk myszy zostanie zwolniony. pygame.event.Event()Obiekt ma dwa atrybuty, które dostarczają informacji na temat zdarzenia myszy. posto krotka przechowująca klikniętą pozycję. buttonprzechowuje przycisk, który został kliknięty.


Jeśli masz wiele przycisków, które musisz ze sobą współdziałać, pojedynczy clickedstatus nie wystarczy. Dla każdego przycisku potrzebny jest osobny stan „kliknięcia”. Jeśli stan kliknięcia przycisku 1 zmieni się na True, stan pozostałych klawiszy musi zostać ustawiony na False. Polecam zaimplementować w RadioButtontym celu klasę.

Zobacz także Mysz i Sprite .

Minimalny przykład:

import pygame

class RadioButton(pygame.sprite.Sprite):
    def __init__(self, x, y, w, h, font, text):
        super().__init__() 
        text_surf = font.render(text, True, (0, 0, 0))
        self.button_image = pygame.Surface((w, h))
        self.button_image.fill((96, 96, 96))
        self.button_image.blit(text_surf, text_surf.get_rect(center = (w // 2, h // 2)))
        self.hover_image = pygame.Surface((w, h))
        self.hover_image.fill((96, 96, 96))
        self.hover_image.blit(text_surf, text_surf.get_rect(center = (w // 2, h // 2)))
        pygame.draw.rect(self.hover_image, (96, 196, 96), self.hover_image.get_rect(), 3)
        self.clicked_image = pygame.Surface((w, h))
        self.clicked_image.fill((96, 196, 96))
        self.clicked_image.blit(text_surf, text_surf.get_rect(center = (w // 2, h // 2)))
        self.image = self.button_image
        self.rect = pygame.Rect(x, y, w, h)
        self.clicked = False
        self.buttons = None

    def setRadioButtons(self, buttons):
        self.buttons = buttons

    def update(self, event_list):
        hover = self.rect.collidepoint(pygame.mouse.get_pos())
        for event in event_list:
            if event.type == pygame.MOUSEBUTTONDOWN:
                if hover and event.button == 1:
                    for rb in self.buttons:
                        rb.clicked = False
                    self.clicked = True
        
        self.image = self.button_image
        if self.clicked:
            self.image = self.clicked_image
        elif hover:
            self.image = self.hover_image


pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
font50 = pygame.font.SysFont(None, 50)

radioButtons = [
    RadioButton(50, 40, 200, 60, font50, "option 1"),
    RadioButton(50, 120, 200, 60, font50, "option 2"),
    RadioButton(50, 200, 200, 60, font50, "option 3")
]
for rb in radioButtons:
    rb.setRadioButtons(radioButtons)
radioButtons[0].clicked = True

group = pygame.sprite.Group(radioButtons)

run = True
while run:
    clock.tick(60)
    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.QUIT:
            run = False 

    group.update(event_list)

    window.fill(0)
    group.draw(window)
    pygame.display.flip()

pygame.quit()
exit()
GameDev Nov 29 2020 at 18:15
your_button_rect = pygame.Rect(x,y,width,height)
color = (0,0,0)
pos = pygame.mouse.get_pos()
def change_button_color():
    if your_button_rect.colliderect(pos):
        if event.type == pygame.MOUSEBUTTONDOWN: #checks if mouse button is pressed down while the cursor is on the rectangle
            color = (your_desired_Color_RGBvalue)

while True:
    pygame.draw.rect(screen,color,your_button_rect)
    change_button_color()