软件工程作业二——完成“一箭又一箭”小游戏

项目 内容
这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice/
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice/homework/16718
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102402121
GitHub 仓库 https://github.com/Rong-hub1/homework

用 AIGC 完成“一箭又一箭”小游戏

一、项目展示

1. 开始界面

深色主题、圆角按钮、装饰箭头环绕的标题页。

[开始界面]
屏幕截图 2026-09-15 195416

2. 游戏界面

顶部显示关卡、剩余箭头、失误心形;中央为棋盘;底部为操作按钮。

[游戏界面]
屏幕截图 2026-09-15 210826

3. 通关界面

覆盖式半透明面板,圆形图标 + 提示文字 + 操作按钮。

[通关界面]
屏幕截图 2026-09-15 210843

4. 失败界面

失误机会耗尽时弹出。

[失败界面]

QQ20260915-211730

演示 GIF:


二、项目介绍

游戏规则

“一箭又一箭”是一款点击式解谜小游戏。棋盘上摆放着朝上、下、左、右四个方向的箭头。玩家点击某一箭头:

  • 若它到棋盘边界之间的路径上没有其他箭头阻挡,则该箭头沿自己的方向飞出棋盘并消失;
  • 若路径上存在其他箭头,则箭头不能飞出,给出明显的碰撞反馈,并扣除一次失误机会;
  • 清空全部箭头即通关;失误机会耗尽即失败。

界面设计

整体采用深色主题(深蓝背景 + 半透明网格 + 顶部光晕),箭头使用三层叠加(阴影 / 主色 / 内高光)形成立体感。鼠标悬停时箭头外围出现淡绿光晕,飞出时变为蓝色,碰撞时变为红色并左右抖动。

主要功能

  • 开始 / 游戏 / 结算三类界面;
  • 四个方向的箭头与路径检测;
  • 点击飞出动画、碰撞抖动反馈;
  • 失误次数(心形图标显示);
  • 3 个可通关关卡、自动进入下一关;
  • 重新开始 / 返回主菜单。

特色

  • 心形失误图标由数学公式绘制(x = 16sin³t, y = -(13cos t - 5cos2t - 2cos3t - cos4t)),未使用的失误显示为空心轮廓;
  • 结算使用覆盖式面板,不需要额外窗口;
  • 关卡名称带有“初出茅庐 / 渐入佳境 / 登峰造极”的渐进感。

三、实现思路

1. 箭头和方向的表示

每个箭头用一个字典表示:

{'row': r, 'col': c, 'dir': d, 'alive': True}

方向与增量通过一张表映射(值为 (行增量 dr, 列增量 dc)**):

DIRS = {'up': (-1, 0), 'down': (1, 0),
        'left': (0, -1), 'right': (0, 1)}

绘制箭头时使用另一个映射表,将方向映射为旋转角度,然后对一个归一化的多边形做旋转,这样任意方向都复用同一套绘制代码:

ARROW_ANGLES = {'right': 0.0, 'down': math.pi/2,
                'left': math.pi, 'up': -math.pi/2}

2. 关卡表示

LEVELS = [
    {'name': '初出茅庐', 'cols': 3, 'rows': 3, 'lives': 3,
     'arrows': [(0,0,'right'), (0,1,'up'), ...]},
    ...
]

每个关卡记录棋盘尺寸、失误次数和箭头列表,切换关卡时直接重新读取即可。

3. 路径检测

从被点击的箭头出发,沿它的方向逐格前进,只要在同一行或同一列上还有其它存活的箭头,就判定为“被阻挡”:

def path_clear(self, a):
    dr, dc = DIRS[a['dir']]
    r, c = a['row'] + dr, a['col'] + dc
    while 0 <= r < self.rows and 0 <= c < self.cols:
        for other in self.arrows:
            if other is a:
                continue
            if other['alive'] and other['row'] == r and other['col'] == c:
                return False
        r += dr
        c += dc
    return True

while 条件同时起到了边界保护的作用——一旦走出去就退出循环,返回 True,因此不会越界。

4. 动画

飞出动画用一个循环逐帧右移/左移/上移/下移箭头,配合颜色切换;碰撞动画则用 ±7px 的左右偏移做抖动,7 帧后恢复。


四、AIGC 使用过程

第 1 次:生成基础游戏框架

我的要求:
“用 Python 做一个‘一箭又一箭’小游戏,要求有开始界面、游戏界面、通关/失败界面,3 个关卡,四个方向的箭头,点击能飞出或被阻挡,有失误次数和重新开始。”

AI 完成:
一次性给出了完整的 Tkinter 实现,包括 LEVELS 数据结构、path_clear() 路径检测、on_click() 点击处理、飞出动画 fly_out()、碰撞反馈 hit_feedback(),以及开始/游戏/结算三类界面切换。

