User4497
User4497

Reputation: 75

Creating sound when releasing a button

I've been stuck with this for a very long time now. I have a button class. You can already select the button, click the button, and release the button (which causes a event to happen). I want to put sound for when you release the button, but I just can't. I don't understand how you're supposed to do that, I've tried everything. In other words, I want to make sure that the mouse is held down when it's already selecting the button, then if it releases in that position, a attribute called release will toggle to True for one frame. Then I can check if release is True, then I'd play the sound. My question: What condition do I need to check to have the release attribute toggle to True for one frame? This is my code structure:

# "mouse_down" is a global for when the mouse is being held down
# "clicked" is a global variable for the first frame at which the mouse is held down
# I also have a "release" global variable for the frame that the mouse stops clicking, this variable isn't currently being used.

class Button:
    def __init__(self, pos, size, font, text, colors):
        """
        colors[n]
        
        0: fill   unselected
        1: border unselected
        2: text   unselected
        3: fill   selected
        4: border selected
        5: text   selected
        6: fill   clicked
        7: border clicked
        8: text 
        """

        self.pos = pos
        self.size = size
        self.font = font
        self.text = text
        self.colors = colors
        self.selected = False
        self.clicked = False
        self.release= False

    def update(self):
        # If the mouse is hovering on the button
        if (pygame.mouse.get_pos()[0] > button.pos[0] and pygame.mouse.get_pos()[0] < button.pos[0] + button.size[0]) and (pygame.mouse.get_pos()[1] > button.pos[1] and pygame.mouse.get_pos()[1] < button.pos[1] + button.size[1]):
            self.selected = True
            
            if clicked: 
                self.clicked = True

            if not mouse_down:
                self.clicked = False

        else:
            self.selected = False
            self.clicked = False

Now just to clarify, let's assume I hold down the click button with my mouse, drag it to the button's position, then let go, the release attribute shouldn't toggle on since the mouse needs to be placed on the button to begin with.

Upvotes: 2

Views: 86

Answers (1)

D_00
D_00

Reputation: 1494

Better use pygame.rect.collidepoint to get if the mouse collides with the button instead of

if (pygame.mouse.get_pos()[0] > button.pos[0] and pygame.mouse.get_pos()[0] < button.pos[0] + button.size[0]) and (pygame.mouse.get_pos()[1] > button.pos[1] and pygame.mouse.get_pos()[1] < button.pos[1] + button.size[1]):

How it works:

  • Main loop: get the MOUSEBUTTONUP event (occurs when you release a mouse button)
  • Send this event to the button
  • Also send if the actual mouse click (MOUSEBUTTONDOWN) occurred in the button
  • If both events are True, then play the sound

In the button class:

  • __init__: generate the collide zone + the text Surface
  • update: draw the rect, then the text centered, then check if collision + event + pressed on button

Class Button:

class Button:
    def __init__(self, pos, size, font, text, color):
        self.rect = Rect(pos, size) # 
        self.text = font.render(text, 0, color) # text surface
        self.button_down_on = False

    def update(self, release_event):
        # draw the button
        pygame.draw.rect(screen, (100, 100, 100), self.rect)
        width, height = self.text.get_size()
        screen.blit(self.text, (int(self.rect.x + self.rect.width / 2 - width / 2),
                                int(self.rect.y + self.rect.height / 2 - height / 2)))

        # check collisions
        if release_event and self.rect.collidepoint(pygame.mouse.get_pos()):
            if self.button_down_on: # if the mouse began to press on this button
                print('play sound')

Script

import pygame
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((640, 480))

button = Button((10, 10), (200, 40), pygame.font.SysFont('consolas', 20), 'Test', (127, 255, 255))

running = True
while running:
    release_event = False
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            exit()
        elif event.type == MOUSEBUTTONDOWN:
            # check if the click begin on a button
            button.button_down_on = button.rect.collidepoint(event.pos)
        elif event.type == MOUSEBUTTONUP:
            release_event = True # send this event to Button.update

    screen.fill((255, 255, 255))
    button.update(release_event)
    pygame.display.flip()

Upvotes: 2

Related Questions