第二次作业

第二次作业

项目 内容
这个作业属于哪个课程 H202601软件工程与软件工程实践
这个作业要求在哪里 2026 秋软件工程个人作业(第二次) - 作业
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102401217
GitHub 仓库 https://github.com/Emrys-m/arrow-game

项目展示

开始界面
游戏开始界面
游戏进行
游戏进行
通关
通关

项目介绍

一、## 游戏规则

一、基本玩法

  1. 棋盘中分布着若干带有方向的箭头,方向分为上、下、左、右四种。
  2. 玩家用鼠标左键点击任意一个箭头,程序会检查该箭头前进方向(同一行或同一列)上是否有其他箭头阻挡。
  3. 前方无阻挡:箭头会以加速拖尾动画飞出棋盘并消失,剩余箭头数减 1,同时获得 +10 分
  4. 前方有阻挡:箭头会变红并向前碰撞弹回,无法消除,失误次数 +1,并且 分数 -5(最低扣至 0 分)。

二、胜负条件

  • 通关:消除本关全部箭头后,显示通关结算面板,并自动进入下一关。
  • 失败:失误次数累计达到 3 次 时,本关失败,显示失败结算面板,可点击重新挑战。
  • 游戏共设 5 个关卡,难度逐级递增。

三、得分与星级

  • 得分规则
    • 成功消除一个箭头:+10 分
    • 发生碰撞失误:-5 分(最低为 0 分)
    • 通关奖励:+50 分
  • 星级评价(仅通关时结算):
    • 3 星:0 次失误通关
    • 2 星:1 次失误通关
    • 1 星:2 次失误通关
    • 失败则为 0 星
  • 所有关卡获得的星级会累计显示在开始界面,重新开始整个游戏时归零。

四、撤销功能

  • 每关可使用 1 次撤销,用于回退到上一次操作之前的状态(包括箭头布局、得分和失误次数)。
  • 无论上一次操作是成功消除还是碰撞失误,均可撤销。
  • 使用后撤销按钮变为灰色,不可再次使用;重新开始本关或进入下一关时重置为可用状态。
  • 也可以按键盘 Z 键 快速触发撤销。

五、计时系统

  • 从进入关卡开始计时,仅在游戏进行中累加。
  • 通关或失败时,结算面板会显示本局用时。

六、其他操作

  • 重新开始:点击游戏界面右上角的“重新开始”按钮,当前关卡恢复到初始布局,分数和计时清零。
  • 开始游戏:在开始界面点击“开始游戏”按钮,或按空格键。

实现思路

一、游戏数据的表示
方向表示:采用字符 'U'、'D'、'L'、'R' 分别代表上、下、左、右四个方向,方便在代码中进行方向判断和后续计算。

箭头与棋盘表示:游戏棋盘是一个 5×5 的二维列表 grid。每个格子对应列表中的一个元素:

None 表示该格子为空。

字符(如 'R')表示该格子上存在一个朝该方向的箭头。
例如:grid[0][1] = 'R' 表示第 0 行第 1 列有一个向右的箭头。

关卡表示:所有关卡数据存放在 LEVELS 列表中,每个关卡都是一个 5×5 的二维列表。切换关卡时,只需根据索引加载对应的二维列表,并深拷贝一份到游戏主棋盘中,确保原始关卡数据不会被修改。

二、路径检测方法(核心逻辑)
路径检测是游戏中最核心的算法。玩家点击一个箭头后,程序需要沿着箭头所指方向逐格检查,判断其与棋盘边界之间是否有其他箭头阻挡。

实现方法:
根据箭头的方向,使用 for 循环沿着行或列进行遍历:

向右 ('R'):从 col + 1 遍历到 COLS - 1,检查 grid[row][c] 是否为 None。

向左 ('L'):从 col - 1 遍历到 0。

向上 ('U'):从 row - 1 遍历到 0,检查 grid[r][col] 是否为 None。

向下 ('D'):从 row + 1 遍历到 ROWS - 1。

如果遍历过程中遇到任意一个非 None 的格子,说明前方有箭头阻挡,立即返回 False;如果遍历结束都没有遇到阻挡,则返回 True,表示该箭头可以飞出棋盘。

