Pygame не выйдет после вызова функции - PullRequest
0 голосов
/ 25 июня 2018

У меня возникли проблемы при попытке выйти из функции, которую я сделал.Кажется, это просто не сломает петлю.Игра открывается, и я могу поиграть, но не могу выйти, она просто остается там, ничего не делая, и значок на панели задач становится полностью желтым.

Вот мой код:

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()

Спасибо и извините за мой плохой английский.

Ответы [ 3 ]

0 голосов
/ 25 июня 2018

Если вы импортируете sys, вы можете использовать его для выхода из своего кода.

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 голосов
/ 25 июня 2018

Причина, по которой это не работает, заключается в том, что вы вызываете pygame.event.get несколько раз за кадр. Очередь событий будет очищена после первого вызова, поэтому события не будут обработаны правильно. В каждом кадре должен быть только один pygame.event.get вызов.

Чтобы устранить эту проблему, вы можете назначить список событий, которые pygame.event.get возвращает переменной в главном цикле while, а затем передать его в функцию button.

while menu:
    events = pygame.event.get()
    for event in events:
        # etc.

    button("Jugar",300,200,200,50,events,None)

Добавить параметр events к функции button:

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.

Кстати, эта button функция снова и снова появляется здесь, возможно, потому, что это действительно плохой способ реализации кнопок. Я бы порекомендовал решение, похожее на одно из них: https://stackoverflow.com/a/47664205/6220679 или поиск инструментария GUI для Pygame (SGC довольно хорош).


Другие уже упоминали, что отступ в вашем примере неверен и что sys.exit - лучший способ выйти, чем функция quit.

Вот фиксированный, полный пример:

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()
0 голосов
/ 25 июня 2018

Попробуйте добавить pygame.display.quit() перед строкой pygame.quit(). Это должно закрыть все открытые дисплеи.

Edit: Проблема в том, что большая часть вашей программы не находится в цикле while. Самое главное, что events = pygame.event.get() не находится внутри цикла while, поэтому события никогда не обновляются.

Изменение порядка кода на что-то вроде этого должно работать:

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()
...