2026秋软件工程第二次个人作业—— 一箭又一箭

项目 内容
这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/202601SofwareEngineering
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/202601SofwareEngineering/homework/16717
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102401403
GitHub 仓库 https://github.com/pyyy123/arrow-game

一、项目展示

1. 开始界面

dream_start

2. 游戏过程

游戏界面

演示 GIF:demo.gif

3. 失败界面

失败界面

4. 通关界面

通关界面

二、项目介绍

游戏规则

棋盘上分布着朝向上、下、左、右四个方向的箭头。玩家点击某个箭头后:

  • 如果箭头前进方向上没有其他箭头阻挡,它会飞出棋盘并被消除;
  • 如果路径上有其他箭头,它不会消失,并会晃动并变色作为碰撞反馈;
  • 每次点击被阻挡的箭头消耗一次失误机会;
  • 清空本关全部箭头即可通关,失误耗尽则失败。

界面设计

游戏包含三种界面状态:

  • 开始界面:标题、玩法说明、开始按钮;
  • 游戏界面:顶部 HUD(关卡、剩余箭头、剩余失误)、棋盘、重新开始按钮;
  • 通关/失败界面:半透明遮罩 + 结果文字 + 操作按钮。

主题为“梦境”,背景为淡紫色,配有云朵和梦境精灵装饰,箭头带有柔光效果。

主要功能

  • 四种方向箭头;
  • 鼠标点击交互;
  • 路径阻挡检测;
  • 飞出动画与碰撞晃动反馈;
  • 失误次数机制;
  • 3 个可通关关卡;
  • 通关、失败、重新开始、下一关。

三、实现思路

1. 箭头、方向的表示

用一个二维列表 grid 表示棋盘,每个格子的值是整数:

  • 0 表示空;
  • 1/2/3/4 分别表示上、下、左、右。

方向到行列增量的映射:

DIR_VEC = {
    UP:    (-1, 0),
    DOWN:  ( 1, 0),
    LEFT:  ( 0, -1),
    RIGHT: ( 0, 1),
}

这样在路径检测时只需要按方向累加即可,不需要为四个方向分别写四套循环。

2. 关卡表示

每个关卡是一个字典,包含 name、mistakes 和 grid:

"level_1": {
    "name": "第1关:5x5 简单",
    "mistakes": 5,
    "grid": [
        [0, 0, 1, 0, 0],
        ...
    ],
}

LEVEL_ORDER 控制关卡顺序,方便后续扩展。

3. 路径检测(重点)

核心函数 is_blocked(row, col):

def is_blocked(self, row, col):
    direction = self.grid[row][col]
    dr, dc = DIR_VEC[direction]
    r, c = row + dr, col + dc
    while 0 <= r < self.rows and 0 <= c < self.cols:
        if self.grid[r][c] != 0:
            return True
        r += dr
        c += dc
    return False

从当前格子出发,沿方向逐步前进,只要在棋盘内且遇到非空格子就返回 True;走出棋盘则返回 False。这样同时处理了“被挡住”和“边缘飞出”两种情况,不需要额外判断边界。

4. 飞出动画与碰撞反馈

飞出:点击无阻挡箭头后,把 (row, col) 加入 animating_cells,并创建 FlyAnimation。动画期间 grid 仍保留该箭头,动画结束后再置 0。这样 count_arrows() 在动画期间不会误判通关。

碰撞:点击被阻挡箭头时,把 (row, col) 加入 bad_effects,绘制时根据剩余时间做水平晃动并变色。

四、AIGC 使用过程

开发过程中我主要使用 ChatGPT 和 DeepSeek 辅助开发,下面记录 3 次有代表性的过程。

记录 1:飞出动画优化(ChatGPT)

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
飞出动画 ChatGPT 分析缓动与 alpha 曲线,给出优化建议 指出 alpha 线性衰减过早、距离与 alpha 缓动不一致 未采纳 alpha 曲线建议,保留线性 alpha,仅参考了写法建议

我向 ChatGPT 展示了 FlyAnimation.draw 的代码,并问了三个问题:

  1. 飞出动画能否更自然?
  2. 渐隐 alpha 会不会在飞出距离长时提前变透明?
  3. 有没有更简洁或更流畅的写法?

