Python 3.6.2中的开始菜单错误,Pygame 1.9.3

Python 3.6.2中的开始菜单错误,Pygame 1.9.3

问题描述:

我决定让pyong中的Pong成为一个不错的入门项目。这个错误虽然不是很好。我到了想用两个按钮添加开始菜单的阶段,开始和退出。我这样做是为了当鼠标悬停在开始按钮上并按下空格时,它将用黑色填充显示。然后我会继续制作游戏。但是,当我这样做时,窗户冻结,并没有回应。这里是我的开始菜单代码:Python 3.6.2中的开始菜单错误,Pygame 1.9.3

def startMenu(): 
     gameDisplay.fill(black) 
     gameDisplay.blit(font2.render("PONG", True, white), (250, 0)) 
     start = pygame.draw.rect(gameDisplay, white, (210, 300, 40, 40)) 
     quit = pygame.draw.rect(gameDisplay, white, (600, 300, 40, 40)) 
     gameDisplay.blit(font1.render("Start", True, white), (170, 350)) 
     gameDisplay.blit(font1.render("Quit", True, white), (560, 350)) 

     mousePos = pygame.mouse.get_pos() 

     #start button 
     if event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_SPACE: 
       if mousePos[0] > 210 and mousePos[0] < 250: 
        if mousePos[1] > 300 and mousePos[1] < 340: 
         play = True 
         while play: 
          gameDisplay.fill(black) 
startMenu() 

我也包括我的整个主代码在这里:

import pygame, time 

pygame.init() 

displayWidth = 800 
displayHeight = 600 

black = (0, 0, 0) 
white = (255, 255, 255) 

gameDisplay = pygame.display.set_mode((displayWidth, displayHeight)) 
gameCaption = pygame.display.set_caption("Pong") 
gameClock = pygame.time.Clock() 
font1 = pygame.font.Font('freesansbold.ttf', 50) 
font2 = pygame.font.Font('freesansbold.ttf', 115) 

def gameLoop(): 

    gameExit = False 

    while not gameExit: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       gameExit = True 

     def startMenu(): 
      gameDisplay.fill(black) 
      gameDisplay.blit(font2.render("PONG", True, white), (250, 0)) 
      start = pygame.draw.rect(gameDisplay, white, (210, 300, 40, 40)) 
      quit = pygame.draw.rect(gameDisplay, white, (600, 300, 40, 40)) 
      gameDisplay.blit(font1.render("Start", True, white), (170, 350)) 
      gameDisplay.blit(font1.render("Quit", True, white), (560, 350)) 

      mousePos = pygame.mouse.get_pos() 



      #start button 
      if event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_SPACE: 
        if mousePos[0] > 210 and mousePos[0] < 250: 
         if mousePos[1] > 300 and mousePos[1] < 340: 
          play = True 
          while play: 
           gameDisplay.fill(black) 
     startMenu() 

     pygame.display.update() 
     gameClock.tick(60) 

gameLoop() 
pygame.quit() 
quit() 

谢谢您的阅读,我希望你能帮助!

while play: 
    gameDisplay.fill(black) 

这将永远运行,永远充满黑色的显示。

+0

那么为什么它会崩溃? –

+0

我相信如此。如果你在gameDisplay.fill(黑色)之后加上'break',程序不会崩溃。当您按住空格按钮时,屏幕会变黑,并在释放时返回主菜单。 – Krishi

+0

有没有办法让它保持黑色?我试过调用一个函数,但我不能,因为我认为我不能访问另一个函数内的另一个函数。 –

窗口冻结是因为您未处理while play:循环中的事件,因此操作系统认为程序已无响应并将其锁定。您需要在while循环中调用至少pygame.event.pump()以防止冻结或仅使用事件循环for event in pygame.event.get():

你试图实现场景的方式有点奇怪。作为初学者,你不应该尝试在其他函数中嵌套函数。而是做类似于下面的例子:用自己的while和event循环为菜单和游戏创建单独的函数,然后添加管理这些场景的另一个函数(main)。如果用户点击start按钮,只需返回下一个场景功能,然后在main中将其分配给scene变量,并在下一次迭代中调用它以运行当前场景功能。

此外,请查看我如何使用和collidepoint返回的方法使用按钮执行碰撞检测。 MOUSEBUTTONDOWN事件有一个pos属性,您可以使用该属性而不是调用pygame.mouse.get_pos

import sys 
import pygame 


pygame.init() 

black = (0, 0, 0) 
white = (255, 255, 255) 

gameDisplay = pygame.display.set_mode((800, 600)) 
gameClock = pygame.time.Clock() 
font1 = pygame.font.Font('freesansbold.ttf', 50) 
font2 = pygame.font.Font('freesansbold.ttf', 115) 


def startMenu(): 
    scene_done = False 

    gameDisplay.fill(black) 
    gameDisplay.blit(font2.render("PONG", True, white), (250, 0)) 
    start_button = pygame.draw.rect(gameDisplay, white, (210, 300, 40, 40)) 
    quit_button = pygame.draw.rect(gameDisplay, white, (600, 300, 40, 40)) 
    gameDisplay.blit(font1.render("Start", True, white), (170, 350)) 
    gameDisplay.blit(font1.render("Quit", True, white), (560, 350)) 

    pygame.display.update() 

    while not scene_done: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
       sys.exit() 
      elif event.type == pygame.MOUSEBUTTONDOWN: 
       if event.button == 1: # Left mouse button. 
        if start_button.collidepoint(event.pos): 
         return gameLoop 
        elif quit_button.collidepoint(event.pos): 
         pygame.quit() 
         sys.exit() 

     gameClock.tick(60) 


def gameLoop(): 
    scene_done = False 

    while not scene_done: 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       pygame.quit() 
       sys.exit() 
      elif event.type == pygame.KEYDOWN: 
       if event.key == pygame.K_ESCAPE: 
        return startMenu 

     gameDisplay.fill(black) 
     gameDisplay.blit(font1.render("Game loop", True, white), (260, 150)) 
     pygame.display.update() 
     gameClock.tick(60) 


def main(): 
    """This function manages the scenes. 

    Call the current scene function and when it's done 
    assign the returned function to `scene`.""" 
    scene = startMenu 

    while True: 
     scene = scene() 

main() 
+0

当你更熟悉类/面向对象编程时,最好使用[像这样的有限状态机](https://www.reddit.com/r/pygame/comments/3kghhj/simple_state_machine_example/)来实现场景而不是功能。 – skrx