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

如何在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
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 06:57:12