Reputation: 75
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
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:
MOUSEBUTTONUP
event (occurs when you release a mouse button)MOUSEBUTTONDOWN
) occurred in the buttonIn 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 buttonButton
: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')
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