首页 > 解决方案 > 为什么 Pygame 一次只注册一些输入而不是立即按下

问题描述

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

提前致谢

import pygame


FPS = 60

black = (0, 0, 0)
white = (255, 255, 255)
blue = (0, 0, 255)
cyan = (0, 255, 255)
grey = (150, 150, 150)
brown = (139, 69, 19)
lBrown = (235, 188, 128)
peach = (255, 211, 129)
selected_colour = (0, 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))

标签: pythonpygame

解决方案


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()评估按钮的当前状态并获得连续移动。


推荐阅读