当我在pygame新建一个画面时,你必须反复点击退出按钮才能关闭window

When I make a new screen in pygame, you have to repeatedly click the exit button to close the window

在我的 pygame 游戏中,当玩家死亡时,我 运行 一个 game_over() 函数,它显示一个屏幕“GAME OVER 按 E 退出或按 R 重新启动。”但是虽然是运行ning,但是如果你想关闭window,你必须点击多次,点击E也是如此。即使你点击R并重新启动,你也必须这样做, 但在 game_over() 有 运行.

之前

这里是game_over():

def game_over():
running = False
while not running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = True
            pygame.QUIT
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r:
                player.score = 0
                main()
                break
            if event.key == pygame.K_e:
                running = True
                pygame.QUIT

    WIN.fill(BLACK)
    game_over = BIGFONT.render('GAME OVER', False, WHITE)
    WIN.blit(game_over , (200 , 175))

    instructions = SMALLFONT.render(f'You scored {player.score}. Press R to restart or E to exit' , False , WHITE)
    WIN.blit(instructions , (145 , 290))

    pygame.display.flip()

这里是完整代码:

import pygame , random

pygame.init()

WIDTH , HEIGHT = 900 , 500
WIN = pygame.display.set_mode((WIDTH , HEIGHT))
pygame.display.set_caption('game')

BLOCK_MOVEMENT_TIMER_EVENT = pygame.USEREVENT + 1
BLOCK_MOVEMENT_TIME_DELAY = 15
pygame.time.set_timer(BLOCK_MOVEMENT_TIMER_EVENT , BLOCK_MOVEMENT_TIME_DELAY)

BLOCK_CREATE_TIMER_EVENT = pygame.USEREVENT + 2
BLOCK_CREATE_TIME_DELAY = 1500
pygame.time.set_timer(BLOCK_CREATE_TIMER_EVENT, BLOCK_CREATE_TIME_DELAY)

FPS = 60

#colors
WHITE = (255 , 255 ,255)
BLACK = (0 , 0 , 0)
RED = (255 , 0 , 0)

BIGFONT = pygame.font.Font('Retro.ttf' , 65)
SMALLFONT = pygame.font.Font('Retro.ttf' , 20)

FLOOR = pygame.Rect(0 , 400 , 900 , 5)

class Player:
    def __init__(self):
        self.size = 20
        self.x = 75
        self.y = 380
        self.jumping = False
        self.fall = False
        self.update_rect()
        self.score = 0

    def update_rect(self):
        self.rect = pygame.Rect(self.x , self.y , self.size , self.size)

    def jump(self):
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_SPACE] and not self.fall:
            self.jumping = True
        
        if self.jumping:
            self.y -= 3
            if self.y < 300:
                self.y = 300
                self.fall = True
                self.jumping = False

        if self.fall:
            self.y += 3
            if self.y > 380:
                self.y = 380
                self.fall = False
        
        self.update_rect()

player = Player()

class Obstacles:
    def __init__(self , width , height):
        self.x = 900
        self.y = HEIGHT - height - 100
        self.width = width
        self.height = height
        self.update_rect()

    def update_rect(self):
        self.rect = pygame.Rect(self.x , self.y , self.width , self.height)

def move_obstacles(obstacle_list):
    for obstacle in obstacle_list:
        obstacle.x -= 3
        if obstacle.x < -100:
            obstacle_list.pop(0)
            player.score += 1
        
        obstacle.update_rect()

def add_obstacle(obstacle_list):
    obstacle1 = Obstacles(20 , 40)
    obstacle2 = Obstacles(75 , 20)
    obstacle3 = Obstacles(35 , 35)
    obstacle4 = Obstacles(50 , 25)
    obstacle5 = Obstacles(80 , 10)
    obstacle6 = Obstacles(40 , 20)
    obstacle7 = Obstacles(20 , 30)

    obstacle_options = [obstacle1 , obstacle2 , obstacle3 , obstacle4 , obstacle5 , obstacle6 , obstacle7]

    obstacle_list.append(obstacle_options[random.randint(0,6)])

def is_game_over(obstacle_list):
    for obstacle in obstacle_list:
        if player.rect.colliderect(obstacle):
            return True

def game_over():
    running = False
    while not running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = True
                pygame.QUIT
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    player.score = 0
                    main()
                    break
                if event.key == pygame.K_e:
                    running = True
                    pygame.QUIT

        WIN.fill(BLACK)
        game_over = BIGFONT.render('GAME OVER', False, WHITE)
        WIN.blit(game_over , (200 , 175))

        instructions = SMALLFONT.render(f'You scored {player.score}. Press R to restart or E to exit' , False , WHITE)
        WIN.blit(instructions , (145 , 290))

        pygame.display.flip()

def draw_window(obstacle_list , is_game_over):
    WIN.fill(BLACK)
    pygame.draw.rect(WIN , WHITE , FLOOR)

    pygame.draw.rect(WIN , WHITE , player.rect)

    for obstacle in obstacle_list:
        pygame.draw.rect(WIN , RED , obstacle.rect)
    
    score_counter = BIGFONT.render(f'SCORE  {player.score}', False, (255, 255, 255))
    WIN.blit(score_counter , (240 , 100))

    pygame.display.flip()

def main():
    clock = pygame.time.Clock()
    
    obstacle_list = []

    done = False
    while not done:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
                pygame.QUIT
            if event.type == BLOCK_MOVEMENT_TIMER_EVENT:
                move_obstacles(obstacle_list)
            if event.type == BLOCK_CREATE_TIMER_EVENT:
                add_obstacle(obstacle_list)

        draw_window(obstacle_list , is_game_over(obstacle_list))
        player.jump()
        is_game_over(obstacle_list)

        if is_game_over(obstacle_list):
            game_over()
            done = True

        pygame.display.flip()

if __name__ == '__main__':
    main()

提前致谢!

此处(以及 'e')您将 'running' 设置为 true,这会打破该循环。下面一行 pygame.QUIT。什么都不做 pygame.QUIT 是变量,不是函数,你的意思可能是 pygame.quit().

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

然而,如果 game_over() 是 return 一个 restart bool,那么主句柄要么重新启动,要么只是将 'done' 设置为 True 并让主循环自然结束。

 if game_over():
     done = True
 else:
     reset()