Pygame事件:在不释放键的情况下触发键事件

时间:2020-04-25 11:41:37

标签: pygame keyboard keydown keyup

我正在尝试制作俄罗斯方块游戏,下面是我使方块移动的代码。我希望该块在按住箭头键时保持移动,并在释放时停止。但是,当我运行代码时,即使没有释放键,它也会停止该块。

   def set_keyboard_dirs(cur_block, width, height, events): # events stores pygame.event.get() as I use it multiple times in my code
        global move_timer # only moves block one time per set number of frames
        cur_block.reset_collisions(height)
        for event in events:
            if event.type == pygame.KEYDOWN:  # sets magnitude and direction of movement
                if event.key == pygame.K_RIGHT:
                    cur_block.dir = (cur_block.length, 0)
                elif event.key == pygame.K_LEFT:
                    cur_block.dir = (-cur_block.length, 0)
                elif event.key == pygame.K_DOWN:
                    cur_block.dir = (0, cur_block.length)
                elif event.key == pygame.K_UP:
                    cur_block.rotate(height, width)
                elif event.key == pygame.K_SPACE: # just moves the block instantly to the bottom of the screen by equating it to a 'projection' already there. 
                    cur_block.shape = deepcopy(cur_block.projection)
            elif event.type == pygame.KEYUP:  # stops block from moving
                print(event.key) # I called this to see what's happening, and event.key is printed event when I didn't release the key. 
                cur_block.dir = (0, 0)

        cur_block.move()

由于上述原因,该块一次移动一个步骤,而不是像我想要的那样连续移动(只要保持住它)。我该如何解决?游戏的其余部分都可以正常运行,所以我真的希望它也可以正常工作。提前谢谢。

编辑: 我也尝试过使用pygame.key.get_pressed()设置控件,如下所示:

def set_keyboard_dirs(cur_block, width, height):
    global move_timer, keys
    cur_block.reset_collisions(height)
    cur_block.dir = (0, 0)
    if keys[pygame.K_UP] or keys[pygame.K_w]:
        cur_block.rotate(height, width)
    elif keys[pygame.K_SPACE]:
        cur_block.shape = deepcopy(cur_block.projection)
    elif (keys[pygame.K_DOWN] or keys[pygame.K_s]) and 2 not in cur_block.collisions: # 1, 2, 3 are collisions in left, down and right directions
        cur_block.dir = (0, cur_block.length)
    elif (keys[pygame.K_RIGHT] or keys[pygame.K_d]) and 1 not in cur_block.collisions:
        cur_block.dir = (cur_block.length, 0)
    elif (keys[pygame.K_LEFT] or keys[pygame.K_a]) and 3 not in cur_block.collisions:
        cur_block.dir = (-cur_block.length, 0)
    else:
        print('ran reset') # this statement print even as i'm holding down a key for some reason
        cur_block.dir = (0, 0)
    if cur_block.dir != (0, 0) and move_timer == 0:
        cur_block.move()
        move_timer = 7

在前一种情况下,如果我删除了KEYUP事件,而在后一种情况下,如果我删除了else语句,则该块会连续移动(但不能停止),这也表明导致问题的原因是那些语句,我认为。这是我唯一定义我的cur_block.dir的代码。

2 个答案:

答案 0 :(得分:0)

这可能是因为for循环每帧运行1次,因此,如果按住按钮,则在该特定帧上按1次它就会计数,这与KEYUP事件相同。 您可以尝试在主循环之外使两个变量left = False和right = False 在当前for循环之外,您还要检查是否按下了任何按钮。

#these are outside of the mainloop
left=False
right=False



keys = pygame.key.get_pressed()  # checks for key events (put this outside of the for loop, but still be inside your mainloop)
if keys[pygame.K_LEFT]:
    right = False
    left = True
elif keys[pygame.K_RIGHT]:
    left = False
    right = True

# if none of those buttons pressed, it sets the values back to False
else:
    right = False
    left = False

# using the left value, if its true, it will do your action every frame, 
#(you can adjust the speed of your block later)

if left:
    #  do something
    cur_block.dir = (-cur_block.length, 0)
if right:
    # do something else


然后,例如,如果您按LEFT键,则Left的值将为true,然后您可以检查:这些值中是否有true>做某事。

根据您的示例代码,这是我唯一能想到的。我希望它能起作用。

答案 1 :(得分:0)

在您的代码中,如果释放了任何键,则取消块的移动,如果释放了特殊键,则不会取消。如果释放了一个游标键,则必须实现特殊情况:

this

我建议根据pygame.key.get_pressed()返回的键状态来设置移动方向:

elif event.type == pygame.KEYUP:
    if event.key == pygame.K_RIGHT:
        # [...]
    elif event.key == pygame.K_LEFT:
        # [...]
    # [...]