pygame 未能检测到 keyup

pygame failure to detect keyup

我正在使用 pygame 库制作一个简单的游戏。我注意到一个奇怪的错误,如果我点击其中一个方向键来移动我的角色,它会固定在一个方向上移动。按下键会在您按下的方向上触发正加速度,而按下键会将加速度重置为零。检查这些值,尽管发生了按键弹起,但加速度仍保持正值。查看所有事件,它注册了一个按键按下和按键向上,但是 pygame 没有 运行 与该按键事件关联的代码。这可能是我键盘的信号问题,但它似乎可能是 pygame 中的事件处理。这是我的代码:

import pygame

pygame.init()

display_x = 1024
display_y = 512

game_display = pygame.display.set_mode((display_x, display_y))
clock = pygame.time.Clock()

fps = 30
font = pygame.font.SysFont(None, 25)

max_velocity = 16
acceleration = 4


def print_to_screen(text, color, x, y):
    screen_text = font.render(text, True, color)
    game_display.blit(screen_text, [x, y])


def game_loop():
    game_exit = False

    lead_x = display_x/2
    lead_y = display_y/2
    vel_x = 0
    vel_y = 0
    acc_x = 0
    acc_y = 0
    tile_size = 32

    while not game_exit:
        for event in pygame.event.get():
            print(event)
            if event.type == pygame.QUIT:
                game_exit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    acc_x = -acceleration
                if event.key == pygame.K_RIGHT:
                    acc_x = acceleration
                if event.key == pygame.K_UP:
                    acc_y = -acceleration
                if event.key == pygame.K_DOWN:
                    acc_y = acceleration
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT and vel_x < 0:
                    acc_x = 0
                if event.key == pygame.K_RIGHT and vel_x > 0:
                    acc_x = 0
                if event.key == pygame.K_UP and vel_y < 0:
                    acc_y = 0
                if event.key == pygame.K_DOWN and vel_y > 0:
                    acc_y = 0

        if -max_velocity < vel_x < max_velocity:  # if velocity isn't max, adds acceleration to velocity
            vel_x += acc_x
        if -max_velocity < vel_y < max_velocity:
            vel_y += acc_y
        if vel_x < 0:  # velocity decay, if vel is less than 0, adds one. no input = slowed down cube
            vel_x += 1
        elif vel_x > 0:
            vel_x -= 1
        if vel_y < 0:
            vel_y += 1
        elif vel_y > 0:
            vel_y -= 1

        if (lead_x + vel_x) < 0:  # looks into future: if past border in next frame, sets x coord to 0, stops motion
            vel_x = 0
            acc_x = 0
            lead_x = 0
        elif (lead_x + vel_x) > (display_x - tile_size):
            vel_x = 0
            acc_x = 0
            lead_x = (display_x - tile_size)
        if (lead_y + vel_y) < 0:
            vel_y = 0
            acc_y = 0
            lead_y = 0
        elif (lead_y + vel_y) > (display_y - tile_size):
            vel_y = 0
            acc_y = 0
            lead_y = (display_y - tile_size)

        lead_x += vel_x
        lead_y += vel_y

        game_display.fill((255, 255, 255))
        pygame.draw.rect(game_display, (255, 0, 0), [lead_x, lead_y, tile_size, tile_size])
        print_to_screen(str(int(lead_x)) + ", " + str(int(lead_y)), (0, 0, 0), 0, 0)
        if vel_x > max_velocity or vel_y > max_velocity:
            print_to_screen(str(int(vel_x)) + ", " + str(int(vel_y)), (255, 0, 0), 0, 16)
        else:
            print_to_screen(str(int(vel_x)) + ", " + str(int(vel_y)), (0, 0, 0), 0, 16)
        if acc_x > acceleration or acc_y > acceleration:
            print_to_screen(str(int(acc_x)) + ", " + str(int(acc_y)), (255, 0, 0), 0, 32)
        else:
            print_to_screen(str(int(acc_x)) + ", " + str(int(acc_y)), (0, 0, 0), 0, 32)

        pygame.display.update()
        clock.tick(fps)

game_loop()
pygame.quit()
quit()

这是快速点击的事件数据:

<Event(2-KeyDown {'unicode': '', 'key': 276, 'mod': 0, 'scancode': 75})>
<Event(3-KeyUp {'key': 276, 'mod': 0, 'scancode': 75})>

显示按键弹起和按键按下事件,不知道为什么弹起键不注册。

Remove that keyup block and add this to keydown block:

if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_LEFT:
    acc_x = -acceleration
    acc_y = 0
if event.key == pygame.K_RIGHT:
    acc_x = acceleration
    acc_y = 0
if event.key == pygame.K_UP:
    acc_y = -acceleration
    acc_x = 0
if event.key == pygame.K_DOWN:
    acc_y = acceleration
    acc_x = 0

问题是您结合 KEYUP 事件检查 vel_x 是小于还是大于 0。想想当我们向左移动(vel_x < 0)并快速按下并释放K_RIGHT时会发生什么,那么vel_x仍然是负数所以if event.key == pygame.K_RIGHT and vel_x > 0:False, keyup 事件被忽略并且 acc_x 没有重置为 0.

您应该检查 acc_x 而非 vel_x 是否大于 0。

if event.type == pygame.KEYUP:
    if event.key == pygame.K_LEFT and acc_x < 0:
        acc_x = 0
    if event.key == pygame.K_RIGHT and acc_x > 0:
        acc_x = 0

上下键和vel_y、acc_y.

也是一样