楼主: CDA网校
54 0

[每天一个数据分析师] 用Python实现贪吃蛇游戏——从零开始构建贪吃蛇游戏的简易分步指南 [推广有奖]

管理员

已卖:189份资源

泰斗

5%

还不是VIP/贵宾

-

威望
3
论坛币
126247 个
通用积分
12322.9950
学术水平
278 点
热心指数
286 点
信用等级
253 点
经验
231678 点
帖子
7090
精华
19
在线时间
4409 小时
注册时间
2019-9-13
最后登录
2026-2-25

初级热心勋章

楼主
CDA网校 学生认证  发表于 6 小时前 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

我对母亲第一部手机的记忆,总绕不开里面的那款游戏——没错,就是经典的贪吃蛇游戏。它玩法简单,却让人欲罢不能。我还记得在母亲的手机上一遍遍地玩,输了就重新开始,乐此不疲!

在本文中,我们将学习构建一个简易的贪吃蛇游戏,核心会用到Python的turtle模块。请注意:这是一份面向Python初阶到中阶学习者的教程,要求读者熟悉Python基础(如函数、循环、模块导入、条件语句),并对面向对象编程有基础认知(尤其是从类创建对象实例)。为了便于理解,我会逐行解释每一段代码。现在,让我们开始吧!

图片来源:Unsplash 上的 Alfonso Castro
图片来源:Unsplash 上的 Alfonso Castro

游戏核心逻辑解析

经典的贪吃蛇游戏规则很简单:

  • 背景简洁,屏幕上随机出现食物

  • 蛇吃到食物后身体变长,分数增加

  • 蛇撞到边界墙或自身时,游戏结束

要在Python中实现这款游戏,我们需要解决以下核心问题:

  1. 搭建游戏窗口(经典贪吃蛇的背景是暗黄绿色)

  2. 创建蛇的身体(初始为小黑蛇,吃食物后逐渐变长)

  3. 控制蛇的移动(通过方向键实现上下左右移动)

  4. 生成食物(在屏幕随机位置出现)

  5. 检测蛇吃食物(吃到后加分、变长,同时生成新食物)

  6. 检测碰撞(撞墙或撞到自身则游戏结束)

接下来我们逐步编码实现。

第一步:搭建游戏窗口

首先在IDE中新建项目(命名为“Snake Game”),创建“snake game.py”文件。第一步先导入turtle模块的核心类:


from turtle import Screen, Turtle

Turtle模块说明

Turtle是Python内置模块,能通过代码在屏幕上绘制图形、线条、图案并实现动画。它的核心逻辑就像“一只背着画笔的乌龟”:你指挥它移动,它就会在路径上留下轨迹。可以控制乌龟前进、左转指定角度、画圆等,是可视化代码逻辑的绝佳工具,能直观练习变量、循环、函数、坐标和基础动画。

可参考Turtle官方文档了解更多用法。

我们通过Screen类创建游戏窗口,并自定义样式:


# 搭建游戏窗口
screen = Screen()
screen.setup(width=600, height=600)  # 设置窗口尺寸600×600
screen.bgcolor("green yellow")       # 设置背景色(接近经典游戏的黄绿色)
screen.title("Snake Game")          # 设置窗口标题
screen.tracer(0)                    # 关闭动画追踪(后续手动更新画面)

screen.exiton click()                # 点击窗口才关闭(否则会瞬间闪退)

