Python Turtle贪吃蛇添加尾部碰撞检测后启动即结束问题排查
贪吃蛇游戏启动即触发Game Over问题排查
问题根源分析
1. 蛇段初始化位置错误(核心原因)
在snake.py的add_segment方法中,你完全忽略了传入的position参数,而是用自定义变量a强制设置所有蛇段的位置,导致初始的三个蛇段全部重叠在(0,0)位置。游戏启动后,尾部碰撞检测立刻检测到头部与身体重叠,直接触发Game Over。
2. 全局变量作用域问题
main.py中的tail_collision函数修改game_on变量时,未声明global game_on,导致修改的是函数内部的局部变量,外部的game_on不会被终止。不过因为初始蛇段重叠,scoreboard.game_over()会被调用,所以仍然会显示Game Over界面。
3. 冗余代码
main.py中game_over = Turtle这行代码完全多余,没有实际作用,建议删除。
修复代码
修复snake.py
修改create_snake和add_segment方法,让蛇段按照预设的初始位置创建:
from turtle import Turtle import time START_POSITION = [(0, 0), (-20, 0), (-40, 0)] MOVE_DIST = 20 class Snake: def __init__(self): self.segments = [] self.create_snake() self.snake_head = self.segments[0] def create_snake(self): # 遍历预设位置,传入正确坐标到add_segment for position in START_POSITION: self.add_segment(position) def add_segment(self, position): snake_body = Turtle("square") snake_body.color("white") snake_body.penup() # 使用传入的position参数设置蛇段位置 snake_body.goto(position) self.segments.append(snake_body) def extend(self): self.add_segment(self.segments[-1].position()) def move(self): for seg_num in range(len(self.segments) - 1, 0, -1): new_x = self.segments[seg_num - 1].xcor() new_y = self.segments[seg_num - 1].ycor() self.segments[seg_num].goto(new_x, new_y) self.snake_head.forward(MOVE_DIST) def turn(self, direction): if direction - 180 != self.snake_head.heading() and direction + 180 != self.snake_head.heading(): self.snake_head.setheading(direction) else: pass
修复main.py
修正tail_collision函数的变量作用域,并删除冗余代码:
from turtle import Turtle, Screen import time from snake import Snake from food import Food from scoreboard import ScoreBoard screen = Screen() screen.setup(width=600, height=600) screen.bgcolor("black") screen.title("Snake Game") snake = Snake() food = Food() scoreboard = ScoreBoard() UP = 90 DOWN = 270 RIGHT = 0 LEFT = 180 screen.listen() screen.onkey(lambda: snake.turn(UP), 'Up') screen.onkey(lambda: snake.turn(LEFT), 'Left') screen.onkey(lambda: snake.turn(RIGHT), 'Right') screen.onkey(lambda: snake.turn(DOWN), 'Down') game_on = True def food_collision(): if snake.snake_head.distance(food) < 20: food.change_pos() snake.extend() scoreboard.increase_score() def tail_collision(): # 声明使用全局变量game_on global game_on for segment in snake.segments[1:]: if snake.snake_head.distance(segment) < 10: game_on = False scoreboard.game_over() while game_on: screen.update() time.sleep(0.1) food_collision() # 墙体碰撞检测 if snake.snake_head.xcor() > 280 or snake.snake_head.xcor() < -280 or snake.snake_head.ycor() > 280 or snake.snake_head.ycor() < -280: game_on = False scoreboard.game_over() tail_collision() snake.move() screen.exitonclick()
额外优化建议
snake.py中screen = Screen()属于冗余创建,main.py已经创建了Screen对象,会导致不必要的资源占用,建议删除这行代码。
内容的提问来源于stack exchange,提问作者Hamzacreator
相关产品推荐
相关产品推荐

