软工第二次作业

一箭又一箭:基于 Python 与 AIGC 的休闲小游戏开发实践

作业信息

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

一、项目展示

开始界面:点击“开始游戏”进入第 1 关。

b480c8b2222a2df7dd3cfd95d2d539f3

第 1 关游戏界面:5×5 棋盘内分布着 12 枚不同方向的箭头,右侧显示关卡、剩余箭头和失误次数。

de346670ca145e9597a31ed9dfbe1048

游戏进行中:按合理顺序点击箭头,使其依次飞出棋盘(此处第 1 关已消除 10 枚,剩余 2 枚)。

72144ea042b366c67b3d8f38502f2f62

通关界面:清除本关全部箭头后弹出“第 1 关完成!”,点击“下一关”继续。

fc67007a57b6e452a2c3c560e8ba9dba

第 2 关通关:以剩余 1 次失误完成第 2 关,说明过程中发生过碰撞提示。

53ba2a2f2c4a00ba60299a4513712888

第 3 关游戏界面:第 3 关共 16 枚箭头,边框行箭头全部朝外,中间列箭头上下交错。

6eebb0c7d4858d2cd0dda929e246c7f7

全部通关:完成全部 3 个关卡后弹出“全部通关!”,可回到开始界面。

808d30e74c2e175a29769e7bf6756780

二、项目介绍

游戏规则

  • 棋盘为 5×5 网格,每个格子中至多有一枚箭头,方向分为上、下、左、右四种;
  • 点击某枚箭头后,程序检查该箭头前进方向上、从箭头到棋盘边界之间的路径:
    • 路径上没有其他箭头 → 箭头沿其方向飞出棋盘并被消除;
    • 路径上存在其他箭头 → 箭头不能被消除,产生晃动变红的碰撞反馈,并扣除 1 次失误;
  • 清除本关全部箭头后通关并进入下一关;
  • 失误次数共 5 次,耗尽则本关失败,可选择重玩本关或回到开始界面。

界面设计

游戏包含四种界面状态:开始界面、游戏界面、通关界面、失败界面。游戏界面左侧为棋盘,右侧显示当前关卡、剩余箭头数量和剩余失误次数,右下角提供“重新开始”按钮。界面布局简洁,文字清楚,操作仅需鼠标左键点击。

主要功能

  1. 鼠标点击选择与判断箭头;
  2. 四方向路径检测与越界安全处理;
  3. 箭头飞出动画与碰撞晃动/变色反馈;
  4. 关卡切换(3 关)与重开机制;
  5. 失误次数统计与失败判定。

三、实现思路

1. 箭头与关卡的数据表示

箭头使用一个 Arrow 类表示,记录所在行列、方向、存活状态以及用于动画的坐标:

class Arrow:
    def __init__(self, row, col, direction):
        self.row = row
        self.col = col
        self.direction = direction  # 'U' 上 / 'D' 下 / 'L' 左 / 'R' 右
        self.alive = True
        self.x = BOARD_X + col * CELL + CELL // 2
        self.y = BOARD_Y + row * CELL + CELL // 2
        self.shake = 0.0        # 碰撞晃动剩余时间
        self.blocked_flash = 0.0  # 碰撞变红剩余时间

关卡使用三元组 (row, col, direction) 的列表表示,加载关卡时转换为 Arrow 对象:

levels = [
    [ (0, 0, 'U'), (1, 0, 'U'), (2, 0, 'U'), ... ],  # 第 1 关
    ...
]

2. 路径检测(核心算法)

路径检测是游戏的核心。点击箭头后,只需判断同一行或同一列上、箭头与棋盘边界之间是否还存在其他存活箭头。由于箭头在网格中按格子摆放,检测时按方向逐个格子扫描即可:

def is_blocked(arrow):
    r, c, d = arrow.row, arrow.col, arrow.direction
    if d == 'U':
        for rr in range(r - 1, -1, -1):   # 从上方第一格扫到棋盘边界
            if any(a.alive and a.row == rr and a.col == c for a in arrows):
                return True
    elif d == 'D':
        for rr in range(r + 1, ROWS):     # 向下扫描
            ...
    elif d == 'L':
        for cc in range(c - 1, -1, -1):   # 向左扫描
            ...
    elif d == 'R':
        for cc in range(c + 1, COLS):     # 向右扫描
            ...
    return False

其中 range(r - 1, -1, -1)range(r + 1, ROWS) 的边界设计保证了:位于边缘、朝向棋盘外的箭头(如第 0 行的向上箭头)扫描范围为空,直接判定为“前方无阻挡”,可以正常飞出,不会发生数组越界。

3. 碰撞反馈与失误机制

点击被阻挡的箭头时,设置 shakeblocked_flash 两个计时器,绘制时根据 shake 计算左右晃动的偏移量,根据 blocked_flash 决定箭头颜色(正常蓝色 → 红色),同时失误次数减 1:

