软件工程第二次作业
“一箭又一箭”小游戏
| 项目 | 内容 |
|---|---|
| 这个作业属于哪个课程 | H202601 软件工程与软件工程实践 |
| 这个作业要求在哪里 | 第二次个人作业 |
| 这个作业的目标 | 使用 Python 和 AIGC 完成“一箭又一箭”小游戏 |
| 学号 | 102401205 |
| GitHub 仓库 | https://github.com/chen-yeling/one-arrow-game |
1. 项目展示
1.1 开始界面
本项目使用 Python 和 Pygame 实现了“一箭又一箭”小游戏。
游戏开始后进入主界面,玩家可以选择箭头进行操作。

1.2 游戏过程
游戏棋盘中有多个不同方向的箭头,玩家需要观察箭头的方向,判断箭头前方是否存在其他箭头。
如果箭头前方没有阻挡,可以点击箭头,使其沿自己的方向飞出棋盘。
如果前方存在其他箭头,则该箭头无法直接消除,并会触发碰撞效果。

1.3 碰撞效果
当玩家点击被阻挡的箭头时,箭头会向前移动并与前方的箭头产生碰撞,然后出现变红、震动等效果,最后返回原来的位置,同时消耗一次失误机会。

1.4 通关或失败界面
当棋盘上的所有箭头都被消除后,进入通关界面。
当失误次数耗尽后,进入失败界面。


