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

如何修复贪吃蛇游戏中'Snake'对象无'distance'属性的AttributeError

排查并修复贪吃蛇游戏的AttributeError问题

错误信息

AttributeError: 'Snake' object has no attribute 'distance.'

你的代码片段

main.py

from turtle import Screen, Turtle
import turtle
import time
from snake import Snake
from food import Food

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("My snake game")
screen.tracer(0)


snake = Snake()
food = Food()

screen.listen()
screen.onkey(snake.up, "Up")
screen.onkey(snake.down, "Down")
screen.onkey(snake.right, "Right")
screen.onkey(snake.left, "Left")

snake.create_turtle()

is_game_on = True
while is_game_on:
    screen.update()
    time.sleep(0.1)
    snake.move()

    #detect collision with food
    if snake.head.distance(food) < 15:
        food.refresh()
    
    
    
screen.exitonclick()

snake.py

from turtle import Turtle
X_POSITION = [0, -20, -40]
MOVE_POSITION = 20
UP = 90
DOWN = 270
LEFT = 180
RIGHT = 0

class Snake:
    def __init__(self):
        self.turtle_list = []
        self.create_turtle()
        self.move()
    
    def create_turtle(self):
        for turtle_index in range(0, 3):
            new_turtle = Turtle(shape="square")
            new_turtle.color("white")
            new_turtle.penup()
            new_turtle.goto(x=X_POSITION[turtle_index],y=0)
            self.turtle_list.append(new_turtle)



    def move(self):
        for seg in range(len(self.turtle_list) -1, 0, -1):  #(same as start= 2, stop= 0, step= 1):
            new_x = self.turtle_list[seg -1].xcor()
            new_y = self.turtle_list[seg -1].ycor()
            self.turtle_list[seg].goto(x=new_x, y=new_y) 
        self.turtle_list[0].forward(MOVE_POSITION)
    
    def up(self):
        if self.turtle_list[0].heading() != DOWN:
            self.turtle_list[0].setheading(UP)
    
    def down(self):
        if self.turtle_list[0].heading() != UP:
            self.turtle_list[0].setheading(DOWN)

    def left(self):
        if self.turtle_list[0].heading() != RIGHT:
            self.turtle_list[0].setheading(LEFT)

    def right(self):
        if self.turtle_list[0].heading() != LEFT:
            self.turtle_list[0].setheading(RIGHT)

food.py

from turtle import Turtle, circle
import random

class Food(Turtle):
    def __init__(self):
        super().__init__()
        self.shape("circle")
        self.shapesize(stretch_len=0.5, stretch_wid=0.5)
        self.penup()
        self.speed("fastest")
        self.color("green")
        self.refresh
        
    
    def refresh(self):
        random_x = random.randint(-280, 280)
        random_y = random.randint(-280, 280)
        self.goto(random_x,random_y)

问题排查与修复方案

1. 核心错误:Snake类未定义head属性

你在main.py中尝试通过snake.head调用distance方法,但Snake类里并没有定义head这个属性,这是触发AttributeError的直接原因。

修复方式:在Snake类的__init__方法中,将蛇的头部(即turtle_list的第一个元素)赋值给self.head:

class Snake:
    def __init__(self):
        self.turtle_list = []
        self.create_turtle()
        self.head = self.turtle_list[0]  # 新增这行定义head属性
        # 移除self.move(),避免游戏未启动蛇就提前移动

同时删掉main.py中的snake.create_turtle()——因为Snake的__init__已经调用过这个方法,重复调用会创建额外的蛇身段。

2. Food类初始化未执行refresh方法

food.py的__init__中写的是self.refresh,这只是引用方法而非执行方法,导致游戏启动时食物不会出现在随机位置。

修复方式:给self.refresh加上括号,改为执行方法:

class Food(Turtle):
    def __init__(self):
        super().__init__()
        self.shape("circle")
        self.shapesize(stretch_len=0.5, stretch_wid=0.5)
        self.penup()
        self.speed("fastest")
        self.color("green")
        self.refresh()  # 加上括号执行方法

3. Snake类提前执行move方法

Snake类__init__中的self.move()会导致游戏还没进入主循环,蛇就先移动了,不符合预期,直接删除这行即可。

修复后验证

完成上述修改后,main.py中snake.head.distance(food)就能正常调用乌龟对象的distance方法,食物也会在游戏启动时随机生成,蛇的移动逻辑也会回归正常。

内容的提问来源于stack exchange,提问作者Ruban Raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:23:14