Python pygame实战:从零手写贪吃蛇小游戏,覆盖游戏开发核心逻辑
发布时间:2026/10/2 8:23:23来源:尧图网络
这次我们来看一个几乎每个 Python 学习者都会遇到的经典练手项目用 Python 代码制作一个贪吃蛇小游戏。它不需要 GPU不需要复杂的训练环境更不需要联网调用任何接口本地装一个 Python 环境、再装一个 pygame 库就能跑起来。对于想验证 Python 语法、了解游戏循环、练习类和函数拆分的读者来说这个项目性价比非常高。贪吃蛇小游戏的源码核心并不大一个文件就能写完但它覆盖了 Python 游戏开发里最基础也最关键的几个能力窗口创建、事件监听、坐标计算、碰撞检测、食物生成和游戏主循环。这篇文章会把源码拆开讲清楚并给出可以直接复制运行的完整代码、安装命令、测试步骤以及常见问题的排查方案。如果你正在做课程设计、Python 入门练习或者想给小朋友做一个本地小游戏这个项目可以直接作为起点。1. 核心能力速览能力项说明项目类型2D 小游戏 / Python 入门练手项目开发语言Python 3主要依赖pygame硬件要求普通电脑即可不需要独立显卡支持平台Windows / macOS / Linux启动方式python main.py交互方式键盘方向键控制核心功能蛇身移动、食物生成、碰撞检测、得分统计、自动演示扩展是否支持 API代码本身不提供网络 API但可以将游戏步骤封装成测试入口是否支持批量任务自动演示模式下可做多轮仿真测试适合人群Python 初学者、课程设计、游戏开发入门从能力速览就能看出这个项目的重点不是性能而是“用最少的代码把游戏跑通”。它也特别适合作为第一个 pygame 项目来练手。2. 适用场景与学习路径贪吃蛇小游戏适合下面几类人。第一类是 Python 刚入门不久、想把基础语法落地成实际作品的读者。只学列表、字典、函数和循环很多人的感觉是“语法都认识但不知道能干什么”。贪吃蛇这个项目刚好把列表操作、随机数、条件分支、类与方法、事件循环串在一起代码量又不大是一条很顺畅的学习路径。第二类是需要课程设计或毕业设计题目的学生。贪吃蛇本身是小游戏但可以在它的基础上扩展出很多功能比如计分系统、关卡难度、排行榜、音效、AI 自动寻路。每个扩展都对应一个明确的技术点写进课程设计报告里也容易讲清楚。第三类是想给小朋友做本地小游戏、或者想了解 pygame 基础用法的开发者。它的启动方式简单不需要联网也不会读取额外数据适合作为本机娱乐或教学演示。这个项目不适用的场景也很明确如果你目标是做一个复杂的商业游戏或者高性能实时应用pygame 并不是主力选择。贪吃蛇更适合作为教学和原型验证工具。这里也要提醒一句使用边界开发小游戏、分享源码都属于正常的技术学习但如果引用了他人的代码、素材或开源库发布时要注明来源并遵守对应的开源许可证。不要直接把别人的源码改个名字就当原创发布。涉及游戏素材、音频、图像时也要确认是否有版权授权。3. 环境准备与安装3.1 安装 Python首先确认电脑上已经安装了 Python 3。Windows 用户建议从 Python 官网下载安装包安装时勾选“Add Python to PATH”。macOS 用户如果没有 Python 3可以通过 Homebrew 安装。Linux 用户一般已经自带 Python 3可以用python3命令检查。检查 Python 版本python --version如果提示找不到命令Windows 下可以尝试py --versionLinux / macOS 下可以尝试python3 --version3.2 安装 pygame贪吃蛇小游戏使用的图形库是 pygame。执行下面的命令安装pip install pygame如果电脑上同时存在 Python 2 和 Python 3可能需要使用 pip3pip3 install pygame安装完成后可以用一行命令验证 pygame 是否可以正常导入python -c import pygame; print(pygame.version.ver)如果输出类似2.5.2这样的版本号说明 pygame 已经安装成功。3.3 环境检查清单检查项命令预期结果Python 版本python --version输出 Python 3.xpip 可用pip --version输出版本号无报错pygame 安装pip show pygame显示包信息pygame 导入python -c import pygame无报错输出如果你的网络环境导致 pip 安装缓慢可以考虑配置国内镜像源执行安装命令时加上镜像参数即可。不过这一步不是必须的能装上官方的包就行。4. 整体设计与源码实现4.1 设计思路贪吃蛇小游戏的逻辑并不复杂但要把代码写得清晰建议先用面向对象的方式拆分职责。Snake类负责蛇身坐标、当前方向、移动和碰撞检测。spawn_food函数负责随机生成食物并保证食物不会生成在蛇身上。draw函数负责绘制窗口内容。main函数负责初始化窗口、处理键盘事件、组织主循环。蛇身用坐标元组的列表表示列表最后一个元素代表蛇头。每次移动时在列表末尾追加新蛇头坐标如果没有吃到食物就把列表头部元素弹出。这样蛇看起来就是向前移动一格长度保持不变。吃到食物时不弹出尾部元素蛇身长度就增加一格。这种数据结构实现起来非常直观也方便后面做碰撞检测。判断撞墙只需检查蛇头坐标是否超出窗口范围判断撞自己只需检查蛇头坐标是否已经在蛇身列表中。4.2 贪吃蛇小游戏完整源码import pygame import random import sys # 窗口和格子参数 SCREEN_WIDTH 600 SCREEN_HEIGHT 600 CELL_SIZE 20 FPS 10 # 颜色 BLACK (0, 0, 0) RED (255, 0, 0) GREEN (0, 255, 0) class Snake: 贪吃蛇类负责蛇身、方向、移动和碰撞检测 def __init__(self): # 初始蛇身三个格子方向向右 self.body [ (SCREEN_WIDTH // 2 - CELL_SIZE * 2, SCREEN_HEIGHT // 2), (SCREEN_WIDTH // 2 - CELL_SIZE, SCREEN_HEIGHT // 2), (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2) ] self.direction RIGHT self.grow_flag False def move(self): 将蛇前移一格 head_x, head_y self.body[-1] if self.direction UP: new_head (head_x, head_y - CELL_SIZE) elif self.direction DOWN: new_head (head_x, head_y CELL_SIZE) elif self.direction LEFT: new_head (head_x - CELL_SIZE, head_y) else: new_head (head_x CELL_SIZE, head_y) self.body.append(new_head) if not self.grow_flag: self.body.pop(0) else: self.grow_flag False def change_direction(self, new_dir): 改变方向并禁止直接反向 reverse { UP: DOWN, DOWN: UP, LEFT: RIGHT, RIGHT: LEFT } if new_dir ! reverse.get(self.direction): self.direction new_dir def check_collision(self): 返回是否撞墙或撞自己 head_x, head_y self.body[-1] # 撞墙 if head_x 0 or head_x SCREEN_WIDTH: return True if head_y 0 or head_y SCREEN_HEIGHT: return True # 撞自己 for segment in self.body[:-1]: if segment self.body[-1]: return True return False def spawn_food(snake_body): 随机生成一个不落在蛇身上的食物坐标 while True: x random.randrange(0, SCREEN_WIDTH, CELL_SIZE) y random.randrange(0, SCREEN_HEIGHT, CELL_SIZE) if (x, y) not in snake_body: return (x, y) def draw(screen, snake, food): 绘制蛇与食物 screen.fill(BLACK) for segment in snake.body: pygame.draw.rect( screen, GREEN, (segment[0], segment[1], CELL_SIZE, CELL_SIZE) ) pygame.draw.rect( screen, RED, (food[0], food[1], CELL_SIZE, CELL_SIZE) ) pygame.display.flip() def main(): pygame.init() screen pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption(贪吃蛇小游戏) clock pygame.time.Clock() snake Snake() food spawn_food(snake.body) score 0 running True while running: # 控制游戏帧率FPS 越大速度越快 clock.tick(FPS) # 处理事件 for event in pygame.event.get(): if event.type pygame.QUIT: running False elif event.type pygame.KEYDOWN: if event.key pygame.K_UP: snake.change_direction(UP) elif event.key pygame.K_DOWN: snake.change_direction(DOWN) elif event.key pygame.K_LEFT: snake.change_direction(LEFT) elif event.key pygame.K_RIGHT: snake.change_direction(RIGHT) elif event.key pygame.K_ESCAPE: running False # 移动蛇 snake.move() # 判断是否吃到食物 if snake.body[-1] food: snake.grow_flag True score 1 print(fScore: {score}) food spawn_food(snake.body) # 碰撞检测 if snake.check_collision(): print(fGame Over, Score: {score}) running False # 绘制 draw(screen, snake, food) pygame.quit() sys.exit() if __name__ __main__: main()4.3 关键代码讲解Snake类的设计是这个代码的核心。蛇身使用列表保存列表最后一个是蛇头这样每次移动只需要在末尾追加新坐标然后根据是否吃到食物决定是否弹出首元素。计算效率很高代码也很好懂。change_direction方法里有一个反向字典用来防止蛇直接掉头。如果不加这个限制玩家在快速连续按键时可能会出现“蛇头反向穿进身体”的情况碰撞检测结果会很奇怪。check_collision把撞墙和撞自身分成两个判断。撞墙的判断直接比较蛇头坐标是否超出窗口边界。撞自身的判断注意排除蛇头本身否则蛇每次移动都会判定为与自身重叠。spawn_food使用while True循环随机生成坐标直到生成的位置不在蛇身上。这个函数在游戏早期很稳定但是当蛇几乎占满整个地图时随机查找可能耗时变长。这是一个可以留给读者优化的扩展点可以统计空白格子再从中随机选择。5. 功能测试与效果验证5.1 启动游戏在保存了main.py的目录下打开终端执行python main.py启动后应该能看到一个黑色窗口窗口中央有一条绿色蛇和一个红色食物。蛇会持续向右移动按方向键可以改变移动方向。5.2 测试用例表格测试项操作预期结果窗口创建执行python main.py弹出黑色窗口显示蛇与食物蛇移动不按键蛇自动向右移动方向控制按上下左右键蛇朝对应方向转弯禁止掉头蛇向右时按左键方向不变吃到食物操纵蛇头接触红色方块蛇身变长控制台打印得分撞墙结束让蛇头移动出边界控制台打印 Game Over窗口关闭撞自己结束绕圈让蛇头碰到自己控制台打印 Game Over窗口关闭退出游戏按 Esc 或关闭窗口程序退出5.3 判断成功的标准最基本的标准是窗口能打开蛇能移动方向键能转弯吃到食物能变长撞墙能结束。这里的每一项在 main.py 里都有对应代码如果都能正常工作说明你的 Python 环境和 pygame 安装没有问题游戏逻辑也是通的。如果你想把得分显示在游戏窗口里而不是控制台可以用 pygame 的字体模块font pygame.font.SysFont(arial, 36) score_text font.render(fScore: {score}, True, (255, 255, 255)) screen.blit(score_text, (10, 10))这段代码放在draw函数里每帧绘制得分。需要注意中文字体在不同系统上的可用性不同如果显示乱码可以尝试把字体名换成simhei或直接使用英文字体。6. 功能扩展与自动化测试入口6.1 使用 JSON 配置文件贪吃蛇小游戏的窗口大小、格子大小和速度如果直接写死在代码里每次调整都要改源码。更工程化的做法是把配置抽离到一个 JSON 文件里。{ screen_width: 600, screen_height: 600, cell_size: 20, fps: 10, game_title: 贪吃蛇小游戏 }然后在 main.py 中读取import json with open(config.json, r, encodingutf-8) as f: config json.load(f) SCREEN_WIDTH config[screen_width] SCREEN_HEIGHT config[screen_height] CELL_SIZE config[cell_size] FPS config[fps]6.2 封装自动化测试入口如果想快速验证蛇的逻辑而不用每次手动按键可以把单帧移动封装成一个函数def step_game(snake, food, actionNone): 单步推进游戏逻辑action 为方向键对应的字符串 if action in (UP, DOWN, LEFT, RIGHT): snake.change_direction(action) snake.move() if snake.body[-1] food: snake.grow_flag True food spawn_food(snake.body) return snake, food有了这个step_game函数你可以写一个简单的自动化脚本模拟蛇不吃食物一直向右移动然后观察多久撞墙snake Snake() food spawn_food(snake.body) steps 0 while not snake.check_collision(): snake, food step_game(snake, food, RIGHT) steps 1 if steps 1000: break print(f自动演示结束共移动 {steps} 步)这种可验证的游戏逻辑入口也是后续把贪吃蛇接入其他程序的基础。虽然这个项目没有网络 API但通过函数封装你可以把“下一步会怎样”交给外部代码去判断。7. 资源占用与性能观察7.1 pygame 游戏循环的占用特点pygame 游戏是一个典型的实时循环程序。主循环的执行速度由clock.tick(FPS)控制FPS值越大每帧间隔越短CPU 占用相应升高。贪吃蛇本身的逻辑非常简单普通电脑上运行时 CPU 占用都很低不会出现明显的性能压力。内存占用主要来自 pygame 窗口缓冲区和 Python 对象本身数值不大。7.2 观察运行性能想知道游戏实际跑在多少帧可以在主循环里增加帧率打印current_fps clock.get_fps() if current_fps 0: print(fCurrent FPS: {current_fps:.1f})这样每帧都会输出当前帧率。如果屏幕刷新率低于预期优先检查FPS设置是不是太高。通常贪吃蛇游戏用FPS 10到FPS 15就已经很快了设置成 60 反而会让蛇快得看不清。7.3 如何降低资源占用把窗口调小、降低 FPS 都能减少资源占用。另外draw函数中每次绘制都执行pygame.display.flip()如果改成局部区域更新pygame.display.update(rect_list)可以略微减少刷新开销。在简单小游戏里这种优化效果不明显但可以作为理解 pygame 绘制机制的一个切入点。8. 常见问题与排查方法问题现象可能原因排查方式解决方案提示 ModuleNotFoundError: No module named pygamepygame 未安装或安装到其他 Python 环境执行pip show pygame重新执行pip install pygame窗口一闪而过主循环内有异常或立即退出在终端运行观察错误信息根据报错定位代码检查缩进和变量名方向键控制无效事件判断写错或窗口焦点不在游戏窗口点击游戏窗口后再按键检查 event.key 分支蛇可以反向移动未做禁止掉头逻辑检查 change_direction 方法用反向字典拦截游戏速度太快FPS 设置过高打印当前 FPS调小 FPS 数值撞墙没有结束碰撞检测边界错误打印蛇头坐标检查边界比较是否用了食物生成后与蛇重叠食物坐标生成逻辑有问题打印食物坐标与蛇身坐标确认 spawn_food 中检查了 snake_body中文窗口标题乱码系统字体或编码问题查看终端输出改用英文标题或用 Unicode 字符串这里比较常见的坑是两个。第一个是安装 pygame 时在当前虚拟环境里但运行代码时用了系统 Python导致模块找不到。第二个是撞墙判断写成了而不是导致蛇头到边界时看起来已经超出窗口却还没结束。9. 最佳实践与代码规范9.1 用类拆分逻辑贪吃蛇小游戏的源码虽然只有一个文件但建议不要把所有逻辑都堆在main()函数里。把蛇的行为封装成Snake类把食物生成、绘制单独抽成函数代码可读性会明显提升也方便后续做单元测试。9.2 先小参数测试第一次运行代码时先不要把窗口设置成特别大的尺寸也不要把FPS设置得很高。建议先保持默认参数运行确认所有功能正常后再逐步调整格子大小、速度、颜色和分辨率。每改一个参数就运行一次避免一次改太多导致问题难以定位。9.3 文件目录管理如果你的项目不只是单文件建议按下面的目录结构组织snake_game/ ├── main.py ├── config.json ├── requirements.txt └── README.mdrequirements.txt可以这样写pygame这样其他人拿到项目后只需要执行pip install -r requirements.txt就能安装所有依赖。9.4 版本控制与源码分享小游戏项目同样建议从一开始就放进 Git 仓库每完成一个功能提交一次。发布源码到技术社区时写上运行环境、安装命令和测试方式能够提高源码的可用性。引用第三方代码或素材时必须标注来源和许可证这个习惯越早养成越好。10. 总结与下一步贪吃蛇小游戏值得上手不是因为它的代码量有多厉害而是因为它在极短的篇幅里覆盖了 Python 游戏开发的完整链路安装依赖、创建窗口、处理输入、维护游戏状态、进行碰撞检测、输出可视化结果。把这套代码跑通你等于掌握了 pygame 小游戏的基础骨架。最先应该验证的自然是游戏能不能启动、方向键控制是否正常、撞墙结束的逻辑是否生效。最容易踩的坑是 pygame 没装对 Python 环境以及方向判断逻辑写错。建议第一次运行就从原始源码开始确认无误后再加入配置文件、计分显示和自动演示。后面的扩展方向很明确把得分显示到窗口里加入难度递增添加音效把 FPS 和格子尺寸做成 GUI 可调节项或者用简单的策略让蛇自己吃食物。最终还可以用 PyInstaller 把游戏打包成 exe让没有 Python 环境的电脑也能直接运行。对 Python 小游戏开发这个方向来说这是一条很实用的起步路线。
网站建设高端定制企业官网