So I'm creating a menu for a game and I have made a button function. The buttons do work but only sometimes:
This doesn't make sense to me as all buttons use the same function:
def button(msg,x,y,h):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
pygame.draw.rect(screen, RED, (x,y, BUTTON_WIDTH, h))
smallText = pygame.font.Font("freesansbold.ttf", 20)
textSurf, textRect = text_objects(msg, smallText, WHITE)
textRect.center = ((x+(BUTTON_WIDTH/2)),(y+(h/2)))
screen.blit(textSurf, textRect)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if x+BUTTON_WIDTH > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(screen, BRIGHT_RED, (x,y, BUTTON_WIDTH, h))
screen.blit(textSurf, textRect)
if click[0] == 1:
return True
def intro_screen():
intro = True
while intro:
screen.fill(GREEN)
if button("2-Player",245,145,BUTTON_HEIGHT):
multiplayer_loop()
if button("1-Player",245,270,BUTTON_HEIGHT):
login_screen(True)
if button("Scores",245,395,40):
login_screen(False)
screen.blit(TITLE, (120, 5))
pygame.display.update()
pygame.init()
intro_screen()
Any help would be greatly appreciated, thanks.
The issue is the event loop in the button function. Note, pygame.event.get()
get all the messages and remove them from the queue.
So 1 button (mostly the 1st button) will get the events and the other buttons get no events.
Remove pygame.event.get()
from the button. Get the events in the main application loop and pass the list of event to the button function.
Anyway you would not need the event loop in the button function at all, because you evaluate the state of the buttons by pygame.mouse.get_pressed()
.
But, I recommend to use the MOUSEBUTTONDOWN
event. See pygame.event
.
def button(events,msg,x,y,h):
smallText = pygame.font.Font("freesansbold.ttf", 20)
textSurf, textRect = text_objects(msg, smallText, WHITE)
textRect.center = button_rect.center
mouse = pygame.mouse.get_pos()
button_rect = pygame.Rect(x, y, BUTTON_WIDTH, h)
hit = button_rect.collidepoint(mouse)
pygame.draw.rect(screen, BRIGHT_RED if hit else RED, button_rect)
screen.blit(textSurf, textRect)
if hit:
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
return True
def intro_screen():
intro = True
while intro:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
sys.exit()
screen.fill(GREEN)
if button(events , "2-Player",245,145,BUTTON_HEIGHT):
multiplayer_loop()
if button(events , "1-Player",245,270,BUTTON_HEIGHT):
login_screen(True)
if button(events , "Scores",245,395,40):
login_screen(False)
screen.blit(TITLE, (120, 5))
pygame.display.update()
Note, there should be only 1 call to pygame.event.get()
per frame.