软件工程课程第二次个人作业
软件工程课程第二次个人作业:Pygame 网格解谜游戏《一箭又一箭》开发记录
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/202601SofwareEngineering |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/202601SofwareEngineering/homework/16717 |
| 这个作业的目标 | 合理使用AIGC完成“一箭又一箭”python小游戏 |
| 学号 | 0724080101 |
| GitHub 仓库 | https://github.com/baiyi060404/arrow-game/tree/main |
一、项目展示
本项目的最终成果是一个可运行的 Pygame 网格解谜游戏,主要展示内容包括主界面、第一关、第三关和无尽模式。
演示 GIF

主界面

第一关游戏界面

第三关游戏界面

无尽模式

胜利界面

失败界面

二、项目介绍
2.1 游戏规则
游戏名称为《一箭又一箭》,英文项目名为 arrow-game。棋盘上分布着不同方向、不同长度的箭头:
- 单格箭头占用一个格子
- 长箭头由头部和多段身体组成
- 第二、三关中的长箭头可以弯折
点击箭头后:
- 箭头头部先向前移动一格
- 身体每一段依次跟随前一段上一帧的位置
- 移动过程类似“蛇的跟随”
- 前方没有阻挡时,箭头继续向前移动
- 前方存在其他箭头时,箭头停止移动并扣除一次失误次数
2.2 界面设计
- 主菜单:开始游戏、设置、离开游戏
- 选关界面:第 1 关、第 2 关、第 3 关、无尽模式
- 设置界面:窗口模式 / 全屏模式切换
- 游戏界面:HUD 显示关卡、剩余箭头、得分、时间、爱心
- 结算界面:显示最终得分和星级评价
2.3 主要功能与特色
- 支持普通关卡和无尽模式
- 支持长箭头、弯折箭头
- 支持蛇形逐步移动动画
- 支持碰撞检测与失误反馈
- 支持得分、计时和星级评价
- 支持成功滑出与碰撞音效
- 使用缓存优化第二、三关加载速度
三、实现思路
3.1 箭头和方向的表示
项目使用数字编码表示方向:
DIRECTIONS = {
1: (-1, 0), # 上
2: (1, 0), # 下
3: (0, -1), # 左
4: (0, 1), # 右
}
第一关的普通箭头直接存放在 level_data 二维数组中:
0:空格
1:上
2:下
3:左
4:右
第二、三关使用可弯折的蛇形箭头,每个箭头保存为有序坐标列表:
{
"cells": [头部, 身体段1, 身体段2, ..., 尾巴],
"direction": 当前头部移动方向,
}
其中 cells[0] 永远是头部,后面依次是身体段,最后是尾巴。
3.2 关卡表示
普通关卡配置集中在 LEVELS 字典中:
LEVELS = {
1: {"size": 9, "cell_size": 40, "total_arrows": 20},
2: {"size": 11, "cell_size": 36, "total_arrows": 24},
3: {"size": 13, "cell_size": 32, "total_arrows": 34},
}
第一关只生成单格箭头;第二、三关使用蛇形箭头列表 self.arrows,同时维护 snake_grid 记录每个格子的占用箭头编号,用于碰撞判断。
3.3 路径检测方法
第一关使用 can_arrow_fly_out(row, col, direction) 进行直线路径检测:
- 从箭头头部开始
- 沿箭头方向逐格检查
- 遇到非空格子说明前方被阻挡
- 一直检查到棋盘外仍无阻挡,说明可以飞出
核心逻辑如下:
def can_arrow_fly_out(self, row, col, direction):
dr, dc = self.DIRECTIONS[direction]
check_row = row + dr
check_col = col + dc
while 0 <= check_row < self.BOARD_SIZE and 0 <= check_col < self.BOARD_SIZE:
if self.level_data[check_row][check_col] != 0:
return False
check_row += dr
check_col += dc
return True
对于蛇形箭头,移动时还需要判断“下一格是否可以走”:
def can_snake_arrow_step(self, arrow_index):
...
if 下一格越界:
return "fly_out"
if 下一格存在其他箭头:
return "blocked"
return "move"
蛇形箭头的完整飞出判断使用 can_snake_arrow_fly_out,它调用只读函数 is_snake_arrow_path_clear,从 cells[0] 头部开始沿方向逐格扫描,直到棋盘外:
- 途中发现
snake_grid非 0,返回False - 一路畅通到边界外,返回
True
点击蛇形箭头时,先判断整条前方路径是否可飞出;如果被阻挡则立即触发碰撞反馈,不创建移动动画。
四、AIGC 使用过程
本次开发中主要使用了 Codex、ChatGPT 等 AIGC 工具。以下记录三次有代表性的协作过程。
| 子任务 | 借助何种 AIGC 技术 | AI 实现或提供了什么 | 效果如何 | 人工修改 |
|---|---|---|---|---|
| 路径检测 | ChatGPT / Codex | 生成四个方向的检测代码 | 向上判断时出现越界 | 修改边界条件后正常 |
| 关卡设计 | ChatGPT / Codex | 生成第二、三关可弯折箭头和可通关检测 | 存在相互阻挡导致无解 | 增加可通关检测,并调整生成策略 |
| 蛇形移动与渲染 | ChatGPT / Codex | 生成头部移动、身体跟随、折线绘制代码 | 身体段顺序和坐标映射出错 | 修正 cells 顺序,修正像素坐标映射 |
4.1 路径检测协作
我向 AI 提出:
“实现路径检测函数,输入箭头坐标和方向,判断从箭头位置到棋盘边界之间是否存在其他箭头,四个方向都要处理。”
AI 生成了基本检测逻辑,但最初在向上方向判断时数组越界,导致边缘箭头报错。我检查后修改了边界条件,最终稳定运行。
4.2 关卡生成协作
我向 AI 提出:
“设计三个可通关关卡,第二、三关包含可弯折长箭头,并保证不存在无解关卡。”
AI 最初生成了随机布局,但实际测试发现存在多个箭头相互阻挡、无法全部消除的情况。我让 AI 增加 has_snake_solution 检测函数,并在生成时验证是否存在可消除顺序。同时人工调整第三关箭头数量和弯折比例,最终保证关卡可通关。
4.3 蛇形移动与渲染协作
我向 AI 提出:
“箭头头部先移动一格,身体每一段跟随前一段上一帧的位置,渲染时按照顺序连接成连续折线。”
AI 生成了移动和渲染代码,但出现两个问题:
- 身体段坐标顺序不正确,导致渲染图形扭曲。
- 像素坐标
x对应列、y对应行,AI 写反了偏移。
我修改了 cells 顺序和 body_start 坐标映射,最终实现连续弯折箭头效果。
五、测试结果
测试环境:
- Windows
- Python 3.11
- Pygame 2.6.x
主要测试结果如下:
| 编号 | 测试内容 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|
| T01 | 点击前方无阻挡的箭头 | 箭头飞出棋盘并消失 | 箭头逐步飞出并清除 | 通过 |
| T02 | 点击前方有阻挡的箭头 | 箭头不消失,失误次数减 1 | 箭头原位红色晃动,爱心减 1 | 通过 |
| T03 | 点击位于边缘且朝向棋盘外的箭头 | 箭头正常消失,不发生越界错误 | 正常飞出,无越界 | 通过 |
| T04 | 消除本关全部箭头 | 显示通关并进入下一关 | 显示通关,普通关卡可进入下一关 | 通过 |
| T05 | 失误次数耗尽 | 显示失败并允许重新开始 | 显示失败,可重新开始 | 通过 |
| T06 | 游戏进行中重新开始 | 箭头布局和失误次数恢复 | 布局重新生成,爱心恢复 3 个 | 通过 |
自动化测试命令:
python -m unittest test_path_detection.py -v
测试结果:全部通过。
六、PSP 表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 3 | 4 | +1 |
| Python 与图形库学习 | 4 | 5 | +1 |
| 游戏界面实现 | 1 | 3 | +2 |
| 路径与碰撞逻辑实现 | 5 | 8 | +3 |
| 关卡设计 | 4 | 6 | +2 |
| AIGC 辅助开发 | 3 | 4 | +1 |
| 测试与修改 | 4 | 6 | +2 |
| README 与博客撰写 | 2 | 3 | +1 |
| 合计 | 26 | 39 | +13 |
七、心得体会
7.1 AI 带来的帮助
- 快速生成基础代码和框架
- 快速补全路径检测、动画等重复性逻辑
- 帮助分析越界、坐标映射等隐蔽问题
7.2 使用 AI 时出现的问题
- AI 生成的代码并不总是符合游戏规则
- 关卡随机生成容易出现无解布局
- 蛇形移动和渲染容易出现坐标顺序错误
- 直接使用 AI 代码会导致功能看似可用,但实际存在边界问题
7.3 个人收获
这次开发让我更清楚地理解了:
- 网格坐标和像素坐标之间的转换
- 蛇形移动时“先备份旧坐标,再更新新坐标”的重要性
- 关卡不能只随机生成,还需要验证是否存在可通关顺序
- AIGC 是很好的加速工具,但必须结合测试和人工验证
最终项目实现了普通关卡、无尽模式、得分、计时、星级评价和音效反馈,并完成了较完整的自动化测试。

浙公网安备 33010602011771号