如何在Python Turtle迷宫游戏中添加墙体碰撞检测?
Python Turtle迷宫游戏:墙体碰撞检测实现方案
我正在开发一款基于Python Turtle的迷宫游戏,需要为墙体添加碰撞检测功能,避免玩家角色穿墙。尝试过多种方法但均未成功,考虑通过数组实现碰撞检测,但作为Python和Turtle的新手,不清楚具体实现方式。以下是我的游戏代码:
import turtle import random import time print("TURTLE MAZE") player = turtle.Turtle() player.penup() player.speed(0) player.shape("square") player.pensize(5) player.color('red') player.pencolor('white') player.goto(-210,-210) screen = turtle.Screen() screen.title("Maze ") screen.bgcolor("White") screen.setup(width=1000, height=600) grid = [ [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ,2, 2 ,2, 2 ,2, 2, 2, 2, 2, 2, 2, 2, ], [2, 3, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 ,0, 0 ,0, 0 ,0, 0, 0, 1, 0, 1, 3, 2, ], [2, 0, 1, 1, 0, 0, 0, 1, 0, 8, 0, 0 ,1, 1 ,0, 1 ,0, 1, 0, 1, 0, 0, 0, 2, ], [2, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1 ,1, 0 ,0, 1 ,0, 1, 1, 1, 0, 1, 0, 2, ], [2, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0 ,1, 0 ,1, 1 ,0, 0, 0, 1, 0, 8, 0, 2, ], [2, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1 ,1, 0 ,0, 1 ,0, 1, 0, 0, 0, 1, 1, 2, ], [2, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0 ,0, 0 ,1, 1 ,0, 1, 1, 1, 0, 0, 0, 2, ], [2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 ,1, 1 ,1, 0 ,0, 0, 0, 1, 0, 1, 0, 2, ], [2, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0 ,1, 0 ,1, 1 ,1, 1, 0, 1, 1, 1, 8, 2, ], [2, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 ,1, 0 ,0, 1 ,0, 1, 0, 1, 0, 0, 0, 2, ], [2, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 ,0, 0 ,0, 0, 0, 1, 0, 0, 0, 2, ], [2, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 ,1, 1 ,0, 1, 0, 1, 1, 1, 0, 2, ], [2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0 ,1, 0 ,0, 1, 0, 0, 1, 0, 0, 2, ], [2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0 ,1, 1 ,1, 1, 0, 0, 0, 0, 1, 2, ], [2, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0 ,0, 0 ,0, 1, 1, 1, 1, 0, 1, 2, ], [2, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 ,1, 1 ,0, 0, 0, 1, 0, 0, 1, 2, ], [2, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1 ,0, 1 ,0, 1, 0, 1, 0, 1, 1, 2, ], [2, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 8 ,0, 0 ,0, 1, 0, 8, 0, 0, 0, 2, ], [2, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1 ,1, 1 ,1, 1, 0, 1, 0, 1, 1, 2, ], [2, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 ,0, 0 ,0, 1, 0, 1, 0, 1, 0, 2, ], [2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1 ,1, 1 ,0, 0, 0, 1, 1, 1, 0, 2, ], [2, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1 ,0, 0 ,0, 1, 0, 0, 0, 1, 0, 2, ], [2, 4, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1 ,0, 1 ,0, 1, 0, 1, 0, 0, 3, 2, ], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ,2, 2 ,2, 2 ,2, 2, 2, 2, 2, 2, ] ] tiles = ['empty', 'wall'] pen = turtle.Turtle() pen.penup() pen.speed(0) pen.shape("square") pen.setundobuffer(None) def draw_grid(pen, grid): pen.clear() top = 230 left = -230 colors = ["black", "lightblue", "blue", "orange", "yellow", "green", "purple", "red","sky blue"] for y in range(len(grid)): for x in range(len(grid[0])): screen_x = left + (x * 20) screen_y = top - (y * 20) color_number = grid[y][x] color = colors[color_number] pen.color(color) pen.goto(screen_x, screen_y) pen.stamp() draw_grid(pen, grid) class Movement: def movePlayerRight(): x = player.xcor() x += 20 player.setx(x) print(x) def movePlayerLeft(): x = player.xcor() x -= 20 player.setx(x) print(x) def movePlayerUp(): y = player.ycor() y += 20 player.sety(y) print(y) def movePlayerDown(): y = player.ycor() y -= 20 player.sety(y) print(y) screen.listen() screen.onkeypress(movePlayerRight, "Right") screen.onkeypress(movePlayerLeft, "Left") screen.onkeypress(movePlayerUp, "Up") screen.onkeypress(movePlayerDown, "Down") Movement() while True: screen.update() if player.xcor() < -210: player.setx(player.xcor() + 20) print("Nuh uh, Dont try go outside...") if player.xcor() > 210: player.setx(player.xcor() - 20) print("Nuh uh, Dont try go outside...") if player.ycor() < -210: player.sety(player.ycor() + 20) print("Nuh uh, Dont try go outside...") if player.ycor() > 210: player.sety(player.ycor() - 20) print("Nuh uh, don't try go outside...") going = True while going == True: screen.update()
实现碰撞检测的具体步骤:
1. 坐标转换函数
将玩家的屏幕坐标转换为网格数组的索引,每个格子边长为20px,网格左上角对应屏幕坐标(-230, 230),计算方式如下:
def get_grid_pos(x, y): grid_x = int((x + 230) // 20) grid_y = int((230 - y) // 20) # 确保索引在网格范围内 if 0 <= grid_x < len(grid[0]) and 0 <= grid_y < len(grid): return grid_y, grid_x return None
2. 碰撞检测函数
检查目标位置是否为墙体(grid中值为1的元素):
def is_wall(grid_y, grid_x): if grid_y is None or grid_x is None: return True return grid[grid_y][grid_x] == 1
3. 修改移动函数
在移动前先检查目标位置是否合法,只有非墙体才能移动:
class Movement: def movePlayerRight(): current_x = player.xcor() target_x = current_x + 20 target_y = player.ycor() grid_pos = get_grid_pos(target_x, target_y) if grid_pos and not is_wall(*grid_pos): player.setx(target_x) print(player.xcor()) def movePlayerLeft(): current_x = player.xcor() target_x = current_x - 20 target_y = player.ycor() grid_pos = get_grid_pos(target_x, target_y) if grid_pos and not is_wall(*grid_pos): player.setx(target_x) print(player.xcor()) def movePlayerUp(): current_y = player.ycor() target_y = current_y + 20 target_x = player.xcor() grid_pos = get_grid_pos(target_x, target_y) if grid_pos and not is_wall(*grid_pos): player.sety(target_y) print(player.ycor()) def movePlayerDown(): current_y = player.ycor() target_y = current_y - 20 target_x = player.xcor() grid_pos = get_grid_pos(target_x, target_y) if grid_pos and not is_wall(*grid_pos): player.sety(target_y) print(player.ycor()) screen.listen() screen.onkeypress(movePlayerRight, "Right") screen.onkeypress(movePlayerLeft, "Left") screen.onkeypress(movePlayerUp, "Up") screen.onkeypress(movePlayerDown, "Down")
4. 优化主循环
去掉冗余的循环,保留一个主循环即可:
while True: screen.update() if player.xcor() < -210: player.setx(-210) print("Nuh uh, Dont try go outside...") if player.xcor() > 210: player.setx(210) print("Nuh uh, Dont try go outside...") if player.ycor() < -210: player.sety(-210) print("Nuh uh, Dont try go outside...") if player.ycor() > 210: player.sety(210) print("Nuh uh, don't try go outside...")
修改后的完整代码
import turtle import random import time print("TURTLE MAZE") player = turtle.Turtle() player.penup() player.speed(0) player.shape("square") player.pensize(5) player.color('red') player.pencolor('white') player.goto(-210,-210) screen = turtle.Screen() screen.title("Maze ") screen.bgcolor("White") screen.setup(width=1000, height=600) grid = [ [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ,2, 2 ,2, 2 ,2, 2, 2, 2, 2, 2, 2, 2, ], [2, 3, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 ,0, 0 ,0, 0 ,0, 0, 0, 1, 0, 1, 3, 2, ], [2, 0, 1, 1, 0, 0, 0, 1, 0, 8, 0, 0 ,1, 1 ,0, 1 ,0, 1, 0, 1, 0, 0, 0, 2, ], [2, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1 ,1, 0 ,0, 1 ,0, 1, 1, 1, 0, 1, 0, 2, ], [2, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0 ,1, 0 ,1, 1 ,0, 0, 0, 1, 0, 8, 0, 2, ], [2, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1 ,1, 0 ,0, 1 ,0, 1, 0, 0, 0, 1, 1, 2, ], [2, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0 ,0, 0 ,1, 1 ,0, 1, 1, 1, 0, 0, 0, 2, ], [2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1 ,1, 1 ,1, 0 ,0, 0, 0, 1, 0, 1, 0, 2, ], [2, 1, 0, 1, 1, 0
相关产品推荐
相关产品推荐

