You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Turtle迷宫游戏如何无需逐个定义坐标实现墙体碰撞检测

解决方案

你可以用轴对齐矩形碰撞检测的方案实现高效的碰撞校验,全程只用到turtle自带的坐标计算,不需要引入额外库,核心逻辑是预先把所有墙体存成「矩形边界列表」,每次移动前预判位置是否撞墙,具体实现如下:

第一步:定义墙体矩形数据结构

你画的所有墙体都是轴对齐的矩形,每个矩形只需要存4个值:左边界x坐标、右边界x坐标、下边界y坐标、上边界y坐标,把所有墙体的这四个值都存在一个列表里就行,不需要再单独给每个墙体写判断逻辑。

第二步:实现碰撞检测函数

写一个通用的碰撞检测函数,输入海龟的下一个位置坐标,遍历所有墙体矩形,判断坐标是否落在任意一个矩形内部即可。

  • 碰撞判断逻辑:如果海龟的x在墙体左、右边界之间,且y在墙体下、上边界之间,就判定为碰撞

第三步:修改移动逻辑

原来的travel函数直接前进,现在改成先计算下一个位置,判断不撞墙再前进,撞墙就停在原地。

可直接运行的修改后代码

import turtle
import random

screen = turtle.Screen()
screen.tracer(0)

# ---------------------- 新增:墙体边界列表,所有墙体的矩形边界都存在这里 ----------------------
# 每个元素格式:(左边界x, 右边界x, 下边界y, 上边界y)
walls = [
    # 中间竖条上下两段
    (-20, 20, 140, 200),
    (-20, 20, -200, -140),
    # 左上角墙体
    (-200, -180, -200, -160),
    (-200, -180, -160, 200),
    # 右侧大墙体
    (20, 200, -200, 200),
    (20, 80, 140, 200),
    (80, 180, 180, 200),
    (100, 180, -80, 180),
    (20, 100, -140, -80),
    # 上侧小墙体
    (-80, -60, 140, 160),
    (-60, -20, 120, 140),
    (-20, 40, 100, 120),
    (120, 140, 100, 140),
    # 中部偏右墙体
    (80, 140, 60, 100),
    (100, 140, 20, 60),
    (20, 80, 60, 100),
    # 中部竖条墙体
    (20, 20, -100, 60),
    (-20, 20, -100, -40),
    (-60, -20, -100, -40),
    # 左下角墙体
    (-140, -60, -160, -140),
    (-160, -140, -120, -160),
    (-160, -160, -40, -120),
    # 中部偏左墙体
    (-60, -20, 0, -60),
    (-20, -20, 0, 40),
    (-60, -20, 40, 80),
    (-120, -60, 80, 80),
    (-120, -120, 80, 200),
    # 左侧竖条墙体
    (-160, -160, 40, 160),
    (-160, -40, 40, 40),
    # 右下墙体
    (60, 60, -80, 20),
    (60, 140, -40, -20),
    # 左侧墙体
    (-200, -120, 0, 0),
    (-120, -100, 0, -80),
    (-100, -100, -80, -120),
    (-20, -20, -200, -140)
]
# 海龟碰撞判定的容差,因为海龟本身有大小,避免半个身子穿进墙
TOLERANCE = 5

# 碰撞检测函数
def is_collision(next_x, next_y):
    for (x1, x2, y1, y2) in walls:
        if (x1 - TOLERANCE <= next_x <= x2 + TOLERANCE) and (y1 - TOLERANCE <= next_y <= y2 + TOLERANCE):
            return True
    return False

