软件工程个人作业2:一箭又一箭小游戏开发

软件工程个人作业2:一箭又一箭小游戏开发

一、作业基础信息

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

二、项目展示

本次开发的“一箭又一箭”小游戏使用 Python + Pygame 实现,拥有完整的开始界面、游戏主界面、通关界面、失败界面,支持多关卡切换、失误判定、碰撞反馈、重新开始功能。
运行gif:
运行

开始界面:
开始界面

游戏对局界面:
游戏界面

通关界面:
通关界面

失败碰撞界面:

失败碰撞界面

三、项目介绍

1. 游戏规则

棋盘上分布着朝上(U)、下(D)、左(L)、右(R)四个方向的箭头。玩家点击一个箭头后,程序检测其前进方向上的路径:

  • 若箭头与棋盘边界之间没有其他箭头,箭头飞出棋盘并被消除,播放点击音效;
  • 若路径上存在其他箭头,箭头不能被消除,并通过晃动、变红和“前方有阻挡!”文字给出碰撞反馈,同时消耗 1 次失误机会,播放错误音效;
  • 每关共有 3 次失误机会;清空本关全部箭头即通关并进入下一关;失误次数耗尽则本关失败,可重新开始。
  • 路径判定采用网格单格箭头:只需判断同一行(左右箭头)或同一列(上下箭头)、箭头与边界之间是否还有其他箭头。

2. 界面与功能特色

  • 完整三级界面:开始页 → 游戏页 → 通关/失败结果页;
  • 实时显示:当前关卡、剩余箭头数、剩余失误次数(心形UI)、计时;
  • 动态反馈:箭头飞出有透明渐变和位移动画,碰撞有抖动和变色反馈;
  • 内置关卡:设计了 5 个满格可通关合法关卡,布局合理、无死锁;
  • 多素材集成:主菜单和游戏内加入了背景图片,游戏全程配有背景音乐(BGM)和交互音效。

四、实现思路与核心原理

4.1 箭头和方向怎么表示

方向用四个字符常量 U D L R,每个方向对应一组「行增量、列增量」:

DIRECTIONS = {
    'U': (-1, 0),   # 上
    'D': (1, 0),    # 下
    'L': (0, -1),   # 左
    'R': (0, 1),    # 右
}

这里有个容易搞反的地方:屏幕坐标系里 y 轴是向下的,所以第 0 行在最上面,"向上" 是行号减一。我一开始把 U 写成 (1, 0),结果所有上下箭头的路径检测都反了,直到实际试玩时才发现"明明朝上的箭头点了说被挡"。

棋盘用二维列表存储:board[r][c] 存放方向字符或 None(空格)。选二维列表而不是字典,是因为棋盘是稠密矩形网格,按坐标直接索引 O(1)。

4.2 路径检测(核心)

这是整个程序最关键的一段。做法是从箭头的下一个格子开始,沿它指的方向一格一格往外走:

def is_blocked(self, row, col):
    d = self.board[row][col]
    if d is None: return False
    dr, dc = DIRECTIONS[d]
    n = len(self.board)
    r, c = row + dr, col + dc
    while 0 <= r < n and 0 <= c < n:
        if self.board[r][c] is not None:
            return True  # 碰到箭头 -> 被挡住
        r += dr
        c += dc
    return False  # 走出棋盘了 -> 可以飞出

几个关键点:
从下一格开始,不检测箭头自身所在的格子;
只沿方向向量走(同行或同列),不会跨行误判;
遇到边界自动停止,0 <= r < n 兜底,不会数组越界;
返回纯布尔值,调用方根据结果决定是消除还是扣失误,逻辑和界面完全解耦。

4.3 关卡设计:如何保证满格且有解

为了增加游戏画面饱满度和挑战性,我设计了 5 个满格(每个格子都有箭头)的关卡。
设计思路采用了两种必定有解的策略:
整行/整列同向(第 1-4 关):例如第一行全是 U,第二行全是 R。玩家只需按行或列的顺序依次点击,总能全部飞出。
螺旋矩阵(第 5 关):从最外圈开始,按顺时针方向 R -> D -> L -> U 排列,一层层往里清,最后清空中心点。这种设计在逻辑上保证了绝对有解,不会出现死锁。

4.4 音效与背景图集成

为了提升游戏体验,我在 assets 文件夹中引入了背景图与音频。在 Pygame 中,音频和图片的加载需要容错处理,否则文件缺失会导致游戏直接崩溃:

def load_audio(filename):
    path = os.path.join(ASSETS_DIR, filename)
    if os.path.exists(path):
        try:
            return pygame.mixer.Sound(path)
        except pygame.error:
            print(f"无法加载音频: {path}")
    return None

游戏通过 pygame.mixer.music.play(-1) 实现背景音乐的循环播放。

五、AIGC 辅助开发过程(3次真实记录)

本作业使用 AIGC 工具(DeepSeek)辅助开发。以下是 3 次具有代表性的协作过程:

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
环境搭建 DeepSeek 给出安装 pygame 的命令和 VS Code 配置指导 电脑存在多个 Python 版本,pip 安装到了 3.11 而 VS Code 使用的是 3.12,导致报错 使用绝对路径 "C:\...\python.exe" -m pip install pygame 重新安装,并切换 VS Code 解释器解决
字体与资源加载 DeepSeek 生成 SysFont 加载字体及图片音频加载代码 运行时报 TypeError: expected str, bytes or os.PathLike object, not int,且图片音频死活加载不出来 改用 pygame.font.Font('C:/Windows/Fonts/msyh.ttc', size) 绕过兼容性 bug;排查发现 Windows 隐藏了文件扩展名(变成 .png.jpg),手动重命名后正常
满格关卡设计 DeepSeek 生成满格关卡数组与死锁检测思路 初版生成的关卡存在同行/同列互堵死锁,且每个格子都必须填满,难度失衡 采用“整行/整列同向”与“螺旋矩阵”结构重新设计,人工推演验证确保 5 关绝对有解