实际效果:
程序可以直接运行,但发现“箭头飞出方向和箭头方向差 90°,箭头飞出方向不对,游戏没有可行解,而且整体视觉比较朴素——纯色块、无阴影、没有悬停反馈。

人工修改:
debug定位到 DIRS常量错误,表被当作 (dr, dc) 使用,但里面填的值实际是 (dc, dr),相当于每个方向都旋转了 90°。给出了修正:

# 错误
DIRS = {'up': (0, -1), 'down': (0, 1),
        'left': (-1, 0), 'right': (1, 0)}

# 正确
DIRS = {'up': (-1, 0), 'down': (1, 0),
        'left': (0, -1), 'right': (0, 1)}

实际效果:
修改后四个方向的飞出和路径检测都正常了。

人工检查:
我逐关检查了一遍,确认每一关的箭头飞出方向和阻挡判断都符合预期,存在可行解。


第 2 次:初步美化界面

我的要求:
“现在的界面太丑了,做得更好看一点。”

AI 完成:
整体重构为深色主题,引入 round_rect() 圆角矩形工具、三层叠加的立体箭头、悬停光晕、覆盖式结算面板、心形失误图标,以及顶部光晕和网格背景。

实际效果:
视觉上确实接近商业小游戏,圆角、阴影、发光都有了。

屏幕截图 2026-09-15 201318


第 3 次:修改与完善

我的要求:
“加计时和评级已经通关胜利特效。”

AI 完成:
无失误:3 星,1 次失误:2 星,≥2 次失误:1 星
计时器:每关从第一次点击开始,或者在关卡加载时立即开始。当关卡完成时,显示用时。
胜利特效:全部通关时,显示烟花/粒子动画。在 canvas 上使用粒子系统。
帧计数器用 self.root.after 来运行,用于计时器。

实际效果:
达到预期

屏幕截图 2026-09-15 210033

小结

子任务 AIGC 工具 AI 提供了什么 效果 人工调整
基础游戏框架 DeepSeek 完整可运行的 Tkinter 实现 可运行,框架正确 更改参数设置
界面美化 DeepSeek 深色主题 + 圆角 + 立体箭头 + 覆盖式面板 视觉大幅提升 无
进一步美化并完善 DeepSeek 添加了计时、评价和特效 全部正常运行,效果更好了 逐关试玩验证

五、测试结果

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失 箭头沿自身方向飞出并消失 debug后 ✅
T02 点击前方有阻挡的箭头 箭头不消失,失误次数减 1 箭头变红并抖动,失误心形减少 1 个 ✅
T03 点击边缘朝外的箭头 箭头正常消失,不越界报错 正常飞出,无异常 ✅
T04 消除本关全部箭头 弹出通关面板,进入下一关 显示“关卡通过”,可进入下一关 ✅
T05 失误次数耗尽 弹出失败面板,可重新开始 显示“关卡失败”,可选重新挑战 ✅
T06 游戏进行中重新开始 箭头布局和失误次数恢复 完全恢复初始状态 ✅

测试方法: 手工测试。每一关按预设的通关顺序逐一点击,观察动画和状态;同时故意点击被阻挡的箭头,验证失误扣除逻辑。


六、PSP 表格

任务 预估耗时(分钟) 实际耗时(分钟) 差异(分钟)
需求分析与游戏设计 5 3 -2
Python 与图形库学习 10 12 +2
游戏界面实现 20 18 -2
路径与碰撞逻辑实现 20 17 -3
关卡设计 10 13 +3
AIGC 辅助开发 10 12 +2
测试与修改 30 40 +10
README 与博客撰写 30 35 +5
合计 130 145 +15

七、心得体会

AI 带来的帮助:
从零到能运行只花了不到一次对话的时间,尤其是路径检测、动画循环这种“套路化”的代码,AI 写得又快又规范,让我可以把精力放在关卡设计和交互体验上。在美术上也有很大帮助。

出现的问题:
AI 在第二次重构时遗留了重复定义的函数,第三次又在方向常量上写反了 (dr, dc)——两个 bug 都不会导致程序崩溃,但都会让功能“看起来对、其实不对”。如果我不运行、不亲自试玩,是发现不了的。

自己的收获:

  1. AI 生成≠AI 负责。 代码进项目后,最终责任人是自己。要看懂、要跑、要测。
  2. 方向常量最好只定义一次。 如果把 DIRS 和 ARROW_ANGLES 合并成一张表,就不会出现两处不一致的问题。
  3. 视觉美化要留时间回归测试。 界面美化时最容易顺手引入回归问题,必须重跑一遍测试用例。


参考资料:

posted @ 2026-09-15 21:47  Ron_g  阅读(19)  评论(0)    收藏  举报