Python Turtle双人追逐游戏:碰撞检测与计分功能异常求助
问题根源
你的碰撞检测代码只在程序启动时执行了一次,之后玩家移动过程中不会再检查角色与goal的位置关系,所以触发不了计分和goal随机移动的逻辑。原代码里的if判断写在wn.mainloop()之前,只会在初始化阶段运行一次,此时玩家还没开始移动,自然不会触发碰撞事件。
修复步骤
- 把碰撞检测逻辑封装成独立函数,同时处理两名玩家的碰撞判定
- 用
turtle.Screen().ontimer()定时调用检测函数,让游戏运行时持续检查碰撞 - 调整碰撞判定的距离阈值(原代码的5太小,turtle默认角色尺寸约20像素,设为20更容易触发合理的碰撞)
修复后的完整代码
import turtle as trtl import random as rand # 初始化游戏窗口 wn = trtl.Screen() # 创建玩家1:红色乌龟 player1 = trtl.Turtle() player1.shape('turtle') player1.fillcolor('red') player1.penup() player1.goto(rand.randint(-100,100), rand.randint(-100,100)) # 创建玩家2:蓝色三角形 player2 = trtl.Turtle() player2.shape('triangle') player2.fillcolor('blue') player2.penup() player2.goto(rand.randint(-100,100), rand.randint(-100,100)) # 创建目标:黄色圆形 goal = trtl.Turtle() goal.shape('circle') goal.fillcolor('yellow') goal.penup() # 修正原代码的错误:原第二个randint参数相同,导致y轴固定在-150 goal.goto(rand.randint(-200,200), rand.randint(-150,150)) # 初始化计分 player1_score = 0 player2_score = 0 # 玩家移动控制函数 def player1_up(): player1.setheading(90) player1.forward(10) def player2_up(): player2.setheading(90) player2.forward(10) def player1_down(): player1.setheading(270) player1.forward(10) def player2_down(): player2.setheading(270) player2.forward(10) def player1_right(): player1.setheading(0) player1.forward(10) def player2_right(): player2.setheading(0) player2.forward(10) def player1_left(): player1.setheading(180) player1.forward(10) def player2_left(): player2.setheading(180) player2.forward(10) # 碰撞检测函数 def check_collision(): global player1_score, player2_score # 检测玩家1与目标的碰撞 if abs(player1.xcor() - goal.xcor()) < 20 and abs(player1.ycor() - goal.ycor()) < 20: player1_score += 1 print(f"玩家1得分: {player1_score}") goal.goto(rand.randint(-200,200), rand.randint(-150,150)) # 检测玩家2与目标的碰撞 if abs(player2.xcor() - goal.xcor()) < 20 and abs(player2.ycor() - goal.ycor()) < 20: player2_score += 1 print(f"玩家2得分: {player2_score}") goal.goto(rand.randint(-200,200), rand.randint(-150,150)) # 每隔50毫秒重复调用检测函数,实现持续检测 wn.ontimer(check_collision, 50) # 绑定按键事件 wn.onkeypress(player1_up, "w") wn.onkeypress(player2_up, "i") wn.onkeypress(player1_down, "s") wn.onkeypress(player2_down, "k") wn.onkeypress(player1_right, "d") wn.onkeypress(player2_right, "l") wn.onkeypress(player1_left, "a") wn.onkeypress(player2_left, "j") wn.listen() # 启动碰撞检测循环 check_collision() wn.mainloop()
额外优化说明
- 修正了原代码中goal初始位置的bug:原代码
rand.randint(-150,-150)会让goal固定在y=-150,改为rand.randint(-150,150)让目标随机分布在合理区域 - 调整碰撞判定距离为20,匹配turtle默认角色的尺寸,避免因阈值太小导致碰撞难以触发
- 使用
global关键字在函数内部修改全局计分变量,确保计分能正常更新
内容的提问来源于stack exchange,提问作者Tim_Beranek
相关产品推荐
相关产品推荐

