我正在用python编写一个蛇游戏.但如果我们快速按下两个按钮,一次需要两个命令.我能做些什么来防止它



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

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

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

该项目的完整代码可以在这个Git存储库中找到。

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

问题是所有事件都保留在列表中,并且您放慢了代码的速度,这样系统就有时间在运行for event循环之前将两个(或多个(KEYDOWN事件放在该列表中,该循环检查该列表中的所有KEYDOWN

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

这样,当你按下多个键时,它将只使用第一个正确的键/方向,所以你不能快速改变决定——也就是说,当你向下移动并按下leftright时,它会使用left,因为这是第一个正确方向。

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

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

这样,当你按下多个键时,它将使用最后一个正确的键/方向,这样你就可以快速改变决定——也就是说,当你向下移动并按下leftright时,它会使用right,因为这是最后一个准确的方向。

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

如果我理解正确的话,你会遇到一个问题,当你的蛇向右移动时,你按下向上键,然后快速连续按下向左键,你的蛇的头部会向左转动,这实际上会导致它与自己的身体发生碰撞。

这看起来像是你的蛇的移动独立于按键,这就导致了在一次移动中按下两个键的可能性,而且由于唯一的条件是蛇没有向右移动,一旦你按下向上键,这实际上是真的,这就会导致这种行为。

防止这种情况的一个快速方法是设置一些变量,例如moved_from_last_press,其中每次蛇移动时,您指定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

移动的变量用于检查按下键后蛇是否已经移动,程序只有在移动后才会检测到键,这样你就不能让蛇朝着它不应该的方向移动

最新更新