1

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.

Luxia80
  • 13
  • 4
  • Please post a [complete and verifiable example](https://stackoverflow.com/help/mcve). One thing that you shouldn't do is to call `pygame.display.set_mode` every iteration of the while loop. Do that once before the while loop starts. – skrx Jun 25 '18 at 02:01
  • Ok I added all the functions that I used for game_menu – Luxia80 Jun 25 '18 at 02:53

3 Answers3

0

Try adding pygame.display.quit() before the line pygame.quit(). This should close any open displays.

Edit: The problem is that most of your program isn't inside the while loop. Most importantly, the events = pygame.event.get() isn't inside the while loop so the events are never updated.

Rearranging the code to something like this should work:

def game_menu():
    os.environ["SDL_VIDEO_CENTERED"] = "1"
    pygame.init()
    pygame.display.set_caption(".")

    menu = True

    while menu:
        events = pygame.event.get()
        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()
        for event in events:
           if event.type == pygame.QUIT:
              menu = False
              pygame.quit()
              quit()
Eric Zhou
  • 81
  • 1
  • 5
  • I created a new tab to test this without using a background image and it seems to work. But then I try to use it in the original and the game just doens't close. – Luxia80 Jun 25 '18 at 02:51
  • it works on the new module that I made just for trying this but it doesn't work on the whole program. I think it might be the button func but I still can't close the program with the X on the window. – Luxia80 Jun 25 '18 at 03:39
  • It works on my computer. My guess would be that you're calling pygame.event.get() multiple times in each loop, first in the while loop, then 4 more times when you call the function button. Try deleting that line from the button function and instead pass the events in as a parameter. – Eric Zhou Jun 25 '18 at 03:59
  • Thanks, what you said was the same thing that the other guy said but I'm a beginner so I didn't understand you very well. – Luxia80 Jun 25 '18 at 05:29
0

If you import sys then you can use that to exit your code.

import sys
def game_menu():
    menu = True
    while menu:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
0

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()
skrx
  • 19,980
  • 5
  • 34
  • 48
  • Thank you so much!! I've been stuck with this for hours, now I can keep going. Thx for the recomendation too! – Luxia80 Jun 25 '18 at 05:27