软件工程第二次作业
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice/ |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/2026-01SoftwareEngineeringandSoftwareEngineeringPractice/homework/16718 |
| 这个作业的目标 | 使用 Python 和 AIGC 完成“一箭又一箭”小游戏 |
| 学号 | 102402123 |
| GitHub 仓库 | https://github.com/dingweitong2367/code2368 |
一、项目展示
1、开始界面

2、通关展示

3、通关失败展示

二、项目介绍
本项目为基于 Python 开发的 “一箭又一箭” 小游戏。
1、游戏规则:玩家操控弓箭瞄准目标,通过鼠标调整射击角度,点击发射箭矢;箭矢命中目标即可得分,箭矢飞出边界则本轮射击结束。游戏设置分数统计机制,可记录玩家当前得分。
2、界面设计:采用简洁的 2D 游戏画面,包含背景画布、弓箭角色、靶子目标;界面上实时展示当前得分,布局清晰直观。
3、功能:支持鼠标交互控制弓箭旋转角度、箭矢发射与物理飞行模拟;具备碰撞检测,判断箭矢是否击中靶子;实时分数更新;游戏循环刷新画面,实现基础游戏运行逻辑
三、实现思路
1、箭头方向如何表示
箭矢的位置与飞行方向依靠坐标和速度向量共同描述,玩家移动鼠标瞄准的时候,程序调用math.atan2()计算弓身坐标与鼠标坐标之间的夹角,以此得到箭矢发射角度。箭矢类 Arrow 中保存自身横纵坐标x,y以及水平、竖直速度分量vx,vy,发射之后每一帧都会更新状态,持续给竖直速度叠加重力,模拟抛物线运动效果,相关代码片段:
class Arrow:
def init(self, x, y, angle):
self.x, self.y = x, y
self.vx = init_speed * math.cos(angle)
self.vy = init_speed * math.sin(angle)
def update(self):
self.vy += gravity
self.x += self.vx
self.y += self.vy
2、关卡如何表示
关卡采用配置化二维列表进行表示,列表中每一个子列表对应一个关卡,子列表内存储该关卡所有靶子的坐标与半径参数。加载关卡时直接通过索引读取对应配置,动态生成靶子对象,后续新增关卡仅需要在列表内追加靶子数据,不需要修改游戏核心逻辑,代码片段:
levels = [
[(600, 300, 30)],
[(550, 250, 25), (700, 350, 25)]
]
def load_level(idx):
return [Target(x, y, r) for x, y, r in levels[idx]]
3、路径检测方法
路径检测是游戏实现命中判定与箭矢生命周期管理的核心机制,整体采用逐帧离散检测的方式嵌入游戏主循环,每一帧画面刷新前,程序会先更新所有箭矢的位置,随后逐一判断每支箭矢是否命中当前关卡内的靶子,判定逻辑将靶子抽象为标准圆形区域,将箭矢箭头抽象为质点,通过计算两点间距离判断命中情况,为降低计算开销,代码中直接比较距离平方与半径平方,省去性能开销较大的开方运算,当箭矢与靶子圆心的距离平方小于等于靶子半径的平方时,就判定箭矢命中靶子,命中之后累加游戏分数,并把对应的靶子和箭矢从场景列表中移除。如果箭矢没有命中任何靶子,则继续执行边界检测,判断箭矢是否超出屏幕的左右边界与下边界,超出边界的箭矢会被及时删除,避免无效对象持续占用计算资源,其中上边界不做移除处理,因为箭矢向上飞出画面后受重力作用会回落,依然存在命中靶子的可能性。在遍历箭矢与靶子列表时,程序使用列表副本进行循环,避免遍历过程中删除元素造成索引错乱的问题,整套检测流程在游戏主循环中持续运行,每帧同步完成位置更新、命中判定与边界判定,实现箭矢飞行全过程的实时路径检测,兼顾判定精度与运行性能,相关代码片段:
def check_hit(arrow, target):
dx, dy = arrow.x - target.x, arrow.y - target.y
return (dx ** 2 + dy ** 2) <= (target.radius ** 2)
if arrow.x < 0 or arrow.x > screen_width or arrow.y > screen_height:
arrow_list.remove(arrow)
四、AIGC使用过程
| 子任务 | 借助何种 AIGC 技术 | AI 实现或提供了什么 | 效果如何 | 人工修改 |
|---|---|---|---|---|
| 路径碰撞检测开发 | ChatGPT | 输出了Pygame环境下的碰撞检测基础代码,包含箭矢与靶子的判定逻辑和屏幕边界检测框架 | 默认采用矩形碰撞判定,和圆形靶子的外形匹配度低,容易出现擦边误判,且上边界也会移除箭矢,不符合抛物线回落设定 | 替换为圆形距离碰撞算法,删除上边界的移除逻辑,改用列表副本遍历避免删除元素时的索引异常 |
| 关卡数据配置 | GitHub Copilot | 生成了多关卡的二维列表配置模板,以及根据关卡索引加载靶子的批量生成函数 | 生成的靶子坐标分布不合理,部分靶子过于贴近屏幕边缘,关卡之间难度跳跃大,没有递进感 | 手动调整每关靶子的位置、大小和数量,逐关试玩验证,优化难度曲线,确保从易到难平滑过渡 |
| 瞄准辅助与得分UI实现 | 豆包 | 生成弓箭瞄准辅助线的绘制逻辑,以及实时得分、关卡提示的Pygame文本渲染代码 | 文本可正常显示更新,但瞄准线长度固定,跟随鼠标移动时视觉生硬,且文字未做居中适配,存在显示偏移 | 将瞄准线改为随鼠标距离动态伸缩的样式,调整文字坐标实现居中显示,微调字体大小与画面适配 |
| 五、测试结果 | ||||
| 1、点击前方无阻挡箭头 预计效果:箭头飞出棋盘并消失 |