边界处理技巧:
利用 Python range 函数的特性,例如 range(col - 1, -1, -1) 在 col = 0 时会自动不执行循环,无需额外编写复杂的边界判断代码,有效避免了数组越界错误。

三、游戏状态与动画实现
状态机:使用 self.state 变量管理四种游戏状态:START(开始)、PLAYING(游戏中)、WIN(通关)、LOSE(失败),不同状态下绘制不同的界面并响应不同的事件。

飞出动画:创建 FlyingArrow 类,记录箭头初始坐标和方向。每帧更新坐标,并利用加速算法(self.speed += 1.2)模拟弹射感。同时使用一个固定长度的列表记录历史坐标,绘制出“拖尾残影”效果。

碰撞弹回动画:创建 BumpingArrow 类,记录起点、方向以及碰撞前的最大移动距离。动画分为“去程”和“回程”两个阶段,向前冲出一段距离后,模拟物理弹回,速度反向并增加 1.5 倍,回到起点后标记动画结束,恢复静止的箭头。

AIGC使用过程

AIGC调用过程1

AIGC调用过程2

AIGC调用过程3

AIGC 使用过程记录

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
飞行动画 DeepSeek 给箭头飞行增加了拖尾残影效果 基本可用 调整拖尾颜色
开始界面 DeepSeek 生成开始界面 基本可用 调整页面样式
代码git提交 DeepSeek 提供将代码通过Git bash上传到GitHub上的方法 基本可用 修改了Git的安装路径

📝 详细过程说明

1. 路径检测与边界处理(核心算法)

  • 提出要求:我向 AI 描述了“一箭又一箭”的基础玩法,要求它帮我写出判断箭头前方是否有阻挡的代码,要求支持上下左右四个方向。
  • AI 实现:AI 给出了一个 is_path_clear 函数,遍历箭头前方格子。
  • 实际效果与修改:直接运行后发现向上判断时如果箭头在最顶端(第 0 行)会出现索引越界的隐患。在 AI 的提示下,我明白了 Python 中 range(row - 1, -1, -1)row=0 时天然为空,随后根据这个特性精简了代码,彻底修复了越界 Bug。

2. 碰撞与飞行动画(视觉反馈升级)

  • 提出要求:起初游戏点击被阻挡的箭头只会“在原位抖动”,我向 AI 提出想要那种“向前冲一下然后被撞回来”的物理反馈,并且让飞出的箭头更生动。
  • AI 实现:AI 为我设计了 BumpingArrow 类(去程和回程状态切换)和 FlyingArrow 类(速度递增与拖尾残影数组)。
  • 实际效果与修改:效果非常震撼!但我发现弹回速度太快像瞬移,拖尾颜色太亮遮挡视野。于是我自己调整了参数:把弹回速度从 2.0 降到 1.5 倍,把拖尾颜色透明度降低,让动画更加自然顺滑。

3. 深色 UI 与视觉主题(体验优化)

  • 提出要求:最初的界面是白底黑字,像简陋的 PPT,我要求 AI 帮我把它改成“深色、不单调、有活力”的风格。
  • AI 实现:AI 提供了深色背景配色方案(深午夜蓝),引入了发光效果(glow_surf)、圆角格子卡片和霓虹青色(NEON_BLUE)箭头。
  • 实际效果与修改:整体质感瞬间提升。不过默认的箭头是普通三角形,我觉得不够犀利,于是自己动手把绘制顶点从 3 个改成了 4 个(尾部内凹),变成了飞镖造型。

测试结果

测试结果
在游戏开发完成后,我对照作业要求,对本程序进行了系统的手工测试,具体测试项目和结果如下:

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失 箭头带着拖尾动画加速飞出屏幕并消失,剩余箭头数减 1 通过
T02 点击前方有阻挡的箭头 箭头不消失,失误次数减 1 箭头变为红色并向前碰撞弹回,失误次数 +1,箭头仍保留在原位 通过
T03 点击位于边缘且朝向棋盘外的箭头 箭头正常消失,不发生越界错误 箭头正常飞出屏幕并消失,程序无报错 通过
T04 消除本关全部箭头 显示通关并进入下一关 界面出现绿色“通关!”提示,点击后自动加载下一关 通过
T05 失误次数耗尽 显示失败并允许重新开始 界面出现红色“失败!”提示,点击后当前关卡重置 通过
T06 游戏进行中重新开始 箭头布局和失误次数恢复 点击“重新开始”按钮,棋盘恢复初始布局,失误次数清零 通过

