第二次作业
第二次作业
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | H202601软件工程与软件工程实践 |
| 这个作业要求在哪里 | 2026 秋软件工程个人作业(第二次) - 作业 |
| 这个作业的目标 | 使用 Python 和 AIGC 完成“一箭又一箭”小游戏 |
| 学号 | 102401217 |
| GitHub 仓库 | https://github.com/Emrys-m/arrow-game |
项目展示
开始界面

游戏进行

通关

项目介绍
一、## 游戏规则
一、基本玩法
- 棋盘中分布着若干带有方向的箭头,方向分为上、下、左、右四种。
- 玩家用鼠标左键点击任意一个箭头,程序会检查该箭头前进方向(同一行或同一列)上是否有其他箭头阻挡。
- 前方无阻挡:箭头会以加速拖尾动画飞出棋盘并消失,剩余箭头数减 1,同时获得 +10 分。
- 前方有阻挡:箭头会变红并向前碰撞弹回,无法消除,失误次数 +1,并且 分数 -5(最低扣至 0 分)。
二、胜负条件
- 通关:消除本关全部箭头后,显示通关结算面板,并自动进入下一关。
- 失败:失误次数累计达到 3 次 时,本关失败,显示失败结算面板,可点击重新挑战。
- 游戏共设 5 个关卡,难度逐级递增。
三、得分与星级
- 得分规则:
- 成功消除一个箭头:+10 分
- 发生碰撞失误:-5 分(最低为 0 分)
- 通关奖励:+50 分
- 星级评价(仅通关时结算):
- 3 星:0 次失误通关
- 2 星:1 次失误通关
- 1 星:2 次失误通关
- 失败则为 0 星
- 所有关卡获得的星级会累计显示在开始界面,重新开始整个游戏时归零。
四、撤销功能
- 每关可使用 1 次撤销,用于回退到上一次操作之前的状态(包括箭头布局、得分和失误次数)。
- 无论上一次操作是成功消除还是碰撞失误,均可撤销。
- 使用后撤销按钮变为灰色,不可再次使用;重新开始本关或进入下一关时重置为可用状态。
- 也可以按键盘 Z 键 快速触发撤销。
五、计时系统
- 从进入关卡开始计时,仅在游戏进行中累加。
- 通关或失败时,结算面板会显示本局用时。
六、其他操作
- 重新开始:点击游戏界面右上角的“重新开始”按钮,当前关卡恢复到初始布局,分数和计时清零。
- 开始游戏:在开始界面点击“开始游戏”按钮,或按空格键。
实现思路
一、游戏数据的表示
方向表示:采用字符 'U'、'D'、'L'、'R' 分别代表上、下、左、右四个方向,方便在代码中进行方向判断和后续计算。
箭头与棋盘表示:游戏棋盘是一个 5×5 的二维列表 grid。每个格子对应列表中的一个元素:
None 表示该格子为空。
字符(如 'R')表示该格子上存在一个朝该方向的箭头。
例如:grid[0][1] = 'R' 表示第 0 行第 1 列有一个向右的箭头。
关卡表示:所有关卡数据存放在 LEVELS 列表中,每个关卡都是一个 5×5 的二维列表。切换关卡时,只需根据索引加载对应的二维列表,并深拷贝一份到游戏主棋盘中,确保原始关卡数据不会被修改。
二、路径检测方法(核心逻辑)
路径检测是游戏中最核心的算法。玩家点击一个箭头后,程序需要沿着箭头所指方向逐格检查,判断其与棋盘边界之间是否有其他箭头阻挡。
实现方法:
根据箭头的方向,使用 for 循环沿着行或列进行遍历:
向右 ('R'):从 col + 1 遍历到 COLS - 1,检查 grid[row][c] 是否为 None。
向左 ('L'):从 col - 1 遍历到 0。
向上 ('U'):从 row - 1 遍历到 0,检查 grid[r][col] 是否为 None。
向下 ('D'):从 row + 1 遍历到 ROWS - 1。
如果遍历过程中遇到任意一个非 None 的格子,说明前方有箭头阻挡,立即返回 False;如果遍历结束都没有遇到阻挡,则返回 True,表示该箭头可以飞出棋盘。
边界处理技巧:
利用 Python range 函数的特性,例如 range(col - 1, -1, -1) 在 col = 0 时会自动不执行循环,无需额外编写复杂的边界判断代码,有效避免了数组越界错误。
三、游戏状态与动画实现
状态机:使用 self.state 变量管理四种游戏状态:START(开始)、PLAYING(游戏中)、WIN(通关)、LOSE(失败),不同状态下绘制不同的界面并响应不同的事件。
飞出动画:创建 FlyingArrow 类,记录箭头初始坐标和方向。每帧更新坐标,并利用加速算法(self.speed += 1.2)模拟弹射感。同时使用一个固定长度的列表记录历史坐标,绘制出“拖尾残影”效果。
碰撞弹回动画:创建 BumpingArrow 类,记录起点、方向以及碰撞前的最大移动距离。动画分为“去程”和“回程”两个阶段,向前冲出一段距离后,模拟物理弹回,速度反向并增加 1.5 倍,回到起点后标记动画结束,恢复静止的箭头。
AIGC使用过程



