Python Turtle贪吃蛇游戏报错:'float'对象不可下标访问
贪吃蛇游戏报错:吃到食物后程序崩溃
我使用Python的turtle模块开发贪吃蛇游戏,项目包含main.py、food.py、scoreboard.py和snake.py四个文件。每当蛇吃到食物时,程序就会停止运行并抛出错误,推测问题出在add_segment方法中。
各文件代码
main.py
from turtle import Screen from snake import Snake from food import Food from scoreboard import Scoreboard import time screen = Screen() screen.setup(600,600) screen.title("Snake Game") screen.bgcolor("black") screen.tracer(0) # 关闭动画 snake = Snake() food = Food() scoreboard = Scoreboard() screen.listen() screen.onkeypress(fun=snake.up,key="Up") screen.onkeypress(fun=snake.down,key="Down") screen.onkeypress(fun=snake.left,key="Left") screen.onkeypress(fun=snake.right,key="Right") is_game_on = True score = 0 while is_game_on: screen.update() time.sleep(0.1) snake.move() # 检测食物碰撞 if snake.head.distance(food) < 15: food.refresh() scoreboard.score_update() snake.extend() # 检测墙壁碰撞 if snake.head.xcor() > 280 or snake.head.xcor() < -280 or\ snake.head.ycor() > 280 or snake.head.ycor()<-280: scoreboard.game_over() is_game_on = False screen.exitonclick()
food.py
import random from turtle import Turtle class Food(Turtle): def __init__(self) -> None: super().__init__() self.shape("circle") self.penup() self.shapesize(stretch_len=0.5,stretch_wid=0.5) self.color("red") self.speed("fastest") self.refresh() def refresh(self): random_coordinates = ( random.randint(-280,280), random.randint(-280,280) ) self.goto(random_coordinates)
scoreboard.py
from turtle import Turtle ALIGNMENT = "center" FONT_NAME = "Courier" FONT_SIZE = 17 FONT_TYPE = "normal" class Scoreboard(Turtle): score = 0 def __init__(self): super().__init__() self.color("yellow") self.hideturtle() self.penup() self.teleport(0,275) self.write(arg="score = 0",move=False,align=ALIGNMENT,font=(FONT_NAME, FONT_SIZE, FONT_TYPE)) def score_update(self,): self.score += 1 self.clear() self.write(arg=f"score = {self.score}",move=False,align=ALIGNMENT,font=(FONT_NAME, FONT_SIZE, FONT_TYPE)) def game_over(self): self.home() self.write(arg=f"GAME OVER",move=False,align=ALIGNMENT,font=(FONT_NAME, FONT_SIZE, FONT_TYPE))
snake.py
from turtle import Turtle, Screen MOVE_DISTANCE = 20 UP = 90 DOWN = 270 LEFT = 180 RIGHT = 0 class Snake: def __init__(self) -> None: self.segments = [] self.create_snake() self.head = self.segments[0] def create_snake(self): self.x_cor = 0 for i in range(3): self.add_segment(self.x_cor) self.x_cor -= 20 def add_segment(self,position): segment = Turtle("square") segment.color("white") segment.penup() segment.speed("slowest") segment.teleport(x=position,y=0) self.segments.append(segment) def extend(self): self.add_segment((self.segments)[-1].pos()) def move(self): for seq_num in range(len(self.segments) -1, 0 ,-1): new_x = self.segments[seq_num - 1].xcor() new_y = self.segments[seq_num - 1].ycor() self.segments[seq_num].goto(new_x, new_y) self.head.forward(MOVE_DISTANCE) def up(self): if self.head.heading() != DOWN: self.head.setheading(UP) def down(self): if self.head.heading() != UP: self.head.setheading(DOWN) def left(self): if self.head.heading() != RIGHT: self.head.setheading(LEFT) def right(self): if self.head.heading() != LEFT: self.head.setheading(RIGHT)
报错信息
Traceback (most recent call last): File "/home/xenon_54/Snake_Game/main.py", line 29, in <module> screen.update() File "/usr/lib64/python3.12/turtle.py", line 1296, in update t._drawturtle() File "/usr/lib64/python3.12/turtle.py", line 3080, in _drawturtle shape = self._polytrafo(self._getshapepoly(tshape)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib64/python3.12/turtle.py", line 3033, in _polytrafo return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale) ~~^~~~~~~~~~~~~~~~~~~~~~~~~~ File "/usr/lib64/python3.12/turtle.py", line 248, in __add__ return Vec2D(self[0]+other[0], self[1]+other[1]) ~~~~~^^^ TypeError: 'float' object is not subscriptable
问题原因
报错核心是TypeError: 'float' object is not subscriptable,根源在snake.py的方法配合上:
extend方法调用add_segment时,传入的self.segments[-1].pos()返回的是Vec2D对象(包含x、y坐标的二元组类型)。- 但
add_segment方法直接把这个Vec2D对象传给teleport(x=position,y=0)的x参数,导致turtle内部处理坐标时,误将Vec2D当成单个数值,最终触发类型错误。
解决方案
修改snake.py代码,让add_segment正确处理坐标对即可,以下两种方案任选其一:
方案1:统一使用坐标元组传参
- 修改
create_snake方法,传入(x,y)坐标元组:
def create_snake(self): self.x_cor = 0 for i in range(3): self.add_segment((self.x_cor, 0)) self.x_cor -= 20
- 修改
add_segment方法,直接用goto接收坐标:
def add_segment(self, position): segment = Turtle("square") segment.color("white") segment.penup() segment.speed("slowest") segment.goto(position) self.segments.append(segment)
方案2:兼容两种参数类型
如果想保留初始的单个x值传参方式,可让方法自动判断参数类型:
def add_segment(self, position): segment = Turtle("square") segment.color("white") segment.penup() segment.speed("slowest") if isinstance(position, (int, float)): segment.teleport(x=position, y=0) else: segment.goto(position) self.segments.append(segment)
修改后蛇吃到食物时就能正常延长,不会再触发报错。
内容的提问来源于stack exchange,提问作者Ayush Dey
相关产品推荐
相关产品推荐