2. 项目介绍
2.1 游戏规则
本游戏是一款箭头消除类小游戏,主要规则如下:
- 棋盘中存在多个不同方向的箭头;
- 每个箭头只能沿自己的方向移动;
- 如果箭头前方没有其他箭头,则点击后可以成功飞出;
- 如果箭头前方存在其他箭头,则该箭头会被阻挡;
- 点击被阻挡的箭头会触发碰撞动画,并消耗一次失误机会;
- 当所有箭头全部消除后,本关通关;
- 当失误次数耗尽后,本关失败。
游戏的核心玩法就是观察箭头方向,判断箭头前方是否有阻挡,然后选择合适的箭头进行消除。
2.2 界面设计
游戏界面比较简洁,主要包括:
- 游戏棋盘;
- 不同方向的箭头;
- 当前关卡;
- 剩余失误次数;
- 游戏状态提示。
游戏过程中主要以箭头和棋盘为视觉重点,方便玩家观察箭头之间的关系。
2.3 主要功能和特色
本项目主要实现了以下功能:
- 不同方向的箭头;
- 箭头路径检测;
- 箭头飞出动画;
- 被阻挡箭头的碰撞动画;
- 失误次数限制;
- 多关卡设计;
- 通关和失败状态;
- 游戏重新开始。
其中比较有特色的是被阻挡箭头的碰撞效果。
玩家点击错误箭头后,可以看到箭头向前移动、碰撞、变红震动,然后返回原位置,而不是简单地提示“不能移动”。
另外,游戏一共设计了三个关卡,箭头数量逐渐增加,第三关增加了不同方向箭头之间的阻挡关系,提高了游戏难度。
3. 实现思路
3.1 箭头表示
游戏中的每个箭头主要需要记录:
- 箭头的位置;
- 箭头的方向;
- 箭头当前的状态;
- 动画过程中的相关信息。
箭头方向主要分为四种:
↑ 向上
↓ 向下
← 向左
→ 向右
在程序中可以将四个方向转换成坐标变化量:
directions = {
"up": (0, -1),
"down": (0, 1),
"left": (-1, 0),
"right": (1, 0)
}
例如向右移动时,横坐标增加,纵坐标不变;向上移动时,纵坐标减少。
这样四个方向就可以使用相同的代码进行处理。
3.2 关卡表示
游戏一共设置了三个关卡。
| 关卡 | 箭头数量 | 难度特点 |
|---|---|---|
| 第一关 | 10 | 主要用于熟悉游戏规则 |
| 第二关 | 14 | 增加箭头数量和阻挡关系 |
| 第三关 | 18 | 增加不同方向之间的交叉阻挡 |
在设计第三关时,我减少了大量相同方向箭头连续出现的情况,否则玩家可以连续点击同一方向的箭头,游戏会比较简单。
同时对关卡进行了测试,保证可以正常完成。
3.3 路径检测
路径检测是游戏中比较重要的一部分。
例如一个向右的箭头:
→ . . . .
程序会沿着箭头的方向,从箭头的下一个位置开始逐格检查。
如果检查到其他箭头:
→ . → . .
说明前方存在阻挡,当前箭头不能移动。
如果一直检查到棋盘边界都没有发现其他箭头:
→ . . . .
则说明当前箭头可以正常移动。
基本思路可以表示为:
dx, dy = direction
x = arrow.x + dx
y = arrow.y + dy
while is_inside_board(x, y):
if has_arrow(x, y):
return False
x += dx
y += dy
return True
这里的 dx 和 dy 表示箭头的方向。
程序从当前箭头的下一个位置开始,一直沿箭头方向检查,直到棋盘边界。
最终:
True → 没有阻挡,可以移动
False → 存在阻挡,不能移动
这样可以同时处理向上、向下、向左和向右四种情况。
3.4 碰撞处理
如果路径检测发现箭头前方存在阻挡,就不会直接删除箭头,而是进入碰撞动画。
大致过程为:
点击箭头
↓
检测到阻挡
↓
箭头向前移动
↓
发生碰撞
↓
变红、震动
↓
返回原位置
↓
失误次数 - 1
在动画播放期间暂时限制其他操作,避免多个动画同时进行导致游戏状态混乱。
另外,在最后一次失误时,也会先播放完整的碰撞动画,然后再进入失败界面。
4. AIGC 使用过程
本次开发过程中,我使用 ChatGPT 辅助进行代码分析、Bug 排查和功能设计。
4.1 第一次:解决字体问题
遇到的问题
使用 Pygame 的字体功能时出现了字体初始化相关的问题。
我的提问
游戏页面文字无法正确加载,应该如何解决?
AI 的帮助
ChatGPT 分析了 Pygame 字体初始化以及 Windows 字体环境可能存在的问题,并修改了字体加载方式,最终游戏能够正常启动并显示文字。
4.2 第二次:调整关卡难度
遇到的问题
最开始设计第三关时,相同方向的箭头比较多,玩家容易连续点击,导致第三关难度比较低。
同时需要保证关卡不能出现无解的情况。
我的提问
如何调整第三关的箭头方向和位置,让游戏更有难度,同时保证关卡可以正常通关?
AI 的帮助
ChatGPT 建议:
- 减少同方向箭头连续排列;
- 增加不同方向之间的阻挡关系;
- 增加箭头数量;
- 检查完整的消除顺序。
并重新调整了三个关卡,其中第三关重点增加了不同方向箭头之间的交叉阻挡关系。
经过测试后,三个关卡都可以正常完成。
4.3 第三次:增加碰撞动画
遇到的问题
最初点击被阻挡箭头时,箭头只是无法移动,玩家不容易知道为什么点击失败。
我的提问
如何让被阻挡的箭头看起来像撞到前面的箭头,然后弹回来?
AI 的帮助
ChatGPT 建议将动画分成:
向前移动
→
碰撞
→
震动、变红
→
返回原位置
并根据这个思路修改了程序。
在实际运行后发现,最开始的移动距离太短,看起来不像真的发生了碰撞,因此又根据实际效果调整了动画距离。
最终实现了比较明显的碰撞效果。
5. 测试结果
本次测试主要采用手工测试的方式进行,针对游戏中的箭头移动、路径检测、关卡切换、失误次数以及重新开始功能进行测试。测试过程中按照老师要求完成 T01~T06 六项测试,并记录预期结果和实际结果。
| 编号 | 测试内容 | 预期结果 | 实际结果 | 是否通过 |
|---|---|---|---|---|
| T01 | 点击前方无阻挡的箭头 | 箭头飞出棋盘并消失 | 点击前方没有其他箭头的箭头后,箭头沿指定方向飞出棋盘并从棋盘中消失 | 通过 |
| T02 | 点击前方有阻挡的箭头 | 箭头不消失,失误次数减 1 | 点击被其他箭头阻挡的箭头后,箭头发生碰撞并返回原位置,同时失误次数减 1 | 通过 |
| T03 | 点击位于边缘且朝向棋盘外的箭头 | 箭头正常消失,不发生越界错误 | 点击位于棋盘边缘且方向朝外的箭头后,箭头正常飞出并消失,程序没有出现越界报错 | 通过 |
| T04 | 消除本关全部箭头 | 显示通关并进入下一关 | 当前关卡所有箭头消除后,显示通关效果并进入下一关 | 通过 |
| T05 | 失误次数耗尽 | 显示失败并允许重新开始 | 失误次数减少到 0 后,游戏显示失败界面,并可以重新开始游戏 | 通过 |
| T06 | 游戏进行中重新开始 | 箭头布局和失误次数恢复 | 游戏过程中重新开始后,箭头重新生成,失误次数恢复到初始值 | 通过 |
6. PSP 表格
本次项目使用 PSP 表格记录各个阶段的预计耗时和实际耗时。
| 任务 | 预计耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 1.0 | 1.5 | +0.5 |
| Python 与图形库学习 | 1.5 | 2.0 | +0.5 |
| 游戏界面实现 | 2.0 | 2.0 | 0 |
| 路径与碰撞逻辑实现 | 3.0 | 4.0 | +1.0 |
| 关卡设计 | 2.0 | 2.5 | +0.5 |
| AIGC 辅助开发 | 2.0 | 2.5 | +0.5 |
| 测试与修改 | 2.0 | 3.0 | +1.0 |
| README 与博客撰写 | 1.5 | 2.0 | +0.5 |
| 合计 | 15.0 | 19.5 | +4.5 |
从 PSP 表格可以看出,实际耗时比预计时间多了一些。
主要是因为开发过程中遇到了路径检测、关卡设计、碰撞动画以及最后一次失误导致游戏状态异常等问题,因此测试和修改花费的时间比原计划更多。
通过记录 PSP,我也发现自己之前对于测试和 Bug 修改所需要的时间估计得比较少。
7. 心得体会
通过这次“一箭又一箭”小游戏的开发,我对 Python 和 Pygame 有了更加具体的认识。
刚开始时,我认为这个游戏的主要难点只是画出箭头并让箭头移动。真正开始开发后才发现,比较复杂的地方其实是箭头之间的路径判断以及各种游戏状态的处理。
其中让我印象比较深的是路径检测。程序需要根据箭头的方向,一格一格检查前方的位置,而不能简单地判断附近有没有其他箭头。通过这个过程,我对坐标、方向和碰撞判断有了更加直观的理解。
AIGC 在这次开发中也给了我比较大的帮助。我主要使用 ChatGPT 来分析报错、寻找 Bug 原因以及设计一些功能。例如字体问题、第三关难度调整、碰撞动画以及最后一次失误导致的游戏卡住问题,都通过 AI 得到了一些解决思路。
不过在使用过程中我也发现,AI 给出的代码不一定可以直接使用。即使代码看起来没有问题,放到自己的程序中也可能出现新的错误。因此使用 AI 后仍然需要不断运行、测试和修改。
这次作业让我认识到,软件开发并不是把代码写完就结束了,还需要不断进行测试和修改。特别是一些边界情况,例如最后一次失误,如果没有实际测试,很难发现程序可能会出现卡住的问题。
通过这次项目,我不仅学习了 Pygame 的基本使用,也了解了路径检测、碰撞处理、动画和游戏状态控制等内容。同时也体会到了 AIGC 在软件开发中的作用。
总体来说,这次作业让我对软件开发的完整过程有了更加直观的认识,也提高了我自己分析问题和调试程序的能力。

浙公网安备 33010602011771号