AIGC 使用过程记录
| 子任务 | 借助何种 AIGC 技术 | AI 实现或提供了什么 | 效果如何 | 人工修改 |
|---|---|---|---|---|
| 飞行动画 | DeepSeek | 给箭头飞行增加了拖尾残影效果 | 基本可用 | 调整拖尾颜色 |
| 开始界面 | DeepSeek | 生成开始界面 | 基本可用 | 调整页面样式 |
| 代码git提交 | DeepSeek | 提供将代码通过Git bash上传到GitHub上的方法 | 基本可用 | 修改了Git的安装路径 |
📝 详细过程说明
1. 路径检测与边界处理(核心算法)
- 提出要求:我向 AI 描述了“一箭又一箭”的基础玩法,要求它帮我写出判断箭头前方是否有阻挡的代码,要求支持上下左右四个方向。
- AI 实现:AI 给出了一个
is_path_clear函数,遍历箭头前方格子。 - 实际效果与修改:直接运行后发现向上判断时如果箭头在最顶端(第 0 行)会出现索引越界的隐患。在 AI 的提示下,我明白了 Python 中
range(row - 1, -1, -1)在row=0时天然为空,随后根据这个特性精简了代码,彻底修复了越界 Bug。
2. 碰撞与飞行动画(视觉反馈升级)
- 提出要求:起初游戏点击被阻挡的箭头只会“在原位抖动”,我向 AI 提出想要那种“向前冲一下然后被撞回来”的物理反馈,并且让飞出的箭头更生动。
- AI 实现:AI 为我设计了
BumpingArrow类(去程和回程状态切换)和FlyingArrow类(速度递增与拖尾残影数组)。 - 实际效果与修改:效果非常震撼!但我发现弹回速度太快像瞬移,拖尾颜色太亮遮挡视野。于是我自己调整了参数:把弹回速度从 2.0 降到 1.5 倍,把拖尾颜色透明度降低,让动画更加自然顺滑。
3. 深色 UI 与视觉主题(体验优化)
- 提出要求:最初的界面是白底黑字,像简陋的 PPT,我要求 AI 帮我把它改成“深色、不单调、有活力”的风格。
- AI 实现:AI 提供了深色背景配色方案(深午夜蓝),引入了发光效果(
glow_surf)、圆角格子卡片和霓虹青色(NEON_BLUE)箭头。 - 实际效果与修改:整体质感瞬间提升。不过默认的箭头是普通三角形,我觉得不够犀利,于是自己动手把绘制顶点从 3 个改成了 4 个(尾部内凹),变成了飞镖造型。
测试结果
测试结果
在游戏开发完成后,我对照作业要求,对本程序进行了系统的手工测试,具体测试项目和结果如下:
| 编号 | 测试内容 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|
| T01 | 点击前方无阻挡的箭头 | 箭头飞出棋盘并消失 | 箭头带着拖尾动画加速飞出屏幕并消失,剩余箭头数减 1 | 通过 |
| T02 | 点击前方有阻挡的箭头 | 箭头不消失,失误次数减 1 | 箭头变为红色并向前碰撞弹回,失误次数 +1,箭头仍保留在原位 | 通过 |
| T03 | 点击位于边缘且朝向棋盘外的箭头 | 箭头正常消失,不发生越界错误 | 箭头正常飞出屏幕并消失,程序无报错 | 通过 |
| T04 | 消除本关全部箭头 | 显示通关并进入下一关 | 界面出现绿色“通关!”提示,点击后自动加载下一关 | 通过 |
| T05 | 失误次数耗尽 | 显示失败并允许重新开始 | 界面出现红色“失败!”提示,点击后当前关卡重置 | 通过 |
| T06 | 游戏进行中重新开始 | 箭头布局和失误次数恢复 | 点击“重新开始”按钮,棋盘恢复初始布局,失误次数清零 | 通过 |
PSP 表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 1.0 | 0.5 | -0.5 |
| Python 与图形库学习 | 2.0 | 2.5 | +0.5 |
| 游戏界面实现 | 2.5 | 2.0 | -0.5 |
| 路径与碰撞逻辑实现 | 3.0 | 2.5 | -0.5 |
| 关卡设计 | 1.0 | 1.0 | 0 |
| AIGC 辅助开发 | 2.0 | 2.5 | +0.5 |
| 测试与修改 | 1.5 | 1.0 | -0.5 |
| README 与博客撰写 | 2.0 | 1.5 | -0.5 |
| 合计 | 15.0 | 13.5 | -1.5 |
| 差异分析与说明: |
Python 与图形库学习(+0.5):虽然已有 Python 基础语法,但 Pygame 的图形绘制和事件处理需要重新熟悉。加上配置 Git 和 GitHub 时遇到了不少环境问题(如安装路径冲突、Token 认证报错),额外花了时间排查。
AIGC 辅助开发(+0.5):在调试“开始界面被跳过”、“箭头拖尾动画”和“碰撞弹回”时,反复向 AI 描述问题并验证代码,虽然 AI 生成代码很快,但理解并调试依然需要时间。
游戏界面、路径与碰撞、测试与修改(-0.5):得益于 AI 提供的代码框架非常清晰,加上我们逐层递进地实现(先网格、再箭头、再交互),避免了推倒重来。调试阶段只遇到几处小 Bug,修改效率
附加的功能
- 关卡数设置为了5关,拥有更多关卡
- 在原有基础上增加了得分、计时和星级系统
- 增加了撤销功能,每关仅能撤销一次
- 打包成可执行文件,在GitHub上下载双击即可运行
每个功能都是一点一点加上去的,并分成若干次提交到Github上


