【问题标题】:I have a function that detects if i press a key in pygame, but it only detects one key?我有一个功能可以检测我是否在pygame中按下了一个键,但它只检测到一个键?
【发布时间】:2022-10-14 18:08:16
【问题描述】:

我有一个检测按键的功能,但是,当我使用该功能并检测到“a”时,它会检测到但如果我检测到“d”它不会检测到它,但是如果我将检测到键“d”的功能放在功能之前检测到键“a”它检测到“d”,为什么会这样?

这是我的代码:

keys = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','space','1','2','3','4','5','6','7','8','9','0']
pygame_keys = [pygame.K_a,pygame.K_b,pygame.K_c,pygame.K_d,pygame.K_e,pygame.K_f,pygame.K_g,pygame.K_h,pygame.K_i,pygame.K_j,pygame.K_k,pygame.K_l,pygame.K_m,pygame.K_n,pygame.K_o,pygame.K_p,pygame.K_q,pygame.K_r,pygame.K_s,pygame.K_t,pygame.K_u,pygame.K_v,pygame.K_w,pygame.K_x,pygame.K_y,pygame.K_z,pygame.K_SPACE,pygame.K_1,pygame.K_2,pygame.K_3,pygame.K_4,pygame.K_5,pygame.K_6,pygame.K_7,pygame.K_8,pygame.K_9,pygame.K_0]


def key_pressed(key_press,one_click =False):
    global key_function_run 
    if one_click:
        key_function_run = True
    if not one_click:
        if kb.is_pressed(key_press):
            return True
    if one_click:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            for i in range(len(keys)):
                if event.type == pygame.KEYDOWN:
                    if key_press == keys[i]:
                        if event.key == pygame_keys[i]:
                            print(i)
                            return True
    pass

这是我使用该功能的方式:

    if x == 205:
        player_lane = 2
    if x == 60:
        player_lane = 1
    if x == 347:
        player_lane = 3
    #player movement
    if peasy.key_pressed('a',True) and player_lane == 2:
        x = 60
    if peasy.key_pressed('a',True) and player_lane == 3:
        x = 205
    if peasy.key_pressed('d',True) and player_lane == 2:
        x = 347
    if peasy.key_pressed('d',True) and player_lane == 1:
        x = 205

【问题讨论】:

标签: python pygame


【解决方案1】:

从您的列表中制作字典:

key_dict = dict(zip(keys, pygame_keys))

并使用pygame.key.get_pressed

def key_hold(keys, key):
    return keys[key_dict[key]]
keys = pygame.key.get_pressed()
is_a = key_hold(keys, 'a')
is_d = key_hold(keys, 'd')

如果您想使用KEYDOWN 事件,您必须知道pygame.event.get() 获取所有消息并将它们从队列中删除。请参阅文档:

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

因此,您每帧只能调用一次pygame.event.get。另见Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?。但是,您可以使用 KEYDOWN 事件的 unicode 属性:

def key_down_event(event_list, c):
    return any(e for e in event_list if e.type == pygame.KEYDOWN and e.unicode == c)
event_list = pygame.event.get()
is_a = key_down_event(event_list, 'a')
is_d = key_down_event(event_list, 'd')

如果你想要一个功能来检测一个键是被按下还是被按下,你需要为每个键计算一个键被按下多长时间的帧数。返回True,如果您想确定是否刚刚按下某个键,则该键的计数为 1:

import pygame

key_count = {}
def key_pressed(keys, key, one_click):
    pressed = keys[key]
    if key not in key_count or not pressed:
        key_count[key] = 0
    if pressed:
        key_count[key] += 1        
    return key_count[key] == 1 if one_click else pressed
    
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 

    keys = pygame.key.get_pressed()
    a_once = key_pressed(keys, pygame.K_a, True)
    d_hold = key_pressed(keys, pygame.K_d, False)
    if a_once:
        print(f'key event: {pygame.key.name(pygame.K_a)}')
    if d_hold:
        print(f'key pressed: {pygame.key.name(pygame.K_d)}')
    
    pygame.display.flip()

pygame.quit()
exit()

【讨论】:

    【解决方案2】:

    您不需要为输入处理创建自定义函数,您可以使用以下内容:

    running = True
    
    def main():
        # Your normal game loop
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
    
    
            # Gets a list of the currently pressed keys,
            # this is updated because we put it in the while loop
            kbd = pygame.key.get_pressed()
    
            if kbd[pygame.K_a]:
                print("I just pressed the A button!") # You can run here whatever ya want
    

    编辑:我意识到OP想使用pygame.KEYDOWN而不是pygame.key.get_pressed(),所以在这种情况下,你可以使用这样的东西

        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
               
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_d:
                        print("Pressed D!")
    

    希望我有所帮助。如果您有任何问题,请发表评论/回复/随便!

    【讨论】:

    • 不,kbd["A"] 不起作用,因为密钥需要是 pygame.K_a。 => kbd[pygame.K_a]
    • 是的,刚刚更正了。我的错!
    • 我正在尝试使用 pygame.KEYDOWN,因为如果我单击一次按钮而不是单击按钮时返回。这就是我需要的。
    • 但是提问者想用“A”,而不是pygame.K_a
    • 实际上我正在尝试将其写为“a”,然后使用 pygame.K_a 检测 a
    猜你喜欢
    • 2016-10-31
    • 2021-07-14
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2018-06-26
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多