记录 1:环境搭建与依赖冲突(Python 版本冲突)

  • 提出的要求:如何在 Windows 上为 Python 项目正确安装 pygame 并在 VS Code 中运行?
  • AI 完成的工作:给出了基础的 pip install pygame 命令,以及 VS Code 选择解释器的步骤。
  • 实际效果与问题:电脑中存在 Python 3.11 和 3.12 两个版本。在 CMD 中执行 pip install 默认安装到了 3.11,但 VS Code 默认使用的是 3.12。导致 VS Code 运行时报 ModuleNotFoundError: No module named 'pygame'
  • 人工修改:通过绝对路径强制为 3.12 安装:"C:\Users\...\Python312\python.exe" -m pip install pygame,并在 VS Code 中手动切换解释器版本,最终解决了环境问题。

记录 2:字体加载报错与资源路径排查(隐蔽陷阱)

  • 提出的要求:给游戏加上中文文字、背景图片和背景音乐。
  • AI 完成的工作:生成了 pygame.font.SysFont 以及 pygame.image.loadpygame.mixer.Sound 的资源加载代码。
  • 实际效果与问题:运行后游戏直接崩溃,报错 TypeError: expected str, bytes or os.PathLike object, not int。此外,图片和音频一直加载失败,但在电脑文件夹里明明能看到文件。
  • 人工修改:① 发现是 SysFont 的底层兼容性 bug,果断改用 pygame.font.Font('C:/Windows/Fonts/msyh.ttc', size) 直接加载系统字体;② 排查发现是 Windows 默认隐藏了文件扩展名,我的文件实际是 bg_menu.png.jpg,手动开启扩展名显示并重命名后,图片和音乐终于成功加载。

记录 3:满格关卡设计(可解性验证)

  • 提出的要求:把游戏扩充到 5 个关卡,保证每个格子都有箭头,且关卡要有解。
  • AI 完成的工作:生成了多个满格关卡的二维数组,并提示可以用贪心思路验证。
  • 实际效果与问题:AI 随机生成的满格关卡中,出现了同一行 L...R 或者同一列 U...D 互堵死锁的情况,导致关卡根本无解。
  • 人工修改:采用“整行同向”和“螺旋矩阵”的数学结构手动重写了 5 个关卡的数据。例如第五关从外圈顺时针排列,一层层向内清空,从逻辑上确保了绝对不会死锁。

六、项目测试结果

测试环境:Windows + Python 3.12.4 + Pygame 2.6.1
测试方式:手工测试与试玩验证

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失,播放音效 箭头飞出,剩余数量减少,音效正常 ✅ 通过
T02 点击前方有阻挡的箭头 箭头不消失,失误次数减 1,有抖动反馈 箭头抖动变红,失误 3→2,播放错误音效 ✅ 通过
T03 点击位于边缘且朝向棋盘外的箭头 箭头正常消失,不发生越界错误 上下左右及角落箭头均正常飞出,无报错 ✅ 通过
T04 消除本关全部箭头 显示通关并进入下一关 进入结算页面,点击继续进入下一关 ✅ 通过
T05 失误次数耗尽 显示失败并允许重新开始 进入失败界面,点击重新开始恢复当前关 ✅ 通过
T06 游戏进行中重新开始 箭头布局和失误次数恢复 布局、失误次数、飞行动画均重置为初始状态 ✅ 通过
附加 5个满格关卡可解性验证 每关都存在通关顺序 人工推演试玩,5关全部可正常通关 ✅ 通过

测试小结:共 6 项核心测试及附加测试全部通过。测试不仅验证了需求,还真实暴露了开发中的多个 Bug(环境冲突、字体加载、隐藏扩展名、关卡死锁),体现了“先写用例、再验证”的价值。

七、PSP 个人软件开发过程量表

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

八、心得体会

AI 带来的帮助:AIGC 把“从零搭框架”变成了“在草稿上修改”。路径检测、动画逻辑、资源加载这些成熟模式,AI 能一次性给出可用版本,让我把精力集中在真正需要判断的地方——边界条件、关卡可解性、交互细节。

出现的问题:AI 生成代码最大的风险是“看起来对、实际错”。本次 AI 的路径检测方向向量写错、关卡出现互堵死锁、SysFont 字体兼容性报错,都是只靠肉眼检查发现不了的。特别是在配置环境时,因为电脑装了两个 Python 版本,绕了很大的弯路。这提醒我:AI 是“高效的草稿生成器”,不是“可靠的代码评审员”,把 AI 代码直接当正确答案是最危险的用法。

我的收获:一是真正理解了本游戏路径检测与“互堵死锁”的本质,并学会用数学结构(整行同向、螺旋矩阵)去构造必定有解的关卡;二是掌握了“遇到报错先看终端输出、排查文件扩展名、使用绝对路径”的工程排错习惯;三是对 AI 协作有了更理性的定位——提问要具体,验证要独立(测试、试玩),修改要敢下手。这次查错让我亲身体会到,AI 修改过的代码必须回归测试,环境配置必须锱铢必较。

posted @ 2026-09-18 20:30  zzzoeq  阅读(3)  评论(0)    收藏  举报