1. 心得体会
从最初连 Python 基础语法都忘得差不多、连环境配置都磕磕绊绊,到最终完成一个带有完整状态管理、动画反馈和深色主题的“一箭又一箭”小游戏,这个过程让我深刻体会到了 AIGC 辅助开发的强大,也经历了从“盲人摸象”到“豁然开朗”的成长。
一、AI 带来的帮助
跨越了环境配置的“劝退期”:对于小白来说,配置 Python 虚拟环境、安装 Pygame、解决 Git 的 Token 认证报错、处理安装路径冲突,每一步都是煎熬。AI 用清晰的步骤和截图级的排查建议,帮我跨过了这些初期的门槛。
把抽象逻辑具象化:在实现路径检测时,AI 不仅给出了代码,还解释了如何利用 range 函数的边界特性(如 range(col - 1, -1, -1))来天然规避数组越界。碰撞弹回动画、拖尾残影这些我原本觉得很难的效果,AI 也拆解成了“速度递增”、“历史坐标记录”、“状态切换”等易懂的模块,让我真正理解了背后的原理。
高效的调试工具:当出现“开始界面被跳过”、“图片路径不显示”、“弹回动画卡顿”等问题时,AI 能精准指出是代码执行顺序错误还是逻辑遗漏,大大缩短了修 Bug 的时间。
二、出现的问题与反思
AI 并非“一次性完美”:AI 生成的代码有时存在细微的逻辑漏洞,比如 init 里 load_level 覆盖了 START 状态,导致开始界面被跳过;再比如一开始的碰撞反馈只是原地震动,不够生动,需要反复迭代和人工调整。
不能做“甩手掌柜”:如果只是无脑复制粘贴代码,遇到与本地环境不匹配(如 Python 版本、操作系统差异)的情况时,就会完全束手无策。我学会了把报错信息完整丢给 AI,并结合实际运行结果去判断它的建议是否可行。
拆分任务的重要性:一开始看整个游戏代码会觉得庞大,但在 AI 的建议下,我们采用了“先画网格 -> 再画箭头 -> 再加点击检测 -> 再加动画 -> 最后美化 UI”的迭代路径,这种“小步快跑”的开发模式让复杂问题变得可控。
三、个人收获
技术能力的提升:重新熟悉了 Python,掌握了 Pygame 的图形绘制、事件监听、面向对象编程,以及 Git 和 GitHub 的版本管理。
解决问题的信心:从面对几百行代码的茫然,到能够自己定位问题、修改参数、调试运行,对代码的掌控感增强了。
人机协作的思维:我深刻认识到,AI 是一个极佳的“副驾驶”,它能提供思路和代码框架,但最终的决策、理解、试玩验证和审美调整(比如深色主题的配色、按钮悬停效果)依然需要人类的判断。AI 能写出代码,但理解并让代码真正符合需求,还是得靠自己。

浙公网安备 33010602011771号