如何实现子弹Turtle触碰僵尸Turtle后使其消失或移动?
解决Turtle僵尸射击游戏的碰撞检测与僵尸移动问题
问题根源
- 碰撞检测未生效:你写的
if b.xcor() == z.xcor(): z.clear()只在程序启动时执行一次,不会在子弹飞行过程中实时检测;而且子弹用forward(400)瞬间完成移动,没有逐帧更新,根本抓不到碰撞时机。 - 僵尸无法移动:没有在游戏主循环中添加僵尸的移动逻辑,自然不会动。
修复方案
核心修改点
- 将子弹的瞬间飞行改为逐帧移动,每移动一小步就检测一次碰撞
- 用
distance()方法判断碰撞(比坐标相等更贴合图形实际大小,避免因坐标精度问题检测不到) - 新增僵尸随机移动的定时触发逻辑
- 移除初始化阶段的无效碰撞检测代码
修改后的完整代码
import turtle as trtl import random wn = trtl.Screen() # 初始化角色 p = trtl.Turtle() z = trtl.Turtle() b = trtl.Turtle() counter = trtl.Turtle() font_setup = ("Arial", 20, "normal") p.penup() b.penup() b.hideturtle() pSpeed = 30 bSpeed = 10 # 降低子弹速度,方便碰撞检测 zSpeed = 5 # 僵尸移动速度 # 注册自定义形状(保留你的原有注册) trtl.register_shape("appleleft.gif") trtl.register_shape("appleright.gif") trtl.register_shape("mario.gif") trtl.register_shape("mario2.gif") trtl.register_shape("bullet.gif") trtl.register_shape("bulletleft.gif") trtl.register_shape("bosszombie.gif") p.shape("mario.gif") b.shape("bullet.gif") z.shape("bosszombie.gif") z.goto(200, 0) z.penup() wn.bgpic("mars.gif") def shoot(): b.goto(p.position()) b.showturtle() # 逐帧移动子弹并检测碰撞 while b.distance(wn.window_width()/2, b.ycor()) > 10: b.forward(bSpeed) # 检测子弹与僵尸的碰撞(距离小于50视为碰撞,可根据图形大小调整) if b.distance(z) < 50: z.hideturtle() # 碰撞后让僵尸随机瞬移到新位置 z.goto(random.randint(-250, 250), random.randint(-250, 250)) z.showturtle() break # 碰撞后停止当前子弹飞行 b.hideturtle() b.goto(p.position()) def move_left(): x = p.xcor() - pSpeed if x < -280: x = -280 p.setx(x) p.shape("mario2.gif") b.shape("bulletleft.gif") b.setheading(180) def move_up(): y = p.ycor() + pSpeed if y > 280: y = 280 p.sety(y) def move_down(): y = p.ycor() - pSpeed if y < -280: y = -280 p.sety(y) def move_right(): x = p.xcor() + pSpeed if x > 280: x = 280 p.setx(x) p.shape("mario.gif") b.shape("bullet.gif") b.setheading(0) def zombie_random_move(): # 随机选择移动方向 dx = random.randint(-zSpeed, zSpeed) dy = random.randint(-zSpeed, zSpeed) new_x = z.xcor() + dx new_y = z.ycor() + dy # 限制僵尸在窗口内移动 if -280 <= new_x <= 280 and -280 <= new_y <= 280: z.goto(new_x, new_y) # 每隔100ms触发一次移动,形成持续随机移动 wn.ontimer(zombie_random_move, 100) # 绑定按键 wn.onkeypress(move_left, "a") wn.onkeypress(move_up, "w") wn.onkeypress(move_down, "s") wn.onkeypress(move_right, "d") wn.onkeypress(shoot, "l") wn.listen() # 启动僵尸随机移动 zombie_random_move() wn.mainloop()
关键说明
- 子弹改为逐帧移动,每移动一次就检查与僵尸的距离,当距离小于设定值时触发碰撞逻辑
- 碰撞后僵尸会瞬移到随机位置,你也可以改成其他逻辑(比如消失一段时间再出现)
- 僵尸的随机移动用
ontimer()定时触发,保证游戏运行时持续移动 - 调整了子弹速度,避免因速度过快导致碰撞检测漏判
内容的提问来源于stack exchange,提问作者Youngish
相关产品推荐
相关产品推荐

