一箭又一箭:软件工程第二次作业
| 这个作业属于哪个课程 | H202601软件工程与软件工程实践 |
|---|---|
| 这个作业要求在哪里 | 2026秋软件工程个人作业(第二次) |
| 这个作业的目标 | 利用 AIGC 和 Python 完成「一箭又一箭」风格的小游戏 |
| 学号 | 102401426 |
| GitHub 仓库 | SE_Homework2 · Apo975 |
一箭又一箭:软件工程第二次作业
1.项目展示
演示视频
https://pan.baidu.com/s/1LvNzjVENHIIcmWCUvn_I5A?pwd=mxzv
开始界面
游戏过程
通关界面
失败界面
2.项目介绍
游戏规则
- 棋盘中包含朝上、下、左、右四个方向的箭头;
- 玩家可以通过鼠标点击棋盘中的箭头进行操作;
- 点击箭头后,程序会检查该箭头前进方向到棋盘边界之间是否存在其他箭头;
- 如果前方没有其他箭头阻挡,箭头会沿自身方向飞出棋盘并被消除;
- 如果前方存在其他箭头,当前箭头不能被消除;
- 被阻挡的箭头会出现前移回弹、晃动和变色反馈;
- 点击被阻挡的箭头会消耗一次失误机会;
- 游戏界面会显示当前关卡、剩余箭头数量、剩余失误次数和关卡计时;
- 清除当前关卡中的全部箭头后,即可通关并进入下一关;
- 当前关卡的失误次数耗尽后,挑战失败;
- 游戏失败后可以重新开始当前关卡;
- 游戏进行中可以使用重开按钮恢复当前关卡初始状态;
- 游戏支持暂停、继续和暂停后返回开始菜单;
- 完成第三关后,玩家可以返回开始界面重新开始游戏。
界面设计
- 游戏采用深紫渐变背景与浅色卡片搭配,整体风格偏向休闲益智游戏。
- 开始界面包含独立标题卡片、规则摘要、“开始游戏”和“退出游戏”按钮;
- 游戏界面包含顶部状态栏、棋盘、反馈提示框、重开与暂停按钮;
- 通关和失败时会显示独立结果面板。
- 棋盘使用圆角网格设计,箭头以带阴影和高光的圆形徽章形式呈现。
- 不同方向的箭头使用不同颜色,以增强辨识度。
- 暂停和最终通关状态均加入暗色遮罩,使用户注意力集中到当前操作面板。
主要功能
- 开始、游戏、通关、失败四种界面状态;
- 6 × 6 网格棋盘与上、下、左、右四方向箭头;
- 鼠标点击箭头与空白格反馈;
- 同行或同列的箭头路径阻挡检测;
- 无阻挡箭头飞出并消失;
- 被阻挡箭头前移回弹、晃动、变色,并扣除失误次数;
- 3 个固定且可正常通关的关卡;
- 关卡切换、游戏内重开、最终返回开始菜单;
- 关卡自动计时、暂停、继续和暂停后返回菜单;
- 开始界面退出游戏功能。
项目特色
-
明确的动画反馈:箭头成功消除时沿自身方向飞出;被阻挡时会前移后回弹,并配合晃动与红色提示,帮助玩家理解判定结果。
-
完整的游戏流程:从开始菜单、关卡挑战、通关切换到失败重开均具备完整状态管理,第三关通关后可返回开始菜单。
-
较完整的交互体验:游戏中支持重开、暂停、继续、退出至菜单和退出游戏,计时功能也能在暂停与重开时正确处理。
-
统一的视觉风格:使用深紫渐变背景、圆角面板、状态卡片和徽章式箭头,使开始界面、游戏界面和结果界面保持统一的视觉语言。
3.实现思路
箭头表示
程序使用字典表示每个箭头,记录其行、列和方向:
{
"row": 2,
"col": 0,
"direction": "right"
}
row:箭头所在行;col:箭头所在列;direction:箭头方向,可取up、down、left、right。
当前关卡中未消除的箭头保存在列表中。玩家成功点击无阻挡箭头后,程序将该箭头从列表中移除,因此重新绘制棋盘时该箭头不再显示。
方向表示
程序用英文字符串表示四种方向:
"up" # 上
"down" # 下
"left" # 左
"right" # 右
方向决定箭头图标的绘制方式、路径检测范围以及飞出动画的移动方向。例如,向上的箭头检测同列上方是否有其他箭头;向右的箭头检测同行右侧是否有其他箭头。
关卡表示
每个关卡使用一个箭头列表表示,多个关卡组成 LEVELS 列表:
LEVELS = [
[
{"row": 2, "col": 0, "direction": "right"},
{"row": 2, "col": 3, "direction": "up"},
],
[
# 第二关箭头数据
],
[
# 第三关箭头数据
],
]
开始新关卡或点击重开按钮时,程序会复制对应关卡的初始数据,恢复箭头布局、失误次数和计时。
路径检测方法
路径检测是游戏的核心逻辑。点击某个箭头后,程序遍历当前棋盘中仍存在的其他箭头,根据被点击箭头的方向判断是否存在阻挡。
核心逻辑如下:
if direction == "up" and other_col == col and other_row < row:
return True
if direction == "down" and other_col == col and other_row > row:
return True
if direction == "left" and other_row == row and other_col < col:
return True
if direction == "right" and other_row == row and other_col > col:
return True
判断规则:
- 向上:检查同一列中是否存在行号更小的箭头;
- 向下:检查同一列中是否存在行号更大的箭头;
- 向左:检查同一行中是否存在列号更小的箭头;
- 向右:检查同一行中是否存在列号更大的箭头。
只要找到一个满足条件的箭头,就说明当前箭头前方存在阻挡,不能被消除;如果遍历结束都没有找到阻挡箭头,则该箭头可以飞出棋盘。
游戏状态管理
程序使用不同状态管理游戏流程:
"start" # 开始界面
"playing" # 游戏进行中
"success" # 当前关卡通关
"failed" # 当前关卡失败
根据不同状态,程序绘制对应界面并限制可执行操作。例如,暂停时不能点击棋盘箭头;通关或失败后只能点击结果面板中的按钮。
4.AIGC 使用过程
按照要求记录至少 3 次具有代表性的 AI 协作过程;
第一次
分析作业要求
| 项目 | 内容 |
|---|---|
| 向 AI 提出的需求 | 要求 AI 阅读并理解作业说明,整理项目需要实现的功能、GitHub 提交要求、自动化测试要求和博客撰写结构。 |
| AI 完成的工作 | AI 将作业要求划分为游戏开发、版本管理、自动化测试和博客撰写四个部分,并生成了作业要求理解文档。 |
| 实际效果 | 帮助我在开发前明确了任务范围,并确定先完成最小可行版本,再逐步增加关卡、动画、暂停和界面美化等功能。 |
| 人工检查与修改 | 我重新对照原始作业要求进行检查,确认作业原文不需要上传,并决定 GitHub 仓库只保存项目成果、测试代码、依赖文件和说明文档。 |
第二次
修复第二关无法完成的问题
| 项目 | 内容 |
|---|---|
| 向 AI 提出的需求 | 在试玩过程中发现第二关存在箭头互相阻挡、无法全部消除的问题,要求 AI 检查关卡数据和箭头移动方向。 |
| AI 完成的工作 | AI 分析了第二关各箭头的位置和方向,找出了形成相互阻挡关系的箭头,并修改了部分箭头的位置或方向。 |
| 实际效果 | 修改后的第二关不再出现无法解除的循环阻挡,所有箭头都能按照合理顺序被消除。 |
| 人工检查与修改 | 重新运行游戏并多次试玩第二关,按照不同顺序点击箭头,确认关卡可以正常完成后保留了修改结果。 |
第三次
编写和修正自动化测试
| 项目 | 内容 |
|---|---|
| 向 AI 提出的需求 | 要求 AI 根据题目规定的 T01~T06 测试项,并结合项目新增功能补充 T07~T16,使用自动化测试验证游戏逻辑。 |
| AI 完成的工作 | AI 使用 unittest 编写了16项测试,覆盖箭头路径检测、成功消除、阻挡反馈、失误次数、关卡切换、重新开始、暂停和计时等功能。 |
| 实际效果 | 自动化测试能够快速检查核心游戏逻辑,减少了每次修改代码后完全依靠人工试玩的工作量。 |
| 人工检查与修改 | 初次运行时 T14 测试失败。检查后发现测试所选位置实际存在箭头,而不是空白格。我调整了测试数据的选取方式并重新运行,最终16项测试全部通过。 |
5.测试结果
测试环境:
- Python 3.12.14
- Pygame 2.6.1
- 测试框架:Python
unittest - 测试结果:16 项全部通过
| 编号 | 测试内容 | 测试操作 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|---|
| T01 | 点击无阻挡箭头 | 选择当前关卡中前方没有其他箭头的箭头并点击 | 箭头进入飞出状态,从棋盘数据中移除,剩余箭头数减 1 | 箭头成功进入飞出状态,箭头数量减少 1,反馈为“箭头飞出棋盘” | 通过 |
| T02 | 点击有阻挡箭头 | 选择当前关卡中前方存在其他箭头的箭头并点击 | 箭头不消失,失误次数减 1,并触发碰撞动画 | 箭头数量不变,失误次数由 3 减为 2,碰撞动画状态成功启动 | 通过 |
| T03 | 点击边缘朝外箭头 | 创建位于棋盘边缘且朝向棋盘外的箭头并点击 | 箭头正常飞出,不发生数组越界或程序异常 | 箭头正常移除,反馈为“箭头飞出棋盘”,未发生越界错误 | 通过 |
| T04 | 清除当前关卡全部箭头 | 自动寻找并依次点击所有当前可飞出的箭头 | 全部箭头清除后,游戏状态变为通关 | 箭头全部清除,飞出动画结束后游戏状态变为 success |
通过 |
| T05 | 失误次数耗尽 | 连续 3 次点击被阻挡的箭头 | 失误次数变为 0,游戏状态变为失败 | 失误次数变为 0,游戏状态变为 failed |
通过 |
| T06 | 游戏中重新开始 | 消除一个箭头并改变计时后,点击游戏内“重开”按钮 | 当前关卡布局、失误次数和计时恢复初始状态 | 箭头布局恢复,失误次数恢复为 3,计时恢复为 0 | 通过 |
| T07 | 开始游戏 | 在开始状态下点击“开始游戏”按钮 | 进入第一关并正确初始化游戏数据 | 游戏状态变为 playing,加载第一关,箭头布局正确 |
通过 |
| T08 | 进入下一关 | 自动完成第一关后点击“下一关”按钮 | 进入第二关并加载第二关初始布局 | 当前关卡变为第二关,游戏状态和箭头布局初始化正常 | 通过 |
| T09 | 暂停游戏 | 点击“暂停”按钮后推进计时并点击棋盘箭头 | 计时停止,棋盘操作无效 | 暂停状态保持,计时未增加,箭头数量未改变 | 通过 |
| T10 | 继续游戏 | 暂停后再次点击“继续”,随后推进计时 | 取消暂停,计时恢复增长 | 暂停状态解除,计时正常增加 | 通过 |
| T11 | 暂停后退出至菜单 | 暂停游戏后点击“退出至菜单” | 返回开始界面,不关闭程序 | 游戏状态变为 start,暂停解除,程序未退出 |
通过 |
| T12 | 退出游戏 | 在开始界面点击“退出游戏”按钮 | 设置退出状态并正常结束程序主循环 | 退出标志成功变为 True |
通过 |
| T13 | 最终关卡返回菜单 | 加载并完成第三关,然后点击“返回开始” | 返回开始界面,当前关卡重置为第一关 | 游戏状态变为 start,当前关卡索引恢复为 0 |
通过 |
| T14 | 点击空白格 | 自动寻找当前关卡中的空白棋盘格并点击 | 箭头和失误次数不变,显示空白格提示 | 箭头布局和失误次数均未改变,反馈为“这里没有箭头” | 通过 |
| T15 | 动画状态 | 触发箭头飞出动画和阻挡回弹动画,并持续更新动画帧 | 两种动画都能正常结束,不残留错误状态 | 飞出动画对象最终清空,碰撞动画帧最终归零 | 通过 |
| T16 | 计时重置 | 修改当前计时后点击重开;完成关卡后进入下一关 | 重开和进入下一关时计时均恢复为 0 | 两种情况下计时都成功恢复为 0 | 通过 |
6.PSP 表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 1 | 0.5 | -0.5 |
| Python 与图形库学习 | 2 | 3 | 1 |
| 游戏界面实现 | 2 | 1 | -1 |
| 路径与碰撞逻辑实现 | 2 | 0.5 | -1.5 |
| 关卡设计 | 1 | 0.5 | -0.5 |
| AIGC 辅助开发 | 3 | 2 | -1 |
| 测试与修改 | 2 | 1 | -1 |
| README 与博客撰写 | 2 | 2 | 0 |
| 合计 | 15 | 10.5 | -4.5 |
7.心得体会
本次作业中,我使用 Codex 辅助完成了“一箭又一箭”小游戏的需求分析、代码编写、界面优化、问题排查、自动化测试和文档整理。相比完全独立开发,AI 能够快速提供实现思路和代码框架,降低了学习 Pygame 和处理游戏逻辑的难度。
通过本次作业,我掌握了 Pygame 的窗口创建、图形绘制、鼠标事件处理和游戏循环等基本用法,也进一步理解了二维坐标、路径检测、状态管理、动画反馈和关卡数据设计。同时,我学习了使用 Git 和 GitHub 分阶段提交代码,并通过 unittest 编写自动化测试。
AI 在路径检测、游戏状态管理和动画实现方面提供了较大帮助。例如,程序需要根据箭头方向检查同一行或同一列中的其他箭头,AI 帮助我将四个方向的判断条件整理成清晰的代码。开发过程中,我还借助 AI 逐步实现了箭头飞出、碰撞前移回弹、晃动变色、关卡计时、暂停和重新开始等功能。
但 AI 给出的结果不总是正确的。早期设计的第二关出现了箭头互相阻挡的问题,导致关卡无法通关;界面优化过程中也出现过文字超出边框、提示内容与棋盘重叠、窗口高度过大等情况。添加自动化测试时,T14 最初选择的“空白格”实际上存在箭头,使测试错误地扣除了失误次数。遇到这些问题后,我通过实际运行、观察现象和分析数据,对关卡布局、界面坐标和测试代码进行了修改。
这次实践让我认识到,AI 更适合作为开发过程中的辅助工具,而不是完全代替开发者。AI 可以快速生成方案,但开发者仍需要理解代码、验证功能,并对不合理的结果进行调整。如果不了解程序的核心逻辑,就很难判断 AI 生成的代码是否正确,也难以发现隐藏的问题。本次作业不仅完成了一个简单的小游戏,也让我体会到了与 AI 协作开发时,需求表达、结果验证和人工判断的重要性。

浙公网安备 33010602011771号