ChatGPT 指出:距离用了 ease-out cubic,但 alpha 是线性的,视觉上会出现“先冲后飘”的割裂感;而且 alpha = 255 * (1 - p) 在 p=0.5 时已经降到 128,对 560px 的飞行距离来说太早淡出。

它建议:

  • 距离用 ease-out quad 1 - (1-p)**2
  • alpha 也加缓动,例如 alpha = 255 * (1 - p**2)alpha = 255 * clamp((1-p)/0.4, 0, 1)
  • 可选加缩放增强纵深;
  • convert_alpha()Vector2 位移、rect.move 等优化写法。

我评估后没有采纳 alpha 曲线的建议,因为本游戏的飞出动画时长只有 0.28 秒,线性 alpha 在实际观感中已经足够自然,换成曲线反而会让前段过亮、后段过暗。我最终保留了原有的 alpha = int(255 * (1 - progress)) 写法,没有改动这段代码。

屏幕截图 2026-09-18 135634

屏幕截图 2026-09-18 135655

记录 2:路径检测边界分析与飞出逻辑(ChatGPT)

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
路径检测 ChatGPT 补充边界测试用例,分析飞出期间 grid 未清空的问题 指出动画期间其他箭头仍会把它算作阻挡物 评估后保留原方案,并加注释说明

我让 ChatGPT 为 is_blocked 补充边界测试用例,包括:

  1. (0,0) 位置朝上(越界判断);
  2. 两个箭头背对背,互不阻挡;
  3. 空 grid 上的行为;
  4. 同一行/列多个箭头。

ChatGPT 给出了详细分析:

  • 边界安全is_blocked 不会数组越界,因为 r 一旦越界,while 条件立刻不成立;
  • 不会把自己算作阻挡:检测起点是 row + dr, col + dc,不是 (row, col)
  • 关键发现:代码无法区分「静止箭头」和「正在飞出的箭头」。如果飞出动画开始后 grid 里还保留着 1–4,其他箭头会把它算作阻挡物。

它建议:如果游戏规则是“箭头一旦开始飞出就不再阻挡其他箭头”,应该在启动飞行动画时立刻把原格清空:

self.grid[row][col] = 0

我评估后认为,本游戏的设计是“飞出动画期间箭头仍占位”——这样视觉上箭头还没飞出棋盘,其他箭头就仍应把它当阻挡物。如果按 AI 建议立刻清空 grid,会导致动画期间路径检测结果和视觉不一致。

因此我保留了自己原有的方案:用animating_cells标记正在飞出的格子,动画结束才在update里把 grid置 0。这段逻辑最终没有改动。

屏幕截图 2026-09-18 140326

屏幕截图 2026-09-18 140354

屏幕截图 2026-09-18 140510

记录 3:README 模板与撰写(DeepSeek)

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
README 撰写 DeepSeek 生成完整的 README 结构模板 框架清晰,但内容偏通用,与项目实际不符 逐节替换为实际内容,修正 6 处不符

我向 DeepSeek 提问:“帮我写一份 Pygame 项目的 README 模板,项目是一个点击式箭头解谜小游戏,名叫‘一箭又一箭’。”DeepSeek 给出了一份结构清晰的 Markdown 模板,包含项目名称、游戏简介、开发环境、安装运行、操作说明、截图、项目结构、关卡说明、素材来源等章节。

模板的框架是可用的,但内容偏通用,我逐节对照实际项目进行了修改:

  1. 游戏简介:DeepSeek 写的是“改变箭头方向或触发连锁反应”,与我的实际玩法(点击后路径无阻挡则飞出)不符,我改写为真实规则;
  2. 开发环境:DeepSeek 写的是 Python 3.8+Pygame 2.1+,我按实际写了 Python 3.10+pygame
  3. 安装运行:DeepSeek 写的是 git clone https://github.com/yourname/one-arrow-after-another.git,我替换为实际仓库地址,运行命令改成 python main_fixed.py
  4. 操作说明:DeepSeek 额外写了 ESC 退出、R 重新开始,但我的项目只支持鼠标点击,没有键盘快捷键,我删掉了这两条;
  5. 项目结构:DeepSeek 假设有 scenes/assets/levels/level1.py 等目录,与实际不符,我按实际文件列表重写;
  6. 关卡说明:DeepSeek 写的是“连锁反应”“终极考验”等玩法,与实际关卡机制不符,我改为按尺寸和失误次数说明;
  7. 素材来源:DeepSeek 写了 KenneyOpenGameArtFreesoundGoogle Fonts,但我的项目所有图形均由 Pygame 绘制,未使用外部素材,我改为真实来源。

