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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 01:53:18