
这次我们来看一个能把 Python 兴趣值直接拉满的小游戏人狗大作战。不要被名字吓到它不是 3A 大作也不是什么复杂引擎项目而是一个用 Python 加 pygame 写出来的 2D 小游戏。这个项目最大的价值不是游戏画面有多好而是让你在学完 Python 基础语法之后有一个能真正跑起来、能互动、能改参数、能打包成 exe 的动手目标。如果你现在的状态是Python 教程看了不少print、for、if 都会写但不知道下一步做什么那人狗大作战就是一个非常合适的练手项目。它的核心玩法是控制一个角色移动躲避不断出现的狗同时用键盘发射面包进行“投喂”得分。整个代码量不大所有逻辑加在一起几百行一两个小时就能理解并改出你自己的版本。本文会带你走一遍完整流程先看核心能力和硬件门槛再讲游戏设计思路接着从 Python 安装、pygame 环境配置开始给出一份可运行的完整源码然后运行测试、观察资源占用、排查常见问题最后聊聊从这个小游戏继续往 Python 爬虫、数据分析、量化、打包 exe 方向扩展的路线。1. 核心能力速览能力项说明项目类型Python 2D 小游戏pygame 实现开发语言Python 3依赖库pygame运行平台Windows / macOS / Linux 均可启动方式命令行运行 Python 脚本操作方式方向键移动空格键发射面包硬件要求无独立显卡要求CPU 即可内存占用较低主要功能角色移动、随机敌人生成、碰撞检测、分数统计、难度递增、重新开始是否支持 API否但扩展时可封装为命令行或服务是否支持批量任务否但可通过脚本自动化压测稳定性是否支持打包支持使用 PyInstaller 打包为单文件 exe从表格里可以看到这个项目的硬件门槛几乎为零。普通办公电脑、轻薄本、没显卡的旧机器都能跑。它不需要 CUDA不需要模型文件不需要巨大的磁盘空间只需要 Python 环境和 pygame 库。2. 游戏玩法与项目设计人狗大作战的规则设计为“躲避 投喂”。玩家控制的蓝色方块代表人物红色椭圆代表狗黄色小方块代表面包。游戏开始后狗会从窗口上方随机位置出现以不同的速度向下移动。玩家需要移动角色避开狗同时按空格键向上方发射面包。面包碰到狗狗被“投喂成功”并从画面中消失同时获得额外分数。如果狗碰到人物游戏结束。这个规则有两个好处第一不涉及血腥暴力画面简单友好第二它足够覆盖 Python 初学阶段的核心知识点变量与数据类型玩家坐标、速度、分数、颜色等。列表与字典狗和面包都用列表存储每个对象用字典表示属性。循环与事件pygame 的主循环、事件处理循环。条件判断碰撞检测、边界限制、游戏结束判断。函数封装生成狗、发射面包、重置游戏、绘制画面。全局变量多个函数之间共享游戏状态。这种设计非常适合教学。你不会觉得语法枯燥因为每一个知识点都直接对应游戏里一个能看到的反馈按下方向键角色移动按下空格面包飞出狗碰到角色游戏结束分数随难度递增。从程序结构上看项目可以拆成三个部分模块职责初始化部分设置窗口、颜色、玩家默认位置、字体、时钟游戏逻辑部分玩家移动、狗生成、面包移动、碰撞检测、分数更新绘制与事件部分画面绘制、事件响应、游戏结束处理这种拆分方式也是真实项目里常用的思路数据、逻辑、表现各司其职。即使后面要在这个小游戏上添加新功能比如增加障碍物、加入音效、记录最高分也只需要在对应模块里改动不需要重写整个文件。3. 环境准备Python 安装与 pygame 配置在写代码之前先确认本机的 Python 环境。人狗大作战要求 Python 3推荐使用 3.8 及以上版本。如果电脑上还没有 Python可以按下面的步骤安装。3.1 安装 Python打开 Python 官网下载对应操作系统的安装包。Windows 用户在安装时要注意勾选“Add Python to PATH”这一步经常被忽略会导致后续在命令行里无法直接使用 python 命令。安装完成后打开命令行窗口输入以下命令验证python --version pip --version如果能看到 Python 版本号和 pip 版本号说明环境正常。如果提示“python 不是内部或外部命令”通常是 PATH 没有配置好重新执行安装程序勾选“Add Python to PATH”后修复安装即可。3.2 安装 pygamepygame 是 Python 写 2D 小游戏最常用的库安装非常简单pip install pygame国内网络环境下如果 pip 下载速度慢可以临时切换到国内镜像源pip install pygame -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后可以运行一行命令验证 pygame 是否安装成功python -m pygame.examples.aliens如果弹出 pygame 自带的太空射击小游戏窗口说明 pygame 安装完全正常。关闭窗口后就可以开始写我们自己的游戏了。3.3 准备项目目录建议新建一个独立的项目文件夹例如dog_game把所有代码和后续可能用到的素材放在里面。这样结构清晰也方便以后用 PyInstaller 打包。目录结构建议dog_game/ └── 人狗大作战.py游戏里没有使用外部图片和音频全部用 pygame 的绘图函数完成因此暂时不需要额外的素材目录。这样做有一个好处代码复制到任何一台安装了 Python 和 pygame 的电脑上都能直接运行不会因为图片路径问题报错。4. 完整代码实现下面给出完整的项目代码。建议不要直接复制粘贴完就结束而是边读注释边理解每一段的作用。这样以后改参数、加功能的时候才不会迷路。# -*- coding: utf-8 -*- 人狗大作战 - Python pygame 小游戏 简化版控制人物移动使用空格键投喂面包躲避狗的接近。 import pygame import random import sys # 初始化 pygame pygame.init() # 窗口参数 WIDTH, HEIGHT 800, 600 screen pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption(人狗大作战 - Python 小游戏) # 颜色定义 WHITE (255, 255, 255) BLACK (0, 0, 0) RED (220, 60, 60) BLUE (60, 120, 220) YELLOW (240, 200, 40) # 玩家参数 player_size 30 player_x WIDTH // 2 player_y HEIGHT - 80 player_speed 5 # 狗列表列表中的每个元素是一个 dict dogs [] dog_size 26 dog_spawn_interval 60 # 初始生成间隔帧 dog_spawn_timer 0 # 面包列表 breads [] bread_size 12 bread_speed 8 # 分数与字体 score 0 font pygame.font.SysFont(SimHei, 28) # 游戏控制 FPS 60 clock pygame.time.Clock() game_over False running True def spawn_dog(): 在窗口上方随机生成一只狗 x random.randint(0, WIDTH - dog_size) y random.randint(-120, -dog_size) speed random.randint(2, 5) dogs.append({x: x, y: y, speed: speed}) def throw_bread(): 从人物当前位置抛出一个面包 breads.append({ x: player_x player_size // 2 - bread_size // 2, y: player_y }) def reset_game(): 重置游戏状态 global player_x, player_y, score, dog_spawn_timer, game_over dogs.clear() breads.clear() player_x WIDTH // 2 player_y HEIGHT - 80 score 0 dog_spawn_timer 0 game_over False def draw_game(): 绘制游戏画面 screen.fill(WHITE) if game_over: over_text font.render(游戏结束按 R 重新开始按 Q 退出, True, RED) score_text font.render(最终得分{}.format(score), True, BLACK) screen.blit(over_text, (WIDTH // 2 - 190, HEIGHT // 2 - 30)) screen.blit(score_text, (WIDTH // 2 - 90, HEIGHT // 2 20)) pygame.display.flip() return # 绘制玩家 pygame.draw.rect(screen, BLUE, (player_x, player_y, player_size, player_size)) # 绘制狗 for dog in dogs: dog_rect pygame.Rect(dog[x], dog[y], dog_size, dog_size) pygame.draw.ellipse(screen, RED, dog_rect) # 绘制面包 for bread in breads: pygame.draw.rect( screen, YELLOW, (bread[x], bread[y], bread_size, bread_size) ) # 显示分数和操作提示 score_text font.render(得分{}.format(score), True, BLACK) tip_text font.render(方向键移动空格投喂面包, True, (120, 120, 120)) screen.blit(score_text, (10, 10)) screen.blit(tip_text, (10, 50)) pygame.display.flip() def update_game(): 更新游戏逻辑 global player_x, player_y, score, dog_spawn_timer, game_over, dog_spawn_interval # 玩家移动 keys pygame.key.get_pressed() if keys[pygame.K_LEFT] and player_x 0: player_x - player_speed if keys[pygame.K_RIGHT] and player_x WIDTH - player_size: player_x player_speed if keys[pygame.K_UP] and player_y 0: player_y - player_speed if keys[pygame.K_DOWN] and player_y HEIGHT - player_size: player_y player_speed # 生成狗难度随分数提高 dog_spawn_timer 1 if dog_spawn_timer dog_spawn_interval: spawn_dog() dog_spawn_timer 0 score 1 # 更新狗位置 for dog in dogs: dog[y] dog[speed] # 更新面包位置 for bread in breads: bread[y] - bread_speed # 玩家与狗碰撞检测 player_rect pygame.Rect(player_x, player_y, player_size, player_size) for dog in dogs: dog_rect pygame.Rect(dog[x], dog[y], dog_size, dog_size) if player_rect.colliderect(dog_rect): game_over True return # 面包与狗碰撞检测 for bread in breads[:]: bread_rect pygame.Rect(bread[x], bread[y], bread_size, bread_size) for dog in dogs[:]: dog_rect pygame.Rect(dog[x], dog[y], dog_size, dog_size) if bread_rect.colliderect(dog_rect): dogs.remove(dog) if bread in breads: breads.remove(bread) score 5 break # 清理出界对象 dogs[:] [dog for dog in dogs if dog[y] HEIGHT 80] breads[:] [bread for bread in breads if bread[y] -50] # 动态难度分数越高狗生成越快 dog_spawn_interval max(25, 60 - score // 10) def run_game(): 游戏主循环 global running, game_over while running: clock.tick(FPS) # 事件处理 for event in pygame.event.get(): if event.type pygame.QUIT: running False if event.type pygame.KEYDOWN: if not game_over and event.key pygame.K_SPACE: throw_bread() if game_over and event.key pygame.K_r: reset_game() if game_over and event.key pygame.K_q: running False if not game_over: update_game() draw_game() pygame.quit() sys.exit() if __name__ __main__: run_game()代码中几个比较关键的点pygame.Rect是 pygame 提供的矩形对象colliderect方法可以直接判断两个矩形是否碰撞比自己写坐标范围判断方便很多。dogs和breads都用列表保存每个元素是一个字典。这种“列表套字典”的方式在 Python 游戏开发里非常常见也是从基础语法过渡到实际项目的重要一步。dogs[:]的写法是在遍历列表副本这样可以在循环里安全地删除列表元素不会出现“list changed size during iteration”的报错。全局变量使用global声明后才能在函数内部修改它们的值。这部分是 Python 初学者比较容易卡住的地方。5. 运行与功能测试代码写完之后保存为人狗大作战.py在项目目录下打开命令行执行python 人狗大作战.py如果一切正常会弹出 800x600 的游戏窗口。刚启动时窗口上方会不断掉下红色椭圆。每掉下一只狗得分会增加 1 分。随着分数升高狗出现的间隔会越来越短需要不断移动角色躲避同时寻找机会按空格发射面包。建议按下面的测试清单走一遍确认每个功能都正常测试项操作预期结果窗口启动运行脚本弹出游戏窗口无报错角色移动按方向键蓝色方块按对应方向移动不会超出窗口边界投喂面包按空格键从蓝色方块位置向上飞出一个黄色小方块狗掉落等待数秒红色椭圆从窗口上方随机出现向下移动投喂命中让面包碰到狗狗消失得分增加 5 分游戏结束让狗碰到角色画面切换为结束提示显示最终得分重新开始游戏结束后按 R画面清空数据重置可以重新游戏退出程序游戏结束后按 Q 或关闭窗口程序正常结束命令行无残留其中最容易出问题的是游戏结束后的重开功能。如果按 R 没反应检查事件处理代码里是否在game_over状态下响应了pygame.K_r以及reset_game()是否把所有状态都恢复到位。如果想调整游戏难度可以修改这几个参数player_speed玩家移动速度数值越大越快。dog_spawn_interval初始狗的生成间隔数值越小越密集。dog_spawn_interval max(25, 60 - score // 10)难度递增速度score // 10的除数越小难度涨得越快。bread_speed面包飞行速度。改完参数后重新运行脚本不需要重新安装任何依赖。6. 扩展能力接口、打包与批量测试人狗大作战本身不涉及 API 服务也没有 Web 接口。但从这个项目出发可以尝试几个非常实用的扩展方向它们会让你写的 Python 代码具备更强的工程价值。6.1 打包成 exe如果你想把这个小游戏发给朋友玩或者想在没装 Python 的电脑上运行可以用 PyInstaller 打包成独立 exe。先安装 PyInstallerpip install pyinstaller然后执行打包命令pyinstaller -F -w 人狗大作战.py命令参数说明-F表示打包成单个 exe 文件。-w表示运行时不显示命令行窗口。打包完成后exe 文件在dist目录下。打包过程可能需要几十秒到几分钟。打包出来的文件体积通常在 10MB 到 30MB 左右具体取决于 Python 版本和 pygame 版本。第一次打包建议在项目目录下操作并确认脚本本身已经能正常运行避免把报错也打进 exe 里。6.2 用命令行参数控制难度如果想做自动化测试可以给游戏增加命令行参数让每次启动时指定不同的难度、窗口大小和运行局数。比如使用标准库argparse这是 Python 处理命令行参数的主流方式。下面是一个简化的思路import argparse parser argparse.ArgumentParser(description人狗大作战参数) parser.add_argument(--difficulty, typeint, default1, help难度等级 1-5) parser.add_argument(--rounds, typeint, default1, help自动运行局数) args parser.parse_args()有了这些参数就可以写一个批量测试脚本循环启动多局游戏记录每局得分判断游戏是否稳定。这一步虽然简单但能让你提前感受“写代码不只是写功能还要考虑测试和自动化”的工程习惯。6.3 接入 HTTP 接口的通用写法从 pygame 小游戏继续往前走下一阶段通常会接触到“Python 程序如何调用别人提供的接口”。这个能力在爬虫、数据分析、量化交易里都经常用到。下面是一个非常通用的 HTTP 请求模板任何有 requests 库的环境都能跑import requests url https://httpbin.org/post payload {game: 人狗大作战, score: 120} response requests.post(url, jsonpayload, timeout10) print(response.status_code) print(response.json())运行之前需要先安装 requestspip install requests这个示例只展示 Python 发起 HTTP 请求的基本流程。实际项目中接口地址、请求参数和鉴权方式各不相同需要按目标服务的文档调整。6.4 自动化批量压测游戏本身没有批量任务需求但如果你想验证游戏逻辑在长期运行下是否稳定可以写一个自动化脚本绕过 pygame 的图形界面直接调用update_game逻辑函数循环执行数千帧记录是否出现异常。这种思路在很多游戏项目里叫“无头测试”。实际操作时可以把游戏逻辑和绘制逻辑拆得更彻底甚至用 pytest 来管理测试用例这又是一个新的学习方向。7. 资源占用与性能观察pygame 游戏属于轻量级图形应用对硬件的要求很低。运行人狗大作战时可以打开系统的任务管理器观察 Python 进程的资源占用情况。重点看两个指标指标观察方法说明内存占用任务管理器中定位 python.exe 进程小游戏通常较低具体以本机为准CPU 占用任务管理器中的 CPU 列与窗口尺寸、对象数量、FPS 设置相关由于本项目没有使用外部图片和音频所有物体都是简单图形CPU 和内存压力很小。一般办公电脑跑起来非常流畅。如果你发现游戏窗口有些卡顿可以先从这几个方向排查窗口是否开得太大。WIDTH和HEIGHT越大pygame 每次全屏重绘的计算量越大。FPS 是否设置得太高。clock.tick(FPS)中的 FPS 调低到 30能显著降低刷新频率减少 CPU 消耗。场景中物体数量是否过多。如果狗的数量累积很多碰撞检测的循环次数会变多。目前代码里已经有出界清理逻辑会移除跑出窗口下边缘的狗正常情况下不会无限累积。显存方面pygame 默认使用 CPU 软件渲染不依赖独立显卡。这一点和现在主流的 AI 绘图、深度学习项目完全不同。写 pygames 小游戏不需要考虑 CUDA、显存占用、显卡驱动哪怕是一台很老的电脑也能跑。8. 常见问题与排查方法新手运行 pygame 项目时最容易遇到下面这些问题。这里整理成排查清单。问题现象可能原因排查方式解决方案运行提示 ModuleNotFoundError: No module named pygamepygame 未安装执行pip show pygamepip install pygame重新安装命令行里敲 python 没反应或提示未知命令Python 未加入 PATH执行python --version重装 Python 并勾选 Add Python to PATH游戏窗口一闪而过脚本运行到结尾直接退出检查代码末尾是否有pygame.quit()和sys.exit()确保事件循环正常不要用裸while True不处理退出中文文字显示成方块系统没有代码里指定的字体检查pygame.font.SysFont的字体名换成系统自带字体例如SimHei、Microsoft YaHei、Arial按键没有响应事件处理位置不对检查事件循环里是否处理了 KEYDOWN把按键响应代码放在事件循环内游戏很卡窗口太大或 FPS 过高观察任务管理器 CPU 占用降低 FPS缩小窗口控制物体数量按 R 无法重新开始重置函数没有清空所有状态检查 reset_game 里是否清空 dogs 和 breads手动把全局变量恢复初始值PyInstaller 打包后双击没反应打包命令缺少参数或脚本报错先在命令行下运行脚本确认无报错用pyinstaller -F -w重新打包查看 dist 目录日志pip 安装 pygame 很慢网络原因无明显现象使用国内镜像源安装如果你遇到的是其他问题先看命令行里有没有报错信息。Python 的报错信息通常会给出文件名和行号根据行号去代码里找问题是最快的排查方式。不要一上来就怀疑环境配错了。9. 从人狗大作战走向更大的 Python 世界人狗大作战只是一个起点。当你把这段代码完全跑通并且能自己改参数、加功能说明你已经具备了一定的 Python 代码阅读能力和排错能力。这个时候后面的路会宽很多。第一个方向是 Python 爬虫。小游戏里的requests、列表、字典、循环在爬虫项目里都是基础知识。爬取网页数据、解析 JSON、处理字段用的还是这些语法。区别只是从“游戏对象”变成了“网络数据”。第二个方向是 Python 数据分析与可视化。游戏代码里的字典和列表本质上就是一种简单的数据结构。数据分析里常用的 pandas 会把 Excel、CSV 数据读成表格对象处理和统计的方式与你在游戏里遍历 dogs 列表有相通之处。第三个方向是 Python 量化交易策略代码。量化交易最核心的部分是回测逻辑根据历史行情数据计算买卖信号判断盈亏。这个流程和游戏里“根据状态判断是否得分、是否结束”的思路很接近。当然真实量化系统要复杂得多涉及数据源、策略、风控、撮合模型等不建议在没有充分金融知识的情况下直接上真金白银。第四个方向是 Python 转 exe 文件。你已经学会了 PyInstaller 打包命令以后写任何 Python 工具都可以打包成 exe 分发给其他人使用对方不需要安装 Python 环境。第五个方向是 Python 自动化办公。小游戏里的“读取输入、处理数据、输出结果”模型放在办公场景里就是自动化处理 Excel、Word、网页操作。本质上都是写代码让机器代替手工操作。此外搜索“python 入门”“python 安装教程”“python 代码大全”等关键词时你会发现大量同类项目。建议不要只看不练挑一个自己感兴趣的方向从一份能运行的代码开始逐步改成自己的版本。10. 最佳实践与合规提醒写人狗大作战这个小项目时有一些工程习惯可以提前养成。第一代码要分模块。目前所有代码在同一个文件里这是为了便于阅读。继续扩展时可以把游戏逻辑、绘制逻辑、初始化配置拆成不同模块或者将重复逻辑封装成类。第二参数统一管理。player_speed、dog_size、bread_speed这类数值最好集中放在文件开头方便以后统一调整。不要让魔法数字散落在代码各处。第三保留一份最小可运行版本。每当你准备加新功能先复制一份当前能正常运行的代码。这样即使新改的东西写挂了也能回退到稳定版本不需要从零开始找问题。第四关于游戏素材和合规问题。人狗大作战使用 pygame 绘制的简单几何图形不涉及外部图片、音频、字体文件因此没有素材版权风险。后续如果你自己添加图片、音乐、音效务必确认素材来源使用可商用授权的素材或者在代码中保留来源信息。第五如果后续把游戏发布到公开平台建议注意隐私和数据安全。本地小游戏本身不涉及用户数据收集但如果你增加了排行榜、在线对战、用户注册等功能就要考虑个人信息保护和数据合规问题不要未经授权收集用户信息。第六角色形象和美术素材要避免使用未经授权的人物肖像、品牌形象、卡通角色。如果需要给游戏贴上更丰富的角色外观可以自己绘制或者使用开源游戏素材库中的授权素材。11. 总结与下一步人狗大作战这个项目最值得尝试的点在于它让抽象、零散的 Python 语法变成了一款看得见、玩得到、能修改的小游戏。你不需要理解复杂算法也不需要高配电脑只要装好 Python 和 pygame把代码跑起来就能直观感受到“代码驱动世界”的成就感。建议你最先验证的不是画面效果而是“从运行到游戏结束再到重新开始”这整套流程。它能帮你把事件循环、碰撞检测、状态管理这些概念串起来。最容易踩的坑主要集中在环境安装和游戏结束后的状态重置上这两块在检查清单里都已经给了对应方案。代码跑通之后可以继续做几件事调整player_speed、dog_spawn_interval感受参数对游戏难度的影响。把小狗从红色椭圆换成更丰富的造型比如加入耳朵、尾巴的简单图形绘制。增加最高分记录功能把最高分保存到本地文件。用 PyInstaller 打包一份 exe发给朋友运行。把游戏逻辑封装成类拆成多个文件为后续更复杂的项目做准备。一个小游戏能让人对 Python 的兴趣暴涨不是因为游戏本身有多华丽而是因为你亲手用一个下午把一行行代码变成了屏幕上真实可玩的东西。这种正反馈比被动看十遍教程都管用。建议先照着把代码跑起来再按自己的喜好改造动手之后你会发现Python 的下一步远比你想的更宽。