最终 README 在 GitHub 上显示正常,助教可按说明直接运行。

屏幕截图 2026-09-22 105049

readme

五、测试结果

5.1 路径检测逻辑测试(tests/test_logic.py

编号 测试内容 预期结果 实际结果 是否通过
T01 前方无阻挡 is_blocked 返回 False 与预期一致
T02 前方有阻挡 is_blocked 返回 True 与预期一致
T03 边缘箭头朝外 正常飞出,不越界 与预期一致
T04 四个方向检测 全部返回 False 与预期一致
T05 左边缘朝左 不越界 与预期一致
T06 背对背箭头 互不阻挡 与预期一致
T07 空格子 不可点 与预期一致
T08 同一行多箭头 最近阻挡生效 与预期一致
T09 顶部朝上 不越界 与预期一致

5.2 游戏功能手工测试

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失 与预期一致
T02 点击前方有阻挡的箭头 箭头不消失,失误次数减 1 与预期一致
T03 点击位于边缘且朝向棋盘外的箭头 箭头正常消失,不发生越界错误 与预期一致
T04 消除本关全部箭头 显示通关并进入下一关 与预期一致
T05 失误次数耗尽 显示失败并允许重新开始 与预期一致
T06 游戏进行中重新开始 箭头布局和失误次数恢复 与预期一致

5.3 关卡可通关性验证

运行 python verify_levels.py,三关均输出“有解”,分别需要 8、13、19 步。

屏幕截图 2026-09-22 141926

屏幕截图 2026-09-22 142102

六、PSP 表格

任务 预估耗时(小时) 实际耗时(小时) 差异(小时)
需求分析与游戏设计 1.0 1.5 +0.5
Python 与图形库学习 2.0 2.5 +0.5
游戏界面实现 2.0 2.0 0
路径与碰撞逻辑实现 2.0 3.0 +1.0
关卡设计 1.0 1.5 +0.5
AIGC 辅助开发 2.0 2.0 0
测试与修改 1.5 2.0 +0.5
README 与博客撰写 2.0 2.5 +0.5
合计 13.5 17.0 +3.5

七、心得体会

这次作业让我第一次比较系统地用 AIGC 工具参与一个小型项目的完整开发。最大的感受是:AI 能大幅提高起手速度,但不能替代自己理解代码。

具体来说:

1.AI 擅长给结构和模板。 比如界面布局、按钮类、状态机这些“套路化”的部分,ChatGPT 给得很快,我只需要按自己的主题调整颜色和文字;README 模板 DeepSeek 也给了很好的框架。

2.AI 在边界条件上容易出错。 路径检测的越界、关卡死锁、动画频率过高,都是 AI 生成后我实际运行才发现的。这让我意识到“能跑”和“跑对”是两回事,必须自己测试。

3.关卡设计不能完全交给 AI。 AI 生成的布局看起来合理,但用 verify_levels.py 一跑就发现死锁。手工调整并试玩是必须的。

4.AIGC 记录要真实。 我在开发过程中确实和 ChatGPT、DeepSeek 来回修改了很多次,博客里记录的这几次是比较有代表性的。

5.AI 给的模板不能照抄。 DeepSeek 的 README 模板看起来齐全,但里面写的素材来源、项目结构、操作说明和我的项目完全不符,必须逐条对照修改。

6.不采纳 AI 的建议也是一种判断。 比如飞出动画的 alpha 曲线、路径检测的 grid 清空方案,我评估后都保留了原写法,因为原来的设计更符合本游戏的实际需求。

总的来说,这次作业让我对“人机协作开发”有了更具体的认识:AI 是加速器,但方向盘和刹车必须自己握。

posted @ 2026-09-22 14:42  pyue  阅读(13)  评论(0)    收藏  举报