代码说明

  • setup():设置窗口宽高

  • bgcolor():设置背景色(颜色名称可参考配色表

  • tracer(0):关闭自动动画刷新,后续通过update()手动控制,避免蛇身体分段创建的动画

  • exiton click():保证窗口不会执行完代码就立即关闭

运行上述代码,会得到一个600×600的黄绿色窗口。

第二步:创建蛇的身体

蛇的身体由多个正方形片段组成,我们用Turtle创建3个正方形片段,拼接成初始蛇身:


# 创建蛇的身体
segments = []  # 存储蛇的所有身体片段
starting_positions = [(0,0), (-20,0), (-40,0)]  # 初始三段身体的坐标

# 定义添加蛇身片段的函数(后续吃食物时复用)
def add_segments(position):
    new_segment = Turtle("square")  # 创建正方形海龟对象
    new_segment.color("black")      # 设置颜色为黑色
    new_segment.penup()             # 抬笔(避免移动时留下轨迹)
    new_segment.goto(position)      # 移动到指定坐标
    segments.append(new_segment)    # 将片段加入列表

# 初始化蛇身
for position in starting_positions:
    add_segments(position)

screen.update()  # 手动更新画面,显示蛇身

代码说明

  • 初始蛇身由3个20×20像素的正方形组成(Turtle默认尺寸)

  • penup():抬笔状态下移动不会绘制线条

  • 封装add_segments()函数:后续蛇吃食物时,可直接调用该函数添加新片段

若想直观看到分段创建的动画,可导入time模块并在循环中添加time.sleep(1),同时注释掉screen.tracer(0)

第三步:实现蛇的移动

让蛇动起来的核心逻辑:除头部外,每个片段都移动到前一个片段的位置,最后头部向前移动


import time  # 导入时间模块控制移动速度

game_is_on = True  # 游戏运行状态标识
while game_is_on:
    screen.update()  # 每次循环刷新画面
    time.sleep(0.1)  # 控制移动速度(0.1秒延迟,值越大速度越慢)
    
    # 让身体片段跟随前一个片段移动
    for seg_num in range(len(segments)-10-1):
        # 获取前一个片段的坐标
        new_x = segments[seg_num - 1].xcor()
        new_y = segments[seg_num - 1].ycor()
        # 当前片段移动到前一个片段的位置
        segments[seg_num].goto(new_x, new_y)
    
    # 蛇头向前移动20像素(一个片段的宽度)
    segments[0].forward(20)

核心逻辑解析

  • 倒序遍历蛇身片段(从最后一段到第一段):确保每个片段都跟随前一段移动

  • xcor()/ycor():获取海龟对象的x/y坐标

  • forward(20):蛇头向前移动20像素(与片段尺寸一致)

  • time.sleep(0.1):控制移动帧率,可调整数值改变蛇的速度

运行代码,就能看到蛇持续向前移动。

第四步:控制蛇的方向

通过键盘方向键控制蛇的移动方向,同时限制蛇不能180度反向(比如向左走时不能直接向右):


# 控制蛇的移动方向
screen.listen()  # 监听键盘输入

def turn_up():
    # 向上时不能直接向下(heading=270是向下)
    if segments[0].heading() != 270:
        segments[0].setheading(90)  # 90度=向上

def turn_down():
    # 向下时不能直接向上
    if segments[0].heading() != 90:
        segments[0].setheading(270# 270度=向下

def turn_left():
    # 向左时不能直接向右
    if segments[0].heading() != 0:
        segments[0].setheading(180# 180度=向左

def turn_right():
    # 向右时不能直接向左
    if segments[0].heading() != 180:
        segments[0].setheading(0)   # 0度=向右

# 绑定方向键与对应函数
screen.onkey(turn_up, "Up")
screen.onkey(turn_down, "Down")
screen.onkey(turn_left, "Left")
screen.onkey(turn_right, "Right")

代码说明

  • screen.listen():开启键盘监听

  • setheading(角度):设置海龟朝向(0=右,90=上,180=左,270=下)

  • onkey(函数名, 按键名):绑定按键与响应函数

  • 条件判断:避免蛇直接反向移动(符合经典游戏规则)

将这段代码放在游戏循环前,运行后即可通过方向键控制蛇的移动。

第五步:生成食物

创建随机位置的红色圆形食物,尺寸为10×10像素(默认20×20的一半):


# 创建食物
import random

food = Turtle()
food.color("red")               # 食物颜色为红色
food.shape("circle")            # 食物形状为圆形
food.penup()                    # 抬笔避免轨迹
food.shapesize(stretch_len=0.5, stretch_wid=0.5)  # 缩小为10×10像素
food.speed("fastest")           # 最快速度移动(无动画延迟)

# 随机生成食物坐标(限制在-275到275之间,避免靠近边界)
def refresh():
    random_x = random.randint(-275275)
    random_y = random.randint(-275275)
    food.goto(random_x, random_y)

# 初始化食物位置
refresh()

代码说明

  • shapesize(stretch_len=0.5, stretch_wid=0.5):将默认20×20的图形缩小50%

  • refresh()函数:重新生成随机坐标,蛇吃到食物后调用该函数刷新食物位置

  • 坐标范围限制在-275~275:避免食物出现在边界,导致蛇撞墙才能吃到

第六步:检测蛇吃食物

当蛇头与食物的距离小于15像素时,判定为“吃到食物”,此时:

  1. 刷新食物位置

  2. 蛇身增加一段

  3. 分数加1


# 蛇身延长函数
def extend():
    # 在最后一个片段的位置添加新片段
    add_segments(segments[-1].position())

# 游戏主循环(整合之前的移动逻辑)
game_is_on = True
while game_is_on:
    screen.update()
    time.sleep(0.1)
    
    # 蛇身跟随移动
    for seg_num in range(len(segments)-10-1):
        new_x = segments[seg_num - 1].xcor()
        new_y = segments[seg_num - 1].ycor()
        segments[seg_num].goto(new_x, new_y)
    segments[0].forward(20)
    
    # 检测吃到食物
    if segments[0].distance(food) < 15:
        refresh()  # 刷新食物位置
        extend()   # 蛇身延长

代码说明

  • distance(food):计算蛇头与食物的直线距离

  • extend():调用之前的add_segments()函数,在蛇尾添加新片段

  • 判定阈值15:通过测试确定的合理值(避免因坐标精度导致无法判定)

第七步:实现计分板

创建计分板,蛇吃到食物后更新分数:


# 初始化计分板
score = 0

# 绘制"Score = "文本
scoreboard = Turtle()
scoreboard.color("black")
scoreboard.penup()
scoreboard.hideturtle()  # 隐藏海龟图标,只显示文字
scoreboard.goto(0250)  # 文本位置(屏幕上方)
scoreboard.write("Score = ", align="center", font=("Arial"12"normal"))

# 绘制分数数字
my_score = Turtle()
my_score.color("black")
my_score.penup()
my_score.hideturtle()
my_score.goto(40250)
my_score.write(score, align="center", font=("Arial"12"normal"))

# 更新游戏循环中的吃食物逻辑
game_is_on = True
while game_is_on:
    # (保留之前的移动、跟随逻辑)
    
    # 检测吃到食物
    if segments[0].distance(food) < 15:
        refresh()
        extend()
        score += 1  # 分数加1
        my_score.clear()  # 清空原有分数
        my_score.write(score, align="center", font=("Arial"12"normal"))  # 写入新分数

第八步:游戏结束逻辑

1. 定义游戏结束提示函数


# 游戏结束提示
def game_over():
    game_over_text = Turtle()
    game_over_text.color("black")
    game_over_text.penup()
    game_over_text.hideturtle()
    game_over_text.write("GAME OVER", align="center", font=("Arial"40"normal"))

2. 检测撞墙

当蛇头超出窗口边界(x/y坐标超过±290)时,游戏结束:


game_is_on = True
while game_is_on:
    # (保留之前的所有逻辑)
    
    # 检测撞墙
    if (segments[0].xcor() > 290 or segments[0].xcor() < -290 or
        segments[0].ycor() > 290 or segments[0].ycor() < -290):
        game_is_on = False
        game_over()

3. 检测撞到自身

蛇头与身体任意片段的距离小于10像素时,判定为“撞到自身”,游戏结束:


game_is_on = True
while game_is_on:
    # (保留之前的所有逻辑)
    
    # 检测撞到自身
    for segment in segments[1:]:  # 遍历除头部外的所有片段
        if segments[0].distance(segment) < 10:
            game_is_on = False
            game_over()

完整代码整合

将所有逻辑整合,最终完整代码如下:


from turtle import Screen, Turtle
import time
import random

# 1. 搭建游戏窗口
screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("green yellow")
screen.title("Snake Game")
screen.tracer(0)

# 2. 蛇身相关函数
segments = []
starting_positions = [(0,0), (-20,0), (-40,0)]

def add_segments(position):
    new_segment = Turtle("square")
    new_segment.color("black")
    new_segment.penup()
    new_segment.goto(position)
    segments.append(new_segment)

# 初始化蛇身
for position in starting_positions:
    add_segments(position)

# 蛇身延长
def extend():
    add_segments(segments[-1].position())

# 3. 控制蛇的方向
def turn_up():
    if segments[0].heading() != 270:
        segments[0].setheading(90)

def turn_down():
    if segments[0].heading() != 90:
        segments[0].setheading(270)

def turn_left():
    if segments[0].heading() != 0:
        segments[0].setheading(180)

def turn_right():
    if segments[0].heading() != 180:
        segments[0].setheading(0)

screen.listen()
screen.onkey(turn_up, "Up")
screen.onkey(turn_down, "Down")
screen.onkey(turn_left, "Left")
screen.onkey(turn_right, "Right")

# 4. 创建食物
food = Turtle()
food.color("red")
food.shape("circle")
food.penup()
food.shapesize(stretch_len=0.5, stretch_wid=0.5)
food.speed("fastest")

def refresh():
    random_x = random.randint(-275275)
    random_y = random.randint(-275275)
    food.goto(random_x, random_y)

refresh()

# 5. 计分板
score = 0
scoreboard = Turtle()
scoreboard.color("black")
scoreboard.penup()
scoreboard.hideturtle()
scoreboard.goto(0250)
scoreboard.write("Score = ", align="center", font=("Arial"12"normal"))

my_score = Turtle()
my_score.color("black")
my_score.penup()
my_score.hideturtle()
my_score.goto(40250)
my_score.write(score, align="center", font=("Arial"12"normal"))

# 6. 游戏结束提示
def game_over():
    game_over_text = Turtle()
    game_over_text.color("black")
    game_over_text.penup()
    game_over_text.hideturtle()
    game_over_text.write("GAME OVER", align="center", font=("Arial"40"normal"))

# 7. 游戏主循环
game_is_on = True
while game_is_on:
    screen.update()
    time.sleep(0.1)
    
    # 蛇身跟随移动
    for seg_num in range(len(segments)-10-1):
        new_x = segments[seg_num - 1].xcor()
        new_y = segments[seg_num - 1].ycor()
        segments[seg_num].goto(new_x, new_y)
    segments[0].forward(20)
    
    # 检测吃到食物
    if segments[0].distance(food) < 15:
        refresh()
        extend()
        score += 1
        my_score.clear()
        my_score.write(score, align="center", font=("Arial"12"normal"))
    
    # 检测撞墙
    if (segments[0].xcor() > 290 or segments[0].xcor() < -290 or
        segments[0].ycor() > 290 or segments[0].ycor() < -290):
        game_is_on = False
        game_over()
    
    # 检测撞到自身
    for segment in segments[1:]:
        if segments[0].distance(segment) < 10:
            game_is_on = False
            game_over()

screen.exiton click()

总结

本教程中,我们成功用Python实现了经典的贪吃蛇游戏,核心用到了:

  • Python基础:函数定义与调用、列表/元组、循环、条件语句

  • 面向对象:从Turtle模块的类创建对象并调用方法

  • 动画控制:通过tracer和update实现流畅的游戏画面

你可以基于此代码进一步优化,比如增加难度(蛇移动速度随分数提升)、添加音效、记录最高分等。如果对代码有任何疑问,或有优化建议,欢迎留言分享!现在,运行代码,玩玩自己制作的贪吃蛇游戏,挑战你的朋友吧!

关键点回顾

  1. Turtle核心用法:通过Screen控制窗口,Turtle创建图形/文字,tracer关闭自动动画后用update手动刷新

  2. 蛇移动逻辑:倒序遍历身体片段,让每个片段跟随前一个移动,最后移动头部

  3. 碰撞检测:通过distance()计算距离,判定吃食物/撞自身,通过坐标范围判定撞墙

  4. 扩展性:可通过调整time.sleep()的参数改变蛇速,或增加新功能(如最高分记录、关卡难度)

推荐学习书籍 《CDA一级教材》适合CDA一级考生备考,也适合业务及数据分析岗位的从业者提升自我。完整电子版已上线CDA网校,累计已有10万+在读~ !

免费加入阅读:https://edu.cda.cn/goods/show/3151?targetId=5147&preview=0

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:python 从零开始 贪吃蛇 positions position

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-2-25 23:09