我正在用python编写一个蛇游戏。但如果我们快速按下两个按钮,它会在一个滴答声中发出两个命令。我能做些什么来防止它?

我正在用python编写一个蛇游戏。但如果我们快速按下两个按钮,它会在一个滴答声中发出两个命令。我能做些什么来防止它?,python,pygame,Python,Pygame,在我的蛇游戏中,我遇到了以下问题:如果蛇向右移动,玩家连续快速地向上和向左按键,蛇向左转弯,越过身体,游戏结束,将其视为碰撞。如何防止游戏在蛇移动之前执行两个改变方向的命令 我检查按下哪个键的代码如下: while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if e

在我的蛇游戏中,我遇到了以下问题:如果蛇向右移动,玩家连续快速地向上和向左按键,蛇向左转弯,越过身体,游戏结束,将其视为碰撞。如何防止游戏在蛇移动之前执行两个改变方向的命令

我检查按下哪个键的代码如下:

while True:
    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_RIGHT and left == False:
                right = True
                up = False
                down = False
            elif event.key == pygame.K_LEFT and right == False:
                left = True
                up = False
                down = False
            elif event.key == pygame.K_DOWN and up == False:
                down = True
                right = False
                left = False
            elif event.key == pygame.K_UP and down == False:
                up = True
                right = False
                left = False

可以找到项目的完整代码


要运行代码,您需要通过pip安装pygame软件包。

如果我理解正确,您遇到了一个问题,即当您的蛇向右移动时,您按下向上键,然后快速连续按下向左键,蛇头向左转动,从而导致与自己的身体发生碰撞

这看起来像是你的蛇的运动独立于按键,这会导致在一次移动中按下两个键的可能性,并且因为唯一的条件是蛇没有向右移动,这在你按下向上键后实际上是正确的,它会导致这种行为


防止这种情况发生的一种快速方法是设置一些变量,例如从上次按下时开始移动的
,每次蛇移动时,您都会指定
True
,每次按下键时,您都会指定
False
。然后,在检查按下了哪个键时,检查
True
值。

问题是,检查键的频率比蛇移动的频率高。例如,在蛇向上移动之前,您可以按向上和向左,这将导致只向左移动。要解决此问题,您需要一个标志,指示蛇已移动,以便您知道何时检查是否再次按下按键:

moved = True

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if(moved):
                if event.key == pygame.K_RIGHT and left == False:
                    right = True
                    up = False
                    down = False
                    moved = False
                elif event.key == pygame.K_LEFT and right == False:
                    left = True
                    up = False
                    down = False
                    moved = False
                elif event.key == pygame.K_DOWN and up == False:
                    down = True
                    right = False
                    left = False
                    moved = False
                elif event.key == pygame.K_UP and down == False:
                    up = True
                    right = False
                    left = False
                    moved = False

    if up:
        next = (snakes_block[0][0], snakes_block[0][1] - 1)
        imghadd = pygame.transform.rotate(imghad, 180)
        moved = True
    elif down:
        next = (snakes_block[0][0], snakes_block[0][1] + 1)
        imghadd = pygame.transform.rotate(imghad, 360)
        moved = True
    elif left:
        next = (snakes_block[0][0] - 1, snakes_block[0][1])
        imghadd = pygame.transform.rotate(imghad, 270)
        moved = True
    elif right:
        next = (snakes_block[0][0] + 1, snakes_block[0][1])
        imghadd = pygame.transform.rotate(imghad, 90)
        moved = True

moved变量用于检查自按下按键后蛇是否已移动,程序仅在移动后检测按键,这样您就无法使蛇朝其无法移动的方向移动。

问题是所有事件都保留在列表中,您会减慢代码速度,以便系统有时间放置两个(或更多)按键
KEYDOWN
此列表中的事件,然后运行
for event
循环,检查此列表中的所有
KEYDOWN

正如@VaclavPelc提到的,若您已经改变了方向并跳过了其他键,那个么您可以使用变量来控制

这样,当您按下多个键时,它将只使用第一个正确的键/方向-因此您无法快速更改决策-即,当您向下移动并按下
时,它将使用
,因为这是第一个正确的方向