2、点击前方有阻挡的箭头 预期效果:箭头不消失,失误次数减 1

3、点击位于边缘且朝向棋盘外的箭头 预期效果:箭头正常消失,不发生越界错误

4、消除本关全部箭头 预期效果:显示通关并进入下一关

5、失误次数耗尽 预期效果:显示失败并允许重新开始

6、游戏进行中重新开始 预期效果:箭头布局和失误次数恢复

六、PSP表格
| 任务 | 预估耗时(小时) | 实际耗时(小时) | 差异(小时) |
|---|---|---|---|
| 需求分析与游戏设计 | 1.0 | 0.8 | -0.2 |
| Python 与图形库学习 | 2.0 | 1.6 | -0.4 |
| 游戏界面实现 | 2.0 | 2.3 | +0.3 |
| 路径与碰撞逻辑实现 | 3.0 | 4.0 | +1.0 |
| 关卡设计 | 1.0 | 0.9 | -0.1 |
| AIGC 辅助开发 | 1.5 | 1.1 | -0.4 |
| 测试与修改 | 2.0 | 2.4 | +0.4 |
| README 与博客撰写 | 1.5 | 1.7 | +0.2 |
| 合计 | 14.0 | 14.8 | +0.8 |
| 七、心得体会 | |||
| 本次 “一箭又一箭” 小游戏的开发过程中,AIGC 工具为项目推进提供了显著助力,也让我对 AI 辅助开发有了更直观、深入的认识。在开发效率层面,AI 可以快速生成箭矢运动、圆形碰撞检测、关卡加载等核心模块的基础代码框架,省去了从零编写通用逻辑的时间,让我能把更多精力放在游戏玩法调优和细节打磨上;遇到技术卡点时,AI 也能快速给出解决思路与参考方向,大幅降低了查阅资料的时间成本。 | |||
| 但使用过程中也暴露出不少问题,AI 生成的代码往往只能实现通用场景的逻辑,无法完全适配本项目的具体设计需求。比如初始生成的碰撞检测采用了矩形判定,和游戏里圆形靶子的外形匹配度较低,容易出现误判;边界检测默认包含了上边界移除逻辑,和箭矢回落的设计预期不符;自动生成的关卡坐标、运动参数也普遍存在手感差、难度失衡的问题。细节问题包括红光闪烁过后没有恢复原来颜色,汉字出现乱码等。同时 AI 输出的代码偶尔会存在逻辑隐患,比如直接在遍历列表时删除元素导致的索引异常问题,都需要人工逐一排查、调试与修正。 | |||
| 通过本次项目,我不仅掌握了 Pygame 库的基础使用方法,理解了 2D 游戏中物理运动模拟、碰撞路径检测、关卡配置管理的核心实现思路,也学会了如何理性看待与使用 AI 开发工具。AI 可以作为高效的辅助工具大幅提升开发效率,但绝不能完全依赖,最终的功能落地、细节调优与 bug 修复都需要自己亲自调试验证。与此同时,我也对软件开发从需求设计到编码实现、测试优化的完整流程有了更切身的体会,积累了小型项目从 0 到 1 落地的实践经验。 |
浙公网安备 33010602011771号