软件工程作业2:一箭又一箭,一改又一改
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | H202601 软件工程与软件工程实践 |
| 这个作业要求在哪里 | 2026 秋软件工程个人作业(第二次) |
| 这个作业的目标 | 使用 Python 和 AIGC 完成「一箭又一箭」小游戏 |
| 学号 | 112401237 |
| Github 仓库 | zwoyyzy/one-arrow-game |
一、项目展示
完整演示视频-在b站上发布Se_实践,可点击仓库查看有多次commit记录。
🧩 1.开始界面
🧩 2.关卡选择
🧩 3.游戏过程
✅ 通关
⭕️失败
🧩 4.全部通关界面
二、项目介绍
1. 游戏规则
本游戏是一款点击式箭头解谜游戏。棋盘中分布着朝上、下、左、右四个方向的箭头,玩家需要观察箭头的朝向以及箭头之间的阻挡关系,按照合理的顺序将全部箭头清除。> 玩家使用鼠标点击箭头后,程序会沿着该箭头指向的方向检测同一行或同一列:
- 如果箭头与棋盘边界之间没有其他箭头阻挡,该箭头飞出棋盘并被消除
- 路径上存在其他箭头,该箭头不能被消除,并通过变红、震动和底部文字提示表现碰撞效果
- 每个关卡共有 3 次失误机会,点击被阻挡的箭头会扣除一颗红心
- 当所有箭头都被成功清除后,游戏显示通关界面,并根据通关时间评定一至三星。玩家可以重新挑战、进入下一关或返回首页;当 3 次失误机会全部耗尽时,游戏显示失败界面,玩家可以重新开始当前关卡。
- 点击“重新开始”按钮后,当前关卡的箭头布局、剩余失误次数和计时都会恢复到初始状态。
- 游戏计时从进入关卡时开始,暂停游戏后计时停止,继续游戏后恢复计时
2. 界面设计
本游戏采用新粗犷主义Neo-Brutalism作为主要视觉风格。界面以暖白色为背景,通过粗黑边框、右下硬阴影和高饱和度色块突出卡片与按钮,使游戏具有鲜明、活泼的视觉效果。荧光黄主要用于标题和关键信息,电光蓝用于功能按钮,珊瑚红用于失误和碰撞提示。游戏中的图标与箭头均使用 Pygame 几何图形绘制,没有使用原商业游戏的美术素材。
为了保证功能清晰并形成完整的游戏流程,项目设计了以下界面:
- 开始界面:显示游戏标题和主要模式入口,包括主线关卡、继续游戏、关卡选择和随机挑战。
- 关卡选择界面:以卡片形式展示5个主线关卡。
- 游戏界面:顶部状态区域显示当前关卡、剩余箭头、游戏用时和剩余失误次数。剩余失误统一使用3颗红心表示,每次错误点击会扣除一颗。棋盘位于页面视觉中心,右侧提供重新开始、暂停等操作,右下角设置提示和AI自动求解按钮。
- 通关界面:清除全部箭头后显示通关弹窗,并展示本关用时、操作步数和星级评价。星级根据玩家通关时间与AI参考时间进行计算,最高为三星。玩家可以选择重玩本关、进入下一关或返回首页。
- 失败界面:当3次失误机会全部耗尽时,显示挑战失败信息,并提供重新开始和返回首页等操作,使玩家能够快速再次挑战。
- 暂停界面:玩家点击暂停后,游戏画面会变暗,关卡计时同时停止。界面中央显示继续游戏按钮,点击后恢复游戏和计时,防止暂停时间影响最终成绩。
- 声音设置界面:玩家可以分别控制背景音乐和箭头飞出音效,不需要关闭全部声音,能够根据个人习惯调整游戏的声音反馈。
3. 主要功能
- 箭头消除: 点击前方无阻挡的箭头,使其飞出棋盘并消失。
- 路径检测: 检测箭头指向的同一行或同一列中是否存在其他箭头。
- 碰撞反馈: 点击被阻挡的箭头时,箭头变红并震动,同时扣除一次失误机会。
- 关卡系统: 包含5个固定主线关卡,通关当前关卡后解锁下一关。
- 随机挑战: 从三种棋盘规格中随机选择一种,生成经过求解验证的随机关卡。
- 游戏辅助: 提供提示、AI自动求解、暂停和重新开始功能。
- 计时与星级: 记录通关时间,并参考AI求解时间评定一至三星。
- 进度保存: 自动保存主线关卡进度、最高星级和最佳时间。
- 声音设置: 提供背景音乐和游戏音效,并支持分别开启或关闭。
- 游戏反馈: 包含箭头飞出、碰撞、通关和失败等动画及声音效果。
4. 项目特色
本项目在完成箭头点击、路径检测、碰撞反馈、失误次数和关卡切换等基础要求的基础上,进一步实现了多项扩展功能,使游戏的内容、交互和完整性得到提升。
| 扩展功能 | 具体实现 |
|---|---|
| 5个主线关卡 | 设计了5个难度逐渐提高的固定关卡,通关当前关卡后解锁下一关 |
| 关卡选择 | 显示每关的解锁状态、最高星级和最佳通关时间,未解锁关卡以灰色锁定卡片表示 |
| 随机挑战 | 从6×6、7×7和8×8三种规格中随机选择棋盘,并随机生成箭头的位置和方向 |
| AI自动求解 | 自动计算当前关卡的正确消除顺序,并按照该顺序演示完整通关过程 |
| 提示功能 | 帮助玩家找到当前可以安全飞出的箭头,降低关卡难度 |
| 计时与暂停 | 进入关卡后自动计时,暂停时停止计时,继续游戏后恢复 |
| 星级评价 | 根据玩家通关时间与AI参考时间进行一至三星评价 |
| 游戏进度保存 | 自动保存主线关卡的解锁进度、最高星级、最佳时间和未完成关卡 |
| 动画反馈 | 成功消除时播放箭头飞出动画,发生阻挡时显示变色和震动效果 |
| 音乐与音效 | 加入背景音乐以及飞出、碰撞、通关和失败音效,并支持单独开关 |
| 可执行文件 | 使用PyInstaller将程序打包成Windows可执行文件,没有安装Python的用户也可以运行 |
下面是一些展示:
AI自动求解
已打包为可执行文件
提示/暂停/重置/声音设置功能
游戏进度保存
当玩家尚未通关当前关卡便返回首页时,程序会保存当前关卡编号、剩余箭头的位置与方向、剩余失误次数、操作步数和已经使用的时间。此时首页会显示“继续主线”入口,玩家点击后可以恢复离开前的棋盘状态,并在原有计时基础上继续挑战,而不需要从头开始。
当玩家通关当前关卡并返回首页时,程序会记录该关卡的通关状态、最高星级和最佳时间,同时将下一关的初始状态保存为新的游戏进度。因此,首页的“继续主线”会进入下一关,而不是返回已经通关的关卡。
如果玩家通关了最后一关,程序会保留五个主线关卡的通关成绩,但不会再生成下一关存档。
如果玩家失误次数耗尽,则本次失败对局不会作为未完成进度保留,但之前获得的关卡成绩不会受到影响。
此外,随机挑战模式不保存游戏进度,返回首页后再次进入时会重新生成一个随机关卡。
三、实现思路
本项目使用 Python 和 Pygame 开发,并按照功能拆分代码。game.py 负责游戏流程和鼠标事件,arrow.py 负责箭头对象与路径检测,levels.py 保存主线关卡,random_levels.py 生成随机挑战,ui.py 负责界面绘制,save_manager.py 负责保存游戏进度。
1. 箭头与关卡的表示
每支箭头使用“行、列、方向”三个数据表示;四个方向使用二维向量表示
(row, col, direction)
DIRECTION_VECTORS = {
"up": (-1, 0),
"down": (1, 0),
"left": (0, -1),
"right": (0, 1),
}
主线关卡以字典形式保存,包含棋盘大小、失误上限、箭头列表和参考解法:
return {
"name": f"第 {level_number} 关",
"rows": size,
"cols": size,
"max_mistakes": max_mistakes,
"arrows": arrows,
"solution": solution,
}
项目共设计了5个主线关卡,箭头数量逐渐增加,并保证每关均包含四种方向且可以正常通关。
2. 路径检测
路径检测是游戏的核心。程序从被点击箭头前方的第一个格子开始,沿箭头方向逐格检查,直到到达棋盘边界。
def is_path_clear(arrow, arrows, rows, cols):
row_step, col_step = DIRECTION_VECTORS[arrow.direction]
check_row = arrow.row + row_step
check_col = arrow.col + col_step
occupied_positions = {
(other.row, other.col)
for other in arrows
if other is not arrow
and other.state != "flying"
}
while 0 <= check_row < rows and 0 <= check_col < cols:
if (check_row, check_col) in occupied_positions:
return False
check_row += row_step
check_col += col_step
return True
如果检查过程中发现其他箭头,则返回 False,表示路径被阻挡;如果一直检查到边界都没有发现箭头,则返回 True,表示箭头可以飞出。
3. 主线关卡与随机挑战
主线关卡的数据固定保存在 levels.py 中,因此每一关的棋盘大小、箭头位置和方向保持不变。随机挑战会从三种规格中随机选择一种。
程序随机选择箭头位置和方向,并检查布局是否具有足够的阻挡关系。生成后还会调用自动求解函数进行验证:
while arrows:
safe_arrows = [
arrow
for arrow in arrows
if is_path_clear(arrow, arrows, rows, cols)
]
if not safe_arrows:
return None
arrow = random.choice(safe_arrows)
solution.append((arrow.row, arrow.col))
arrows.remove(arrow)
只有能够将全部箭头清除的布局才会作为随机关卡,从而避免生成无法通关的题目。
4. 游戏进度保存
程序使用本地JSON文件保存主线游戏进度。未通关时返回首页,会保存当前关卡、剩余箭头、失误次数、操作步数和已用时间;通关后则记录该关的最高星级和最佳时间,并解锁下一关。
return {
"level_index": self.level_index,
"remaining_arrows": [
[arrow.row, arrow.col, arrow.direction]
for arrow in self.arrows
if arrow.state != "flying"
],
"mistakes_left": self.mistakes_left,
"moves_count": self.moves_count,
"elapsed_ms": self.get_elapsed_milliseconds(),
}
随机挑战不保存对局进度,每次进入都会重新生成新的关卡。
四、AIGC使用过程
1.使用记录
| 子任务 | 借助的 AIGC 工具 | 我提出的要求 | AI 实现或提供的内容 | 实际效果 | 我的测试与修改 |
|---|---|---|---|---|---|
| 作业内容分析 | ChatGPT | 阅读并分析作业要求,梳理必须完成的基础功能、界面要求、测试要求、GitHub要求和扩展功能,帮助我确定整体开发流程 | ChatGPT将作业要求整理为需求分析、环境配置、代码结构设计、核心玩法实现、关卡设计、测试和文档编写等阶段,并列出了各阶段需要完成的任务 | 让我对作业内容和开发顺序有了较清晰的认识,避免遗漏开始界面、失误机制、重新开始和测试记录等要求 | 我重新阅读原始作业要求,将AI整理的内容与评分标准逐项对照,只保留与本项目有关的功能,并决定先完成基础要求,再实现附加功能 |
| 游戏基础结构设计与启动问题调试 | Codex | 根据作业的11项基本要求设计代码结构,并解决游戏运行后窗口闪退和中文字体显示异常的问题 | Codex将项目划分为程序入口、游戏流程、箭头对象、关卡数据和界面绘制等模块。出现闪退后,指导我通过VS Code终端运行程序,根据完整报错定位到ui.py中的字体匹配问题,并提供修改方案 |
代码结构基本覆盖了作业要求;修复字体加载逻辑后,游戏窗口能够稳定打开,中文标题、按钮和提示文字也能正常显示 | 我简化了AI最初提供的设计内容,按照先基础功能、后扩展功能的顺序开发。发生闪退时,我将终端报错和截图反馈给Codex,再将修改方案整合到ui.py中,通过多次启动确认问题已经解决 |
| UI页面设计与实现 | Gemini Codex | 在不使用外部商业游戏素材的情况下,为游戏设计一套具有辨识度、适合使用Pygame几何绘制实现的界面 | Gemini主要负责分析和设计UI风格,提出新粗犷主义方案,包括暖白背景、粗黑边框、硬阴影和高饱和度色块;我将确定的设计思路交给Codex,由Codex实现开始界面、游戏界面、关卡选择、暂停界面和结算弹窗 | 初版实现了统一的视觉风格,但存在棋盘与顶部栏距离过近、按钮拥挤、字体大小不一致、箭头与方格不贴合以及部分图标超出边框等问题 | 我先从Gemini给出的方案中确定最终风格,再根据实际运行截图不断向Codex提出修改要求,调整棋盘位置、按钮间距、字体、箭头大小和关卡图标。部分自动修改失败的代码由我手动替换并运行验证 |
| 主线关卡设计 | Codex | 设计5个箭头数量逐渐增加的主线关卡,不要填满棋盘,保证四种方向都出现、阻挡关系正确,并且每一关都可以正常通关 | Codex将5个关卡设计为5×5至9×9棋盘,箭头数量依次为8、12、16、20和24,并为每一关生成箭头位置、方向和经过验证的参考消除顺序 | 第一版关卡虽然可以通关,但箭头数量偏少,而且部分箭头在同一行或同一列中的方向过于一致,布局规律明显,解谜性不足 | 我逐关试玩后,将布局过于规律的问题反馈给Codex,要求重新分散箭头位置、调整方向并增加阻挡关系。修改后,我再次试玩各个关卡,并使用提示和AI自动求解功能检查是否都能正常通关 |
2.使用截图
🔵 作业内容分析
🔵 游戏基础结构设计与相关问题调试
🔵 ui页面设计与实现
🔵 主线关卡设计
3.使用心得
在本项目中,我主要按照“提出需求—AI提供方案或代码—实际运行与试玩—发现问题—反馈修改—再次验证”的流程使用AIGC工具。开发前,我使用ChatGPT梳理作业要求和开发流程;开发过程中,使用Gemini辅助确定界面设计风格,再使用Codex完成Pygame代码实现、关卡设计和问题调试。
AI提高了需求分析、代码编写和错误排查的效率,但第一次生成的结果并不一定完全符合实际需求。例如,界面初版存在布局不协调的问题,主线关卡初版也存在排列过于规律的问题。因此,我仍然需要通过运行程序、观察界面、试玩关卡和检查终端报错来判断实际效果,并根据测试结果对AI提供的内容进行修改和完善。
五、测试结果
为保证严谨,自动化和人工测试double check!
1.自动化测试
为了检查游戏核心逻辑是否正确,使用pytest编写了自动化测试。测试代码位于项目的tests/test_game.py中,共设计了T01—T10十类测试。由于T03分别测试了上、下、左、右四种边缘情况,因此pytest实际执行了13个测试项,最终结果为13 passed。
具体列表如下:
| 编号 | 自动化测试内容 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|
| T01 | 检测前方无阻挡的箭头 | is_path_clear()返回True,说明箭头路径畅通 |
路径检测结果为True |
通过 |
| T02 | 处理前方有其他箭头阻挡的点击 | 箭头状态变为blocked且不会被删除,剩余失误次数减1 |
箭头保留在棋盘中,失误次数由3减为2,并生成阻挡提示 | 通过 |
| T03 | 检测位于四条边且方向朝外的箭头 | 上、下、左、右四种边缘情况均返回路径畅通,并且不发生越界 | pytest分别执行了4个方向的参数化测试,全部通过 | 通过 |
| T04 | 验证5个主线关卡的参考解法 | 解法中的每个箭头在对应步骤都可以安全飞出,最终箭头列表为空 | 5个主线关卡均可按照保存的解法完全清除 | 通过 |
| T05 | 连续触发3次错误点击 | 剩余失误次数变为0,游戏状态切换为失败状态 | 3次错误后进入GAME_OVER状态,并触发失败反馈 |
通过 |
| T06 | 重新开始当前关卡 | 恢复原始箭头布局、3次失误机会和初始操作计数 | 箭头布局恢复,剩余失误变为3,已用失误和操作步数归零 | 通过 |
| T07 | 暂停游戏计时 | 暂停后计时停止,暂停期间的时间不计入游戏用时 | 模拟经过2.5秒后暂停,累计有效时间保持为2.5秒 | 通过 |
| T08 | 使用提示功能 | 程序选中的提示箭头必须是当前可以安全飞出的箭头 | 成功找到安全箭头,路径检测结果为True |
通过 |
| T09 | 保存和读取未完成的主线对局 | 能够将关卡、剩余箭头、失误次数、步数和时间写入JSON并正确读取 | 临时存档写入和读取成功,各项数据保持一致 | 通过 |
| T10 | 生成随机挑战关卡 | 棋盘规格符合要求、位置不重复、四种方向齐全,并且存在完整解法 | 随机关卡的数据格式正确,四种方向齐全,参考解法能够清除全部箭头 | 通过 |
自动化测试主要适合判断数据和逻辑是否正确,但界面效果、动画观感和声音质量难以仅通过代码断言进行评价。因此,还是需要人工测试。
2.人工测试
我亲历亲为亲自依次检查了开始界面、游戏界面、关卡选择、暂停、通关和失败等页面,确认各页面布局正常,中文文字显示清晰,按钮可以正常点击和切换。箭头成功飞出、碰撞变色与震动等动画均能正常播放,背景音乐以及飞出、碰撞、通关和失败音效也可以正常使用。提示和AI自动求解能够按照预期完成操作,未通关进度可以通过首页的“继续关卡”正确恢复。此外,我还对打包后的Windows可执行文件进行了启动和试玩,程序无需安装Python即可正常运行。
六、PSP表格
| 任务 | 预计耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 2 | 1.5 | -0.5 |
| Python 与图形库学习 | 2 | 2.5 | +0.5 |
| 游戏界面实现 | 3 | 4.5 | +1.5 |
| 路径与碰撞逻辑实现 | 3 | 3 | 0 |
| 关卡设计 | 2 | 2.5 | +0.5 |
| AIGC 辅助开发 | 2 | 2 | 0 |
| 测试与修改 | 2 | 3 | +1 |
| README 与博客撰写 | 2 | 3 | +1 |
| 合计 | 18 | 22 | +4 |
本项目预计耗时18小时,实际耗时约22小时。借助AIGC工具,我较快完成了需求分析和初步结构设计,因此这一阶段的实际耗时少于预计。实际增加的时间主要集中在游戏界面实现、关卡调整和程序测试方面。开发过程中,我多次修改界面风格和布局,并对随机挑战、存档、声音设置等功能进行了反复测试,导致最终实际耗时比预计多出4小时。
七、心得体会
这次Codex为主,Gemini打下手,深切体会到了智能体的方便,但也不是百分百托付,有时候一些写入权限获取突然失效,还是需要人工去手动更改代码。并且也需要对代码生成效果进行验证然后更改。还有AI的审美确实很一般,布局之类的也完全不会考虑,人工给提示词反复修改了比较长的时间。然后也是精益求精、尽可能完善功能,算是个人第一次小游戏开发还是挺有意思的,把想法落地放大了我的创造力ദ്ദി˶ー̀֊ー́ )✧
非常感谢老师&助教们的浏览,如果可以的话可以拥有一个还不错的评价吗


浙公网安备 33010602011771号