I'm having some trouble while trying to quit from a function that I made. It just doesn't seem to break the loop. The game opens and I can play around but I can't quit, It just stays there without doing anything and the icon on the task bar goes full yellow.
Here's my code:
import pygame, os, sys, math
black = (0,0,0)
white = (255,255,255)
grey = (128, 128, 128)
gameDisplay = pygame.display.set_mode((800,600))
def game_menu():
os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.init()
pygame.display.set_caption(".")
menu = True
events = pygame.event.get()
while menu:
for event in events:
if event.type == pygame.QUIT:
menu = False
pygame.quit()
quit()
DISPLAYSURF = pygame.display.set_mode((800, 600))
DISPLAYSURF.fill(black)
font = pygame.font.Font('MATRIX.ttf',60)
TextSurf, TextRect = text_objects("MATRIX PASA PALABRA", font,white)
TextRect.center = ((600/2),(50))
gameDisplay.blit(TextSurf, TextRect)
#Jugar
button("Jugar",300,200,200,50,None)
button("Instrucciones",300,275,200,50,None)
button("Dificultad",300,350,200,50,None)
button("Salir",300,425,200,50,None)
pygame.display.update()
def text_objects(text, font,color):
textSurface = font.render(text, True, color)
return textSurface, textSurface.get_rect()
def button(msg,x,y,w,h,action=None):
mouse = pygame.mouse.get_pos()
events = pygame.event.get()
if x+w> mouse[0] > (x) and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay,grey,(x,y,w,h))
for event in events:
if event.type ==pygame.MOUSEBUTTONUP and msg=="Salir":
pygame.quit()
quit()
elif event.type==pygame.MOUSEBUTTONUP and msg=="Jugar":
None
else:
pygame.draw.rect(gameDisplay,white,(x,y,w,h))
smalltext= pygame.font.Font("MATRIX.ttf",30)
textsrf,textrct=text_objects(msg,smalltext,black)
textrct.center = ((x+(w/2)),(y+(h/2)))
gameDisplay.blit(textsrf,textrct)
if __name__ == "__main__":
game_menu()
Thanks and sorry for my bad english.
The reason why it doesn't work is that you call pygame.event.get
multiple times per frame. The event queue will be emptied after the first call, so the events won't get processed correctly. There should be only one pygame.event.get
call per frame.
To fix this problem, you can assign the list of events that pygame.event.get
returns to a variable in the main while loop and then pass it to the button
function.
while menu:
events = pygame.event.get()
for event in events:
# etc.
button("Jugar",300,200,200,50,events,None)
Add an events
parameter to the button
function:
def button(msg,x,y,w,h,events,action=None):
mouse = pygame.mouse.get_pos()
if x+w> mouse[0] > (x) and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay,grey,(x,y,w,h))
for event in events:
# etc.
BTW, this button
function keeps popping up here again and again, probably because it's a really bad way to implement buttons. I'd recommend a solution similiar to one of these: https://stackoverflow.com/a/47664205/6220679 or search for pygame GUI toolkits (SGC is pretty good).
The others have already mentioned that the indentation in your example is wrong and that sys.exit
is a better way to quit than the quit
function.
Here's a fixed, complete example:
import pygame, os, sys, math
black = (0,0,0)
white = (255,255,255)
grey = (128, 128, 128)
gameDisplay = pygame.display.set_mode((800,600))
def game_menu():
os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.init()
pygame.display.set_caption(".")
DISPLAYSURF = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
menu = True
while menu:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
menu = False
pygame.quit()
sys.exit()
DISPLAYSURF.fill((30, 30, 30))
font = pygame.font.Font(None,60)
TextSurf, TextRect = text_objects("MATRIX PASA PALABRA", font,white)
TextRect.center = ((600/2),(50))
gameDisplay.blit(TextSurf, TextRect)
#Jugar
button("Jugar",300,200,200,50,events,None)
button("Instrucciones",300,275,200,50,events,None)
button("Dificultad",300,350,200,50,events,None)
button("Salir",300,425,200,50,events,None)
pygame.display.update()
clock.tick(60)
def text_objects(text, font,color):
textSurface = font.render(text, True, color)
return textSurface, textSurface.get_rect()
def button(msg,x,y,w,h,events,action=None):
mouse = pygame.mouse.get_pos()
if x+w> mouse[0] > (x) and y+h > mouse[1] > y:
pygame.draw.rect(gameDisplay,grey,(x,y,w,h))
for event in events:
if event.type ==pygame.MOUSEBUTTONUP and msg=="Salir":
pygame.quit()
sys.exit()
elif event.type==pygame.MOUSEBUTTONUP and msg=="Jugar":
print("jugar")
else:
pygame.draw.rect(gameDisplay,white,(x,y,w,h))
smalltext= pygame.font.Font(None,30)
textsrf,textrct=text_objects(msg,smalltext,black)
textrct.center = ((x+(w/2)),(y+(h/2)))
gameDisplay.blit(textsrf,textrct)
if __name__ == "__main__":
game_menu()