PSP 表格

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

Python 与图形库学习(+0.5):虽然已有 Python 基础语法,但 Pygame 的图形绘制和事件处理需要重新熟悉。加上配置 Git 和 GitHub 时遇到了不少环境问题(如安装路径冲突、Token 认证报错),额外花了时间排查。

AIGC 辅助开发(+0.5):在调试“开始界面被跳过”、“箭头拖尾动画”和“碰撞弹回”时,反复向 AI 描述问题并验证代码,虽然 AI 生成代码很快,但理解并调试依然需要时间。

游戏界面、路径与碰撞、测试与修改(-0.5):得益于 AI 提供的代码框架非常清晰,加上我们逐层递进地实现(先网格、再箭头、再交互),避免了推倒重来。调试阶段只遇到几处小 Bug,修改效率

附加的功能

  1. 关卡数设置为了5关,拥有更多关卡
  2. 在原有基础上增加了得分、计时和星级系统
  3. 增加了撤销功能,每关仅能撤销一次
  4. 打包成可执行文件,在GitHub上下载双击即可运行
    每个功能都是一点一点加上去的,并分成若干次提交到Github上

提交记录

GitHub截图

1. 心得体会

从最初连 Python 基础语法都忘得差不多、连环境配置都磕磕绊绊,到最终完成一个带有完整状态管理、动画反馈和深色主题的“一箭又一箭”小游戏,这个过程让我深刻体会到了 AIGC 辅助开发的强大,也经历了从“盲人摸象”到“豁然开朗”的成长。

一、AI 带来的帮助
跨越了环境配置的“劝退期”:对于小白来说,配置 Python 虚拟环境、安装 Pygame、解决 Git 的 Token 认证报错、处理安装路径冲突,每一步都是煎熬。AI 用清晰的步骤和截图级的排查建议,帮我跨过了这些初期的门槛。

把抽象逻辑具象化:在实现路径检测时,AI 不仅给出了代码,还解释了如何利用 range 函数的边界特性(如 range(col - 1, -1, -1))来天然规避数组越界。碰撞弹回动画、拖尾残影这些我原本觉得很难的效果,AI 也拆解成了“速度递增”、“历史坐标记录”、“状态切换”等易懂的模块,让我真正理解了背后的原理。

高效的调试工具:当出现“开始界面被跳过”、“图片路径不显示”、“弹回动画卡顿”等问题时,AI 能精准指出是代码执行顺序错误还是逻辑遗漏,大大缩短了修 Bug 的时间。

二、出现的问题与反思
AI 并非“一次性完美”:AI 生成的代码有时存在细微的逻辑漏洞,比如 init 里 load_level 覆盖了 START 状态,导致开始界面被跳过;再比如一开始的碰撞反馈只是原地震动,不够生动,需要反复迭代和人工调整。

不能做“甩手掌柜”:如果只是无脑复制粘贴代码,遇到与本地环境不匹配(如 Python 版本、操作系统差异)的情况时,就会完全束手无策。我学会了把报错信息完整丢给 AI,并结合实际运行结果去判断它的建议是否可行。

拆分任务的重要性:一开始看整个游戏代码会觉得庞大,但在 AI 的建议下,我们采用了“先画网格 -> 再画箭头 -> 再加点击检测 -> 再加动画 -> 最后美化 UI”的迭代路径,这种“小步快跑”的开发模式让复杂问题变得可控。

三、个人收获
技术能力的提升:重新熟悉了 Python,掌握了 Pygame 的图形绘制、事件监听、面向对象编程,以及 Git 和 GitHub 的版本管理。

解决问题的信心:从面对几百行代码的茫然,到能够自己定位问题、修改参数、调试运行,对代码的掌控感增强了。

人机协作的思维:我深刻认识到,AI 是一个极佳的“副驾驶”,它能提供思路和代码框架,但最终的决策、理解、试玩验证和审美调整(比如深色主题的配色、按钮悬停效果)依然需要人类的判断。AI 能写出代码,但理解并让代码真正符合需求,还是得靠自己。

posted @ 2026-09-18 21:05  fzuyzh  阅读(6)  评论(0)    收藏  举报