image Buttons using image buttons on wrong screen

53 Views Asked by At

Hi I don't know if anyone can help me I'm quite new to coding and I have come across an issue with my menu I am creating , basically when I choose an option such as audio it also hits my mute button which is behind it but on the next screen (audio options menu) so it mutes the game without me choosing that option , this issue also happens with other buttons.

this is my code for the game loop

import button

pygame.init()

#create game window
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

bg_img = pygame.image.load("D:\Python\Projects\Second_menu\yper_saber_no_buttons.png")
bg_img = pygame.transform.scale(bg_img,(SCREEN_WIDTH, SCREEN_HEIGHT))

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Main Menu")

pygame.mixer.init()
pygame.mixer.music.load("D:\Python\Projects\main_menu\High_Contrast_-_If_We_Ever.wav")
pygame.mixer.music.play(loops=-1)

#game variables
game_paused = True
menu_state = "main"


#define fonts
font = pygame.font.SysFont("arialblack", 40)

#define colours
TEXT_COL = (255, 255, 255)

#load button images
start_img = pygame.image.load("D:\Python\Projects\Second_menu\Start_Button.png").convert_alpha()
options_img = pygame.image.load("D:\Python\Projects\Second_menu\Options_Button.png").convert_alpha()
quit_img = pygame.image.load("D:\Python\Projects\second_menu\Quit_Button.png").convert_alpha()
controls_img = pygame.image.load("D:\Python\Projects\second_menu\Controls_Button.png").convert_alpha()
audio_img = pygame.image.load("D:\Python\Projects\second_menu\Audio_Button.png").convert_alpha()
video_settings_img = pygame.image.load("D:\Python\Projects\Second_menu\Video_settings_Button.png").convert_alpha()
mute_menu_music_img = pygame.image.load("D:\Python\Projects\Second_menu\Mute_menu_music_Button.png").convert_alpha()

back_img = pygame.image.load("D:\Python\Projects\second_menu\Back_Button.png").convert_alpha()

#create button instances
start_button = button.Button(328, 380, start_img, 1)
options_button = button.Button(325, 435, options_img, 1)
quit_button = button.Button(355, 485, quit_img, 1)
#option menu buttons
controls_button = button.Button(304, 373, controls_img, 1)
audio_button = button.Button(304, 473, audio_img, 1)
Video_settings_Button = button.Button(304 ,423, video_settings_img, 1) 
back_button = button.Button(355, 530, back_img, 1)
#audio menu buttons
mute_menu_music_button = button.Button (350, 473, mute_menu_music_img, 1)


#game loop
run = True
while run:

  screen.blit(bg_img,(0,0))

  #check if game is paused
  if game_paused == True:
    #check menu state
    if menu_state == "main":
      #draw pause screen buttons
      if start_button.draw(screen):
        game_paused = False
      if options_button.draw(screen):
        menu_state = "options"
      if quit_button.draw(screen):
        run = False
    #check if the options menu is open
    if menu_state == "options":
      #draw the different options buttons
      if controls_button.draw(screen):
        print("Controls")
      if audio_button.draw(screen):
        menu_state = "Audio"
      if Video_settings_Button.draw(screen):
        print("Video settings")
      if back_button.draw(screen):
        menu_state = "main"
    #check if the controls menu is open **TO DO**

    #check if the audio menu is open
    if menu_state == "Audio":
      #draw the different audio option buttons
      if mute_menu_music_button.draw(screen):
        pygame.mixer.music.pause()

  

  #event handler
  for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_SPACE:
        game_paused = True
    if event.type == pygame.QUIT:
      run = False

  pygame.display.update()

pygame.quit()

This is my code for the button file


#button class
class Button():
    def __init__(self, x, y, image, scale):
        width = image.get_width()
        height = image.get_height()
        self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)
        self.clicked = False

    def draw(self, surface):
        action = False
        #get mouse position
        pos = pygame.mouse.get_pos()

        #check mouseover and clicked conditions
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                action = True

        if pygame.mouse.get_pressed()[0] == 0:
            self.clicked = False

        #draw button on screen
        surface.blit(self.image, (self.rect.x, self.rect.y))

        return action ```
1

There are 1 best solutions below

0
Rabbid76 On

You have this problem, because you are not using the MOUSEBUTTONDOWN event, but you are using pygame.mouse.get_pressed(). pygame.mouse.get_pressed() returns a list of Boolean values ​​that represent the state (True or False) of all mouse buttons. The state of a button is True as long as a button is held down. The MOUSEBUTTONDOWN event occurs once when you click the mouse button and the MOUSEBUTTONUP event occurs once when the mouse button is released.

Detect the MOUSEBUTTONDOWN in Button.draw:

class Button():

    def draw(self, surface, event_list):
        action = False
        for event in event_list:
            if event.type == pygame.MOUSEBUTTONDOWN:
                if self.rect.collidepoint(event.pos):
                    action = True
                    self.clicked = False
            
            elif event.type == pygame.MOUSEBUTTONUP:
                self.clicked = False

If pygame.event.get() is called in multiple event loops, only one loop receives the events, but never all loops receive all events. As a result, some events appear to be missed. Get the events once per frame and use them in multiple loops or pass the list of events to functions and methods where they are handled:

while run:

    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                game_paused = True
        if event.type == pygame.QUIT:
            run = False

    screen.blit(bg_img,(0,0))

    #check if game is paused
    if game_paused == True:
        #check menu state
        if menu_state == "main":
            #draw pause screen buttons
            if start_button.draw(screen, event_list):
                game_paused = False
            if options_button.draw(screen, event_list):
                menu_state = "options"
            if quit_button.draw(screen, event_list):
                run = False
        #check if the options menu is open
        if menu_state == "options":
            #draw the different options buttons
            if controls_button.draw(screen, event_list):
                print("Controls")
            if audio_button.draw(screen, event_list):
                menu_state = "Audio"
            if Video_settings_Button.draw(screen, event_list):
                print("Video settings")
            if back_button.draw(screen, event_list):
                menu_state = "main"
        #check if the controls menu is open **TO DO**

        #check if the audio menu is open
        if menu_state == "Audio":
            #draw the different audio option buttons
            if mute_menu_music_button.draw(screen, event_list):
                pygame.mixer.music.pause()

        pygame.display.update()