Reputation: 23
I'm struggling with my button
class's functionality. The issue I suspect lies in the pygame.event
check. When I press the escape button, it should close python if on the main menu or go back to the main menu if in one of the screens. This works perfectly fine; however, if I hover my cursor over the buttons and try to do the same thing, it sometimes takes anywhere between 1-8 presses of the button in order to do this. I suspect it's because one of the pygame.event
checks overrides the other, but I'm struggling to rewrite it in a way that will register both.
class button():
def __init__(self, color, x, y, width, height, text = ''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, screen):
button = pygame.draw.rect(screen, self.color, (self.x - self.width/2, self.y - self.height/2, self.width, self.height)) #Draws button
font = pygame.font.SysFont('Calibri body', 70)
text = font.render(self.text, 1, (255,255,255)) #Renders text
textrect = text.get_rect() #Gets rectangle of text
textrect.center = (self.x, self.y) #Assigns center coordinates of text
screen.blit(text, textrect) #Pastes result
mx, my = pygame.mouse.get_pos() #Gets mouse coordinates
if button.collidepoint(mx, my): #Checks if mouse coordinates match to button
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
if event.type == MOUSEBUTTONDOWN and event.button ==1:
return(True)
def mainMenu():
running = True
while running:
screen.blit(mainBackground,(0,0))
draw_text('Obstacle race', font1, (255, 255, 255), screen, width/2, height/15) #Creates main title text
levelSelector_button = button((220, 220, 220), width/2, height/2-150, 400, 100, 'Level Selector')
if levelSelector_button.draw(screen): #Draws button and checks for true
levelSelector()
leaderboard_button = button((220, 220, 220), width/2, height/2, 400, 100, 'Leaderboard')
if leaderboard_button.draw(screen): #Draws button and checks for true
leaderboard()
instructions_button = button((220, 220, 220), width/2, height/2+150, 400, 100, 'Instructions')
if instructions_button.draw(screen): #Draws button and checks for true
instructions()
settings_button = button((220, 220, 220), width/2, height/2+300, 400, 100, 'Settings')
if settings_button.draw(screen):#Draws button and checks for true
settings()
#Event check
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
pygame.display.update()
mainClock.tick(60) #Caps framerate at 60fps
Upvotes: 0
Views: 133
Reputation: 211258
See pygame.event.get()
:
This will get all the messages and remove them from the queue. [...]
This means that if pygame.event.get()
is called in multiple event loops, only one loop will receive the events, but never all loops will receive all events and some events will seem to be missed. You must fetch the events once per frame and use them in multiple loops or pass the list of events to functions and methods where they are used:
# application loop
while True:
# get list of events
event_list = pygame.event.get()
# use list of events
for event in event_list :
if event.type == QUIT:
pygame.quit()
sys.exit()
# [...]
# pass list of events to a method
some_method(event_list)
# [...]
Note that if event_list
is a variable in the global namespace, that variable can be used in any function or method to get the events.
Upvotes: 1