吃豆人 - 当按下并释放一个键后,使吃豆人朝一个方向移动

3

我想使用pygame模块在Python3中编写pac-man游戏。然而,我不知道如何保持pac-man在按下单个键后持续移动。目标是按下“向上”键,pac-man将继续朝该方向移动,直到他撞到边界,即使我释放了按键。就目前而言,我没有编写这些边界,因为我优先考虑pac-man的连续移动。我尝试嵌套了一个while循环,但显然出现了运行时错误。你有什么好主意吗?

if keys[pygame.K_UP] and (pac.y - pac.radius) > 0:
        pac.y -= pac.speed
        pac.direction = "UP"
    elif keys[pygame.K_DOWN] and (pac.y + 2*(pac.radius) + pac.speed) < height:
        pac.y += pac.speed
        pac.direction = "DOWN"
    elif keys[pygame.K_LEFT] and (pac.x - pac.radius) > 0:
        pac.x -= pac.speed
        pac.direction = "LEFT"
        left = True
    elif keys[pygame.K_RIGHT] and (pac.x + 2*pac.radius + pac.speed) < width:
        pac.x += pac.speed
        pac.direction = "RIGHT"
        right = True

期望的结果是输入一个方向,吃豆人将自动朝这个方向移动,而不需要一直按着方向键。但实际情况是我必须不断按住方向键才能让吃豆人朝着我想要的方向移动。

请问您能否在if语句周围添加更多的代码。 - Tim
当前,您只有在按下键时才移动pacman(例如pac.x += pac.speed)。您应该在按下键时存储方向信息,并将移动代码放置在定期执行的某个地方(例如使用计时器)。 - zvone
4个回答

4

直接在按键被按下时移动你的吃豆人是不会对你的程序起作用的。你应该在此处设置吃豆人的速度或其他参数,并在另一个函数中每一帧应用它。

def update():
    pac.y += pac.yspeed
    pac.x += pac.xspeed


while True:
    clock.tick(60)
    if keys[pygame.K_UP] and (pac.y - pac.radius) > 0:
        pac.yspeed = 1
    elif keys[pygame.K_DOWN] and (pac.y + 2*(pac.radius) + pac.speed) < height:
        pac.yspeed = -1
    elif keys[pygame.K_LEFT] and (pac.x - pac.radius) > 0:
        pac.xspeed = -1
        left = True
    elif keys[pygame.K_RIGHT] and (pac.x + 2*pac.radius + pac.speed) < width:
        pac.xspeed = 1
        right = True
    if keys[pygame.K_ESC]:
        break
    update()
    # Do all your other stuff

1
没错。但既然你已经做到这一步了,如果能展示如何在每个时间步骤中调用“update”函数,那么答案就更完整了。 - zvone
1
这个非常好用,我只需要进行一些小的调整,以确保Pac-Man每次只能在x方向或y方向移动,所以我使用了一些if语句。但是这绝对是完美的,谢谢。 - Governor

2
我建议在你的Pac-Man类中创建一个对象来跟踪Pac-Man应该移动的方向(基本上是你已经设置的pac.direction)。对于每个移动迭代,不要检查你的键映射,而是检查pac.direction并执行它所说的操作。如果你想保持你的代码大多数方式,那么基本上让它看起来像这样: "我建议在你的 Pac-Man 类中创建一个对象来记录 Pac-Man 应该移动的方向(基本上就是你已经设置的 pac.direction)。对于每次移动迭代,不要检查按键映射,而是检查 pac.direction 并执行它指定的操作。如果你想保持你的代码大致相同,可以将其设置为类似以下内容:"
if pac.direction == "UP" and (pac.y - pac.radius) > 0:
        pac.y -= pac.speed
elif pac.direction == "DOWN" and (pac.y + 2*(pac.radius) + pac.speed) < height:
        pac.y += pac.speed
elif pac.direction == "LEFT" and (pac.x - pac.radius) > 0:
        pac.x -= pac.speed
        left = True
elif pac.direction == "RIGHT" and (pac.x + 2*pac.radius + pac.speed) < width:
        pac.x += pac.speed
        right = True

然后,当按下一个键之前,您只需要将pac.direction设置为正确的值。我必须承认,我不熟悉PyGame,所以我会把这留给读者。 或者,您可以通过使方向采用pac.direction=(xSpeed, ySpeed)的形式来大大压缩此代码。然后,您的代码压缩为(没有边界检查,可以在行之前完成):
pac.x += pac.direction[0]  # Could be pac.direction.x if you use an object instead of a tuple
pac.y += pac.direction[1]  # Same as above with pac.direction.y
left = pac.direction[0] > 0  # I'm unsure why you're doing left and right separately, so I'll just put left


0
你可以使用OR语句来检查Pac Man是否已经有了方向: if (keys[pygame.K_UP] or pac.direction == "UP") and (pac.y - pac.radius) > 0: 对于每个方向的if语句都要重复此操作。
这是假设没有其他代码改变方向的情况。

0
为什么不使用一个变量来存储最近的方向?
while True:
    if keys[pygame.K_UP] and (pac.y - pac.radius) > 0:
        recent_direction = 'UP'
    elif keys[pygame.K_DOWN] and (pac.y + 2*(pac.radius) + pac.speed) < height:
        recent_direction = 'DOWN'
    elif keys[pygame.K_LEFT] and (pac.x - pac.radius) > 0:
        recent_direction = 'LEFT'
    elif keys[pygame.K_RIGHT] and (pac.x + 2*pac.radius + pac.speed) < width:
        recent_direction = 'RIGHT'
while True:
    if recent_direction == 'UP':
        pac.y -= pac.speed
    elif recent_direction == 'DOWN':
        pac.y += pac.speed
    if recent_direction == 'LEFT':
        pac.x -= pac.speed
    if recent_direction == 'RIGHT':
        pac.x += pac.speed

希望这对你有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接