Pygame 并不总是注册鼠标点击

问题描述

所以我正在用 Python 和 Pygame 编写这个游戏,并尝试制作一个带有可点击按钮的菜单。我写了这段代码

while running:
    click = False
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                click = True

    window.fill((0,0))

    button = pygame.Rect(30,45,280,60)
    pygame.draw.rect(window,(52,235,177),button1,border_radius=20)
    window.blit(
        (font.render('Start Game',True,(255,255,255))),(50,50))

    if click:
        if button1.collidepoint(pygame.mouse.get_pos()):
            main()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            running = False

    pygame.display.update()

但出于某种原因,Pygame 通常不会注册点击。有时它在第一次尝试时就起作用,有时我必须单击一个按钮 20 次才能使其起作用。有人知道如何解决这个问题吗?

解决方法

问题是由多个事件循环引起的。请参阅 pygame.event.get() 获取所有消息并将它们从队列中删除。请参阅文档:

这将获取所有消息并将它们从队列中删除。 [...]

如果在多个事件循环中调用 pygame.event.get(),则只有一个循环接收事件,但不会所有循环都接收所有事件。因此,似乎错过了一些事件。

每帧获取一次事件并在多个循环中使用它们(或将事件列表传递给处理它们的函数和方法):

while running:
    click = False

    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                click = True

    window.fill((0,0))

    button = pygame.Rect(30,45,280,60)
    pygame.draw.rect(window,(52,235,177),button1,border_radius=20)
    window.blit(
        (font.render('Start Game',True,(255,255,255))),(50,50))

    if click:
        if button1.collidepoint(pygame.mouse.get_pos()):
            main()

    for event in event_list:
        if event.type == pygame.QUIT:
            pygame.quit()
            running = False

    pygame.display.update()

或者在一个循环中处理所有事件:

while running:
    click = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                click = True

    window.fill((0,50))

    if click:
        if button1.collidepoint(pygame.mouse.get_pos()):
            main()

    pygame.display.update()