# ---------------------- 原有绘制迷宫的逻辑 ----------------------
mazeWidth=150
tr = turtle.Turtle()
tr.width(5)
tr.speed(0)
tr.penup()
tr.goto(-mazeWidth,190)
def drawMazeSection(color):
  tr.pencolor("lightblue")
  tr.penup()
  tr.goto(-20,200)
  tr.pendown()
  tr.goto(20,200)
  tr.penup()
  tr.goto(-20,-200)
  tr.pendown()
  tr.goto(20,-200)
  tr.penup()
  tr.pencolor("black")
  tr.goto(-200,200)
  tr.pendown()
  tr.goto(-200,-160)
  tr.begin_fill()
  tr.goto(-180,-160)
  tr.goto(-180,-200)
  tr.goto(-200,-200)
  tr.end_fill()
  tr.goto(-20,-200)
  tr.penup()
  tr.goto(20,-200)
  tr.pendown()
  tr.begin_fill()
  tr.goto(200,-200)
  tr.goto(200,200)
  tr.goto(20,200)
  tr.goto(20,140)
  tr.goto(80,140)
  tr.goto(80,180)
  tr.goto(180,180)
  tr.goto(180,-80)
  tr.goto(100,-80)
  tr.goto(100,-140)
  tr.goto(20,-140)
  tr.goto(20,-200)
  tr.end_fill()
  tr.penup()
  tr.goto(20,160)
  tr.pendown()
  tr.begin_fill()
  tr.goto(-80,160)
  tr.goto(-80,140)
  tr.goto(-60,140)
  tr.goto(-60,160)
  tr.end_fill()
  tr.goto(-60,120)
  tr.goto(-20,120)
  tr.goto(-20,100)
  tr.goto(40,100)
  tr.penup()
  tr.goto(120,140)
  tr.pendown()
  tr.begin_fill()
  tr.goto(140,140)
  tr.goto(140,100)
  tr.goto(120,100)
  tr.goto(120,120)
  tr.goto(120,140)
  tr.end_fill()
  tr.goto(140,100)
  tr.goto(80,100)
  tr.goto(80,80)
  tr.goto(80,60)
  tr.begin_fill()
  tr.goto(140,60)
  tr.goto(140,20)
  tr.goto(100,20)
  tr.goto(100,60)
  tr.end_fill()
  tr.goto(20,60)
  tr.goto(20,-100)
  tr.goto(20,-40)
  tr.goto(-20,-40)
  tr.goto(-20,-100)
  tr.goto(-60,-100)
  tr.penup()
  tr.goto(-60,-140)
  tr.pendown()
  tr.goto(-60,-160)
  tr.goto(-140,-160)
  tr.goto(-140,-120)
  tr.goto(-160,-120)
  tr.goto(-160,-40)
  tr.penup()
  tr.goto(-60,-60)
  tr.pendown()
  tr.goto(-60,0)
  tr.goto(-20,0)
  tr.goto(-20,40)
  tr.goto(-60,40)
  tr.goto(-60,80)
  tr.goto(-120,80)
  tr.goto(-120,200)
  tr.penup()
  tr.goto(-160,160)
  tr.pendown()
  tr.goto(-160,40)
  tr.goto(-40,40)
  tr.penup()
  tr.goto(60,20)
  tr.pendown()
  tr.goto(60,-80)
  tr.begin_fill()
  tr.goto(60,-40)
  tr.goto(140,-40)
  tr.goto(140,-20)
  tr.goto(60,-20)
  tr.end_fill()
  tr.penup()
  tr.goto(-200,0)
  tr.pendown()
  tr.goto(-100,0)
  tr.begin_fill()
  tr.goto(-100,-120)
  tr.goto(-100,-80)
  tr.goto(-120,-80)
  tr.goto(-120,0)
  tr.end_fill()
  tr.penup()
  tr.goto(-20,-140)
  tr.pendown()
  tr.goto(-20,-200)
  
for color in ["#FF0000","#0000FF","#00FF00"]:
  drawMazeSection(color)
  

screen.tracer(1)    
wn = turtle.Screen()
wn.bgcolor('darkgreen')

# 初始化玩家海龟
player = turtle.Turtle()
player.shape('turtle')
player.color("#DB148E")
player.penup()
player.goto(0,-200)
player.left(90)

speed = 1.5

# ---------------------- 修改后的移动逻辑,加碰撞检测 ----------------------
def travel():
    heading = player.heading()
    next_x, next_y = player.xcor(), player.ycor()
    if heading == 0: # 右
        next_x += speed
    elif heading == 90: # 上
        next_y += speed
    elif heading == 180: # 左
        next_x -= speed
    elif heading == 270: # 下
        next_y -= speed
    # 没撞墙才移动
    if not is_collision(next_x, next_y):
        player.goto(next_x, next_y)
    wn.ontimer(travel, 10)

wn.onkey(lambda: player.setheading(90), 'w')
wn.onkey(lambda: player.setheading(180), 'a')
wn.onkey(lambda: player.setheading(0), 'd')
wn.onkey(lambda: player.setheading(270), 's')

wn.listen()
travel()

wn.mainloop()

后续优化建议

  • 如果你要修改迷宫的墙体,只需要修改walls列表里的对应矩形参数即可,不需要改碰撞逻辑
  • 可以调整TOLERANCE参数适配海龟的大小,避免出现卡墙或者穿模的问题

内容的提问来源于stack exchange,提问作者Dane Jacobs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 21:06:05