为什么 Pygame 一次只注册一些输入而不是立即按下

问题描述

我正在尝试创建一个需要用户名和密码才能登录的游戏。 我只为字母“w”创建了一个输入,只是为了使代码更小。我的问题是,如果我按下 w 键,它不会在显示屏上弹出,但是在“你好”这个词之后突然弹出 2-4 个“w”。我不明白为什么会发生这种情况

提前致谢

import pygame


FPS = 60

black = (0,0)
white = (255,255,255)
blue = (0,255)
cyan = (0,255)
grey = (150,150,150)
brown = (139,69,19)
lbrown = (235,188,128)
peach = (255,211,129)
selected_colour = (0,0)

#height of game display
height = 960
#width of game display
width = 960

game_display = pygame.display.set_mode((height,width))
pygame.display.set_caption("Chess")
pygame.font.init()
font = pygame.font.SysFont("calibri",30)
clock = pygame.time.Clock()
Login = True
username = "hello"

def update_fps():
    fps_counter = str(int(clock.get_fps()))
    fps_text = font.render(fps_counter,1,pygame.Color("coral"))
    return (fps_text)

Typing = False
gameRunning = True
while gameRunning:
    pygame.display.flip()
    game_display.fill(white)
    game_display.blit(update_fps(),(910,0))

    clock.tick(FPS)
    mouse_x,mouse_y = pygame.mouse.get_pos()


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

    if Login:
        pygame.draw.rect(game_display,black,(330,400,300,100),5)
        font = pygame.font.SysFont("calibri",30)
        if mouse_x >= 330 and mouse_x <= 630 and mouse_y >= 400 and mouse_y <= 500:

            if event.type == pygame.MOUSEBUTTONDOWN:
                #Login = False
                #mainPage = True
                Typing = True

        if mouse_x <= 330 and mouse_x >= 630 and mouse_y <= 400 and mouse_y >= 500:
            if event.type == pygame.MOUSEBUTTONDOWN:
                Typing = False
        if Typing:
            for event in pygame.event.get():
                pressed = pygame.key.get_pressed()
                if pressed[pygame.K_w]:
                    print("w is pressed")
                    username = username + "w"
                if pressed[pygame.K_BACKSPACE]:
                    username[:-1]
        game_display.blit(font.render(username,True,selected_colour),(410,625))

解决方法

pygame.event.get() 获取所有消息并将它们从队列中删除。请参阅文档:

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

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

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

gameRunning = True
while gameRunning:
    # [...]

    event_list = pygame.event.get()
    for event in event_list :
        if event.type == pygame.QUIT:
            gameRunning = False

    if Login:
       # [...]

       for event in event_list:
            if event.type == pygame.MOUSEBUTTONDOWN: 
                mouse_x,mouse_y = event.pos  
                if mouse_x >= 330 and mouse_x <= 630 and mouse_y >= 400 and mouse_y <= 500:
           
                    #Login = False
                    #mainPage = True
                    Typing = True

                if mouse_x <= 330 and mouse_x >= 630 and mouse_y <= 400 and mouse_y >= 500:
                    Typing = False
        if Typing:
            for event in event_list:
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_w:
                        print("w is pressed")
                        username = username + "w"
                    if event.key == pygame.K_BACKSPACE:
                        username[:-1]
        
        # [...]

使用 KEYDOWN 事件代替 pygame.key.get_pressed()
键盘事件(请参阅 pygame.event 模块)仅在键状态更改时发生一次。 KEYDOWN 事件在每次按下键时发生一次。 KEYUP 每次释放键时出现一次。将键盘事件用于单个操作。
pygame.key.get_pressed() 返回一个包含每个键状态的列表。如果某个键被按下,则该键的状态为 True,否则为 False。使用 pygame.key.get_pressed() 评估按钮的当前状态并获得连续移动。