如何阻止Python turtle开发的迷宫游戏中角色穿出墙体边界
迷宫游戏墙体碰撞解决方案
你当前代码存在两个核心问题:
- 墙体变量重复赋值:从第4个墙体开始全部使用
box_4作为变量名,导致前几个box_4的墙体实例被覆盖,无法统一做碰撞检测。 - 缺失碰撞检测逻辑:移动角色前没有预判是否会和墙体碰撞,直接更新坐标导致穿模。
具体实现方案
采用轴对齐边界盒(AABB)碰撞检测算法,矩形角色和矩形墙体的碰撞只需判断两个矩形在水平、垂直方向是否同时重叠,逻辑简单性能适配turtle的渲染效率。
修改步骤如下:
- 修正墙体变量命名,将所有墙体存入统一列表方便批量检测
- 封装碰撞检测函数,支持传入角色预移动坐标判断是否会发生碰撞
- 修改角色移动逻辑,仅当预移动无碰撞时才更新角色实际坐标
完整修改后代码
import turtle wn = turtle.Screen() wn.setup(width=1000, height=700) wn.bgcolor('white') wn.title('test') wn.tracer(0) # 墙体定义,修正变量重复命名问题 box_1 = turtle.Turtle() box_1.shape('square') box_1.penup() box_1.color('black') box_1.goto(-485, 0) box_1.shapesize(stretch_len=1.5, stretch_wid=35) box_2 = turtle.Turtle() box_2.shape('square') box_2.penup() box_2.color('black') box_2.goto(-500, -95) box_2.shapesize(stretch_len=35, stretch_wid=1.5) box_3 = turtle.Turtle() box_3.shape('square') box_3.penup() box_3.color('black') box_3.goto(-325, 0) box_3.shapesize(stretch_len=1.5, stretch_wid=10) box_4 = turtle.Turtle() box_4.shape('square') box_4.penup() box_4.color('black') box_4.goto(-145, -180) box_4.shapesize(stretch_len=1.5, stretch_wid=10) box_5 = turtle.Turtle() box_5.shape('square') box_5.penup() box_5.color('black') box_5.goto(-240, -265) box_5.shapesize(stretch_len=10, stretch_wid=1.5) box_6 = turtle.Turtle() box_6.shape('square') box_6.penup() box_6.color('black') box_6.goto(-345, -220) box_6.shapesize(stretch_len=1.5, stretch_wid=6) box_7 = turtle.Turtle() box_7.shape('square') box_7.penup() box_7.color('black') box_7.goto(-190, 90) box_7.shapesize(stretch_len=15, stretch_wid=1.5) # 所有墙体存入列表 walls = [box_1, box_2, box_3, box_4, box_5, box_6, box_7] character = turtle.Turtle() character.shape('square') character.speed(0) character.penup() character.color('yellow') character.goto(-485, 335) character.shapesize(stretch_wid=1, stretch_len=1) # 角色大小固定,半长半高都是10像素(默认正方形边长20) CHAR_HALF_SIZE = 10 # 碰撞检测函数:传入预移动的x,y坐标,判断是否会和墙体碰撞 def check_collision(new_x, new_y): char_left = new_x - CHAR_HALF_SIZE char_right = new_x + CHAR_HALF_SIZE char_top = new_y + CHAR_HALF_SIZE char_bottom = new_y - CHAR_HALF_SIZE for wall in walls: # shapesize返回顺序为(垂直拉伸值, 水平拉伸值, 边框宽度) stretch_wid, stretch_len = wall.shapesize()[0], wall.shapesize()[1] wall_half_width = stretch_len * 10 wall_half_height = stretch_wid * 10 wall_left = wall.xcor() - wall_half_width wall_right = wall.xcor() + wall_half_width wall_top = wall.ycor() + wall_half_height wall_bottom = wall.ycor() - wall_half_height # 两个矩形重叠则判定为碰撞 if char_right > wall_left and char_left < wall_right and char_top > wall_bottom and char_bottom < wall_top: return True return False def character_up(): new_x = character.xcor() new_y = character.ycor() + 10 if not check_collision(new_x, new_y): character.sety(new_y) def character_down(): new_x = character.xcor() new_y = character.ycor() - 10 if not check_collision(new_x, new_y): character.sety(new_y) def character_right(): new_x = character.xcor() + 10 new_y = character.ycor() if not check_collision(new_x, new_y): character.setx(new_x) def character_left(): new_x = character.xcor() - 10 new_y = character.ycor() if not check_collision(new_x, new_y): character.setx(new_x) wn.listen() wn.onkeypress(character_up, "Up") wn.onkeypress(character_down, "Down") wn.onkeypress(character_right, "Right") wn.onkeypress(character_left, "Left") while True: wn.update()
内容的提问来源于stack exchange,提问作者Beluga
相关产品推荐
相关产品推荐

