Python Turtle双人Tron游戏:按键操作时另一辆摩托停止移动的修复求助
修复双人Tron游戏中摩托停止移动的问题
嘿,我一眼就看出问题出在哪了——你在每个按键处理函数里用了while True无限循环!
Turtle库的screen.mainloop()是个单线程的事件循环,它负责处理按键输入、刷新画面这些核心任务。当你按下一个键,对应的函数(比如RedUp())就会启动一个无限循环,一直让摩托移动,但这会完全阻塞事件循环——这时候程序没法处理其他按键,也没法让另一辆摩托继续移动,自然就停住了。
咱们得换个思路,不用阻塞式的循环,而是用Turtle的ontimer()来实现非阻塞的持续移动。下面是修改后的完整代码,我会标注关键改动:
import turtle import time width = 800 height = 600 def tron(): # 初始化玩家的朝向变量,默认向上 red_heading = 90 blue_heading = 90 # Drawing the starting turtles blueplayer = turtle.Turtle() redplayer = turtle.Turtle() screen = turtle.Screen() screen.setup(width, height) screen.bgpic('TronBg.png') screen.bgcolor('black') screen.addshape('BlueBike.gif') screen.addshape('RedBike.gif') blueplayer.shape('BlueBike.gif') redplayer.shape('RedBike.gif') redplayer.pencolor("red") redplayer.pensize(3) blueplayer.pencolor("blue") blueplayer.pensize(3) redplayer.pu() blueplayer.pu() redplayer.goto(width/2, height/8) blueplayer.goto(-width/2, height/8) redplayer.pd() blueplayer.pd() # Border(注释部分保留你的原代码,顺便修正了坐标逻辑) # box = turtle.Turtle() # box.ht() # box.color('purple') # box.speed('fastest') # box.pensize(10) # box.pu() # box.goto(-width/2, -height/2) # box.pd() # for i in range(2): # box.forward(width) # box.left(90) # box.forward(height) # box.left(90) # 按键处理函数:只修改朝向,不做循环移动 def RedUp(): nonlocal red_heading red_heading = 90 def RedDown(): nonlocal red_heading red_heading = 270 def RedLeft(): nonlocal red_heading red_heading = 180 def RedRight(): nonlocal red_heading red_heading = 0 def BlueUp(): nonlocal blue_heading blue_heading = 90 def BlueDown(): nonlocal blue_heading blue_heading = 270 def BlueLeft(): nonlocal blue_heading blue_heading = 180 def BlueRight(): nonlocal blue_heading blue_heading = 0 # 持续移动玩家的函数 def move_players(): # 根据当前朝向移动红摩托 redplayer.setheading(red_heading) redplayer.forward(3) # 根据当前朝向移动蓝摩托 blueplayer.setheading(blue_heading) blueplayer.forward(3) # 每20毫秒调用一次自己,实现持续移动 screen.ontimer(move_players, 20) # 倒计时 for x in range(10): turtle.color('white') style = ('Arial', 25, 'italic') turtle.write(10-x, font=style, align='center') time.sleep(1) turtle.undo() screen.listen() screen.onkey(RedUp, "w") screen.onkey(RedDown, "s") screen.onkey(RedLeft, "a") screen.onkey(RedRight, "d") screen.onkey(BlueUp, "Up") screen.onkey(BlueDown, "Down") screen.onkey(BlueLeft, "Left") screen.onkey(BlueRight, "Right") # 启动玩家移动 move_players() screen.mainloop() tron()
关键改动说明:
- 新增了
red_heading和blue_heading变量,用来记录两辆摩托的当前朝向,按键函数只负责更新这个变量,不会阻塞程序。 - 写了
move_players()函数,这个函数会让两辆摩托根据各自的朝向前进一小段,然后用screen.ontimer(move_players, 20)定时20毫秒后再次调用自己,这样就实现了持续且非阻塞的移动。 - 移除了所有按键函数里的
while True循环,彻底避免阻塞事件循环。
这样修改后,你操作其中一辆摩托时,另一辆会继续按照之前的方向移动,不会停下来,而且按键响应也会更流畅。
内容的提问来源于stack exchange,提问作者Ian
相关产品推荐
相关产品推荐