while True:

    changed_direction = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.KEYDOWN:
            if not changed_direction:
                if event.key == pygame.K_RIGHT and left == False:
                    right = True
                    up = False
                    down = False
                    changed_direction = True
                elif event.key == pygame.K_LEFT and right == False:
                    left = True
                    up = False
                    down = False
                    changed_direction = True
                elif event.key == pygame.K_DOWN and up == False:
                    down = True
                    right = False
                    left = False
                    changed_direction = True
                elif event.key == pygame.K_UP and down == False:
                    up = True
                    right = False
                    left = False
                    changed_direction = True
while True:

    previous_left = left
    previous_right = right
    previous_up = up
    previous_down = down
    
    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_RIGHT and previous_left == False:
                right = True
                up = False
                down = False
            elif event.key == pygame.K_LEFT and previous_right == False:
                left = True
                up = False
                down = False
            elif event.key == pygame.K_DOWN and previous_up == False:
                down = True
                right = False
                left = False
            elif event.key == pygame.K_UP and previous_down == False:
                up = True
                right = False
                left = False

另一种方法是将上一个方向保留在不同的变量中,并在检查上一个方向时使用这些变量

while True:

    changed_direction = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.KEYDOWN:
            if not changed_direction:
                if event.key == pygame.K_RIGHT and left == False:
                    right = True
                    up = False
                    down = False
                    changed_direction = True
                elif event.key == pygame.K_LEFT and right == False:
                    left = True
                    up = False
                    down = False
                    changed_direction = True
                elif event.key == pygame.K_DOWN and up == False:
                    down = True
                    right = False
                    left = False
                    changed_direction = True
                elif event.key == pygame.K_UP and down == False:
                    up = True
                    right = False
                    left = False
                    changed_direction = True
while True:

    previous_left = left
    previous_right = right
    previous_up = up
    previous_down = down
    
    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_RIGHT and previous_left == False:
                right = True
                up = False
                down = False
            elif event.key == pygame.K_LEFT and previous_right == False:
                left = True
                up = False
                down = False
            elif event.key == pygame.K_DOWN and previous_up == False:
                down = True
                right = False
                left = False
            elif event.key == pygame.K_UP and previous_down == False:
                up = True
                right = False
                left = False
这样,当您按下多个键时,它将使用最后一个正确的键/方向-这样您可以快速更改决策-即,当您向下移动并按下
时,它将使用
,因为这是最后一个正确的方向

while True:

    changed_direction = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.KEYDOWN:
            if not changed_direction:
                if event.key == pygame.K_RIGHT and left == False:
                    right = True
                    up = False
                    down = False
                    changed_direction = True
                elif event.key == pygame.K_LEFT and right == False:
                    left = True
                    up = False
                    down = False
                    changed_direction = True
                elif event.key == pygame.K_DOWN and up == False:
                    down = True
                    right = False
                    left = False
                    changed_direction = True
                elif event.key == pygame.K_UP and down == False:
                    up = True
                    right = False
                    left = False
                    changed_direction = True
while True:

    previous_left = left
    previous_right = right
    previous_up = up
    previous_down = down
    
    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_RIGHT and previous_left == False:
                right = True
                up = False
                down = False
            elif event.key == pygame.K_LEFT and previous_right == False:
                left = True
                up = False
                down = False
            elif event.key == pygame.K_DOWN and previous_up == False:
                down = True
                right = False
                left = False
            elif event.key == pygame.K_UP and previous_down == False:
                up = True
                right = False
                left = False

您应该使用
print()
来调试它,并查看当您按下左键时
right
是否为false。顺便说一句:相反
delay(500)
您可以使用
mainClock。勾选(2)
以获得相同的效果。无需使用
mainClock。如果您将其延迟到一秒内仅显示两帧,则勾选(40)
。您正在检查
False
。您不应该检查
是否为True
。如果我以前使用的键L是
UP
,那么
UP
应该是
True
。所以如果我按下
,那么,我是否应该检查previous是否为
UP
?然后改变方向?