def try_click_arrow(a):
    global mistakes, state
    if is_blocked(a):
        a.shake = 0.4
        a.blocked_flash = 0.4
        mistakes -= 1
        if mistakes <= 0:
            mistakes = 0
            state = "GAME_OVER"
    else:
        a.alive = False
        flying_arrows.append(a)   # 加入飞行动画队列

4. 飞出动画与游戏状态机

  • 成功点击的箭头加入 flying_arrows 列表,每帧按方向以固定速度移动,飞出屏幕后移除;
  • 使用 state 变量维护四种状态:START(开始)、PLAY(游戏)、LEVEL_CLEAR(通关)、GAME_OVER(失败),主循环按状态分发事件处理和绘制;
  • 当存活箭头数为 0 且飞行动画全部结束后,自动进入通关状态。

四、AIGC 使用过程

本次开发使用 AIGC 工具辅助完成了需求分析、代码编写和调试。以下选取 3 次具有代表性的协作过程进行记录:

子任务 借助何种 AIGC 技术 AI 实现或提供了什么 效果如何 人工修改
路径检测 DeepSeek 生成四个方向的路径检测代码,逐格扫描判断前方是否被阻挡 基本逻辑可用,但方向边界的循环范围需要推敲 检查并修正了向上/向左检测的循环边界,确认边缘箭头不会越界
碰撞反馈与动画 DeepSeek 提供箭头晃动、变红提示和飞出动画的实现思路与代码 动画效果基本符合预期 调整了晃动幅度和飞出速度,使反馈更明显、节奏更舒适
关卡设计 DeepSeek 按规则生成三个关卡的箭头布局数组 生成的布局存在“死局”(无法按顺序消除全部箭头) 手工调整箭头位置,并逐个关卡试玩验证通关顺序

使用心得

AIGC 能快速生成可运行的骨架代码,但在边界条件、游戏规则细节(如死局判定)等方面仍需要人工把关。本次最典型的例子是路径检测的循环边界:AI 生成的代码在“箭头位于边缘朝外”的情况下容易越界或误判,必须结合游戏规则手工修正并测试验证。

五、测试结果

对程序进行手工测试,测试环境:Windows 11 + Python 3.x + pygame 2.x。结果如下:

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出棋盘并消失 箭头沿方向飞出并消失,剩余箭头数减 1 通过
T02 点击前方有阻挡的箭头 箭头不消失,失误次数减 1 箭头晃动变红后恢复,失误次数减 1 通过
T03 点击位于边缘且朝向棋盘外的箭头 箭头正常消失,不发生越界错误 程序正常运行,箭头飞出,无异常 通过
T04 消除本关全部箭头 显示通关并进入下一关 弹出“第 X 关完成!”,点击“下一关”进入下一关 通过
T05 失误次数耗尽 显示失败并允许重新开始 弹出失败界面,可“重玩本关”或“回到开始” 通过
T06 游戏进行中重新开始 箭头布局和失误次数恢复 点击“重新开始”后箭头数量和失误次数恢复初始值 通过

6 项测试全部通过,说明程序在正常操作流程下行为符合预期。

六、PSP 表格

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

七、心得体会

本次作业让我第一次完整地走了一遍“需求分析 → 界面设计 → 算法实现 → 测试 → 文档”的小游戏开发流程。收获主要有三点:

  1. AIGC 是高效的“结对编程”助手。借助 AI,我快速得到了 pygame 窗口搭建、箭头绘制、事件处理等大量样板代码,把精力集中在核心的路径检测和游戏规则上,整体开发效率明显提升。
  2. AI 的代码需要人工把关。AI 生成的代码在“看起来能跑”和“真的正确”之间还有差距,本次遇到的最典型问题是路径检测的边界条件:如果循环范围写错,边缘朝外的箭头要么越界要么无法消除。这类问题只有理解了游戏规则、结合测试用例才能发现并修正。
  3. 测试和试玩很重要。关卡数据不是随便生成的,必须保证存在合理的通关顺序。我在三个关卡上都进行了实际试玩,调整了第 3 关的布局后才确认可以正常通关。这也印证了老师强调的“AI 生成代码进入项目后,由提交者本人负责”。

总的来说,AIGC 降低了上手门槛,但理解代码、验证逻辑、完善细节仍然是自己必须完成的工作。

附:GitHub 仓库

  • 仓库地址:https://github.com/kwndl108/kwndl-one-arrow-game
  • 仓库内容:main.py(源代码)、README.md(说明文档)、simhei.ttf(中文字体)、start.pnggame.png(游戏截图)
  • 开发过程中按功能拆分进行了多次 commit,例如:
    • feat: 完成游戏基础版本
    • fix: 优化窗口显示效果
    • docs: 完善README和运行说明
posted @ 2026-09-19 13:45  kwndl  阅读(21)  评论(0)    收藏  举报