• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
102401225王圣杰
博客园    首页    新随笔    联系   管理    订阅  订阅

软工第二次作业

# 2026 秋软件工程个人作业(第二次):一箭又一箭

项目 内容
这个作业属于哪个课程 202601 软件工程班级博客
这个作业要求在哪里 第二次个人作业要求
这个作业的目标 使用 Python 和 AIGC 完成“一箭又一箭”小游戏
学号 102401225
GitHub 仓库 Arrow Game

一、项目展示

本项目使用 Python 标准库 Tkinter 完成,不需要额外安装 pygame。窗口为 920 × 760,采用深蓝暗色主题,包含开始界面、游戏界面、通关界面和失败界面。

1. 开始界面

01_start

2. 游戏界面

02_game

3. 碰撞反馈

03_collision

4. 通关界面

04_clear

5. 失败界面

05_fail

6. 整体流程演示

demo_complete

以上截图和 GIF 均来自本项目的实际运行记录。

二、项目介绍

2.1 游戏规则

“一箭又一箭”是一个点击式箭头解谜游戏。棋盘上有 5 × 5 个网格,箭头分为上、下、左、右四个方向。玩家点击箭头后,程序会沿着箭头所指方向检查它与棋盘边界之间是否存在其他箭头:

  • 如果前方没有其他箭头,当前箭头会飞出棋盘并消失。
  • 如果前方有箭头阻挡,当前箭头不会消失,会向前冲一下再弹回,并变色提示碰撞。
  • 点击被阻挡的箭头会扣除 1 点生命,生命值耗尽则本关失败。
  • 清空当前关卡全部箭头后即可进入下一关。

2.2 界面设计

游戏界面分为几个区域:

  • 顶部状态卡片:显示当前关卡、关卡名称、得分、连击、剩余箭头和生命值。
  • 中部棋盘:显示 5 × 5 圆角网格和方向箭头。
  • 右侧按钮:提供“重新开始”和“提示”操作。
  • 结果界面:显示本关得分、当前总分,以及下一关、重新挑战或返回开始界面的按钮。

界面采用深蓝渐变背景、圆角卡片和柔和投影。按钮有悬停高亮,箭头在鼠标移入时也会高亮边框,便于玩家确认当前可操作对象。

2.3 主要功能与特色

  • 基础单格箭头玩法,方向判断仅依赖同一行或同一列。
  • 箭头飞出动画、碰撞晃动与变色反馈。
  • 得分与连击机制:连续正确消除会提高单次得分。
  • 生命值系统:使用红心显示,生命耗尽会失败。
  • 每关 2 次提示功能,会高亮一个当前可以点击的箭头。
  • 共 10 个关卡,全部通过可通关性验证。
  • 内置 --selftest 命令,可自动检查所有关卡是否存在可通关顺序。

三、实现思路

3.1 方向如何表示

方向使用字典保存为行列增量,这样可以把方向判断统一转化为“在网格上一步一步移动”。

DIRECTION_VECTORS = {
    "up": (-1, 0),
    "down": (1, 0),
    "left": (0, -1),
    "right": (0, 1),
}

例如“向右”对应行不变、列加 1,即 (0, 1)。

3.2 箭头和关卡如何表示

每个箭头在逻辑上用 (row, col, direction) 表示。一个关卡包含关卡名称、初始生命值和一组箭头:

Level(
    "第一关 · 初试身手",
    3,
    (
        (0, 0, "right"),
        (0, 3, "right"),
        (0, 4, "up"),
        (4, 0, "left"),
        (4, 4, "down"),
    ),
)

界面上的每个箭头再由 ArrowSprite 保存其网格坐标、方向、Canvas 标签和绘制的图形元素。

3.3 路径检测方法

路径检测是本题的核心。程序从当前箭头的下一格开始,按照方向增量逐格移动,只要在到达棋盘边界前遇到任何一个已占用格,就认为前方有阻挡。

def position_is_blocked(row, col, direction, occupied):
    dr, dc = DIRECTION_VECTORS[direction]
    r, c = row + dr, col + dc

    while 0 <= r < ROWS and 0 <= c < COLS:
        if (r, c) in occupied:
            return True
        r += dr
        c += dc

    return False

这里 occupied 是当前棋盘上所有箭头的坐标集合。为什么从下一格开始检查,而不是从自身开始?因为箭头自身的位置不属于它前进方向上的阻挡物,如果从自身开始,会错误地认为所有箭头都撞到自己。

3.4 点击后的状态更新

点击箭头后,程序根据路径检测结果更新不同状态:

if not blocked:
    self.combo += 1
    points = 100 + min(self.combo - 1, 4) * 25
    self.score += points
    self.arrows.remove(sprite)
    self.animate_fly_out(sprite, points)
else:
    self.combo = 0
    self.health -= 1
    self.score = max(self.level_start_score, self.score - 20)
    self.animate_collision(sprite, 20)

清除成功会增加连击和得分,并触发飞出动画;碰撞会重置连击、扣除生命,并触发向前冲再弹回的碰撞动画。

3.5 关卡可解性验证

本项目没有只凭感觉设计关卡,而是写了一个回溯验证函数:每一步扫描所有当前前方无阻挡的箭头,尝试移除它并递归检查剩余箭头是否能全部清除。

def level_has_solution(level):
    def search(remaining):
        if not remaining:
            return True
        for arrow in clear_arrows(remaining):
            rest = tuple(item for item in remaining if item != arrow)
            if search(rest):
                return True
        return False

    return search(level.arrows)

运行 python arrow_game.py --selftest 时,程序会依次检查全部 10 个关卡是否都存在至少一种可通关顺序。

四、AIGC 使用过程

本次开发主要使用 Codex 作为 AIGC 辅助工具。下面记录几次有代表性的协作过程。

子任务 借助何种 AIGC 技术 AIGC 提供了什么 我的判断与修改
基础框架与路径检测 Codex 提供了 Tkinter 单文件结构、方向字典、阻挡检测和动画思路 我确认 pygame 未安装后,同意使用标准库 Tkinter;运行后检查四个方向、边界和碰撞逻辑,补充关卡验证
得分、生命、连击和提示 Codex 根据“剩余次数换成血量”“交互性更强”的要求,加入生命、红心、得分、连击、飘分和提示功能 我实际运行后发现生命值文字与右侧按钮重叠,要求把生命值移到中间并调整 HUD 布局
增加关卡 Codex 使用“反向构造”方式生成多组可解关卡,并加入 10 关 我运行 --selftest 验证 10 个关卡均可通关,并根据命名和难度整理关卡顺序
界面美化 Codex 参考休闲游戏 UI 设计原则,加入圆角卡片、柔和投影、按钮和箭头悬停效果 我先后试了浅色、淡蓝色和暗色主题,最终根据实际阅读效果选择暗色系,并简化开始界面
博客素材生成 Codex 生成本博客草稿、截图和演示 GIF 我补充真实运行记录,并整理成博客园可发布的结构

通过这些协作,我体会到 AI 更适合快速生成可运行版本和提供结构建议,而规则是否准确、界面是否重叠、关卡是否真的可通关,仍然需要自己运行和判断。

五、测试结果

5.1 自动化检查

项目提供两个可重复执行的检查:

python arrow_game.py --selftest

用于检查 10 个关卡是否全部存在至少一种可通关顺序。

python -m py_compile arrow_game.py

用于检查 Python 语法是否正确。

5.2 主要测试项

编号 测试内容 预期结果 实际结果 是否通过
T01 点击前方无阻挡的箭头 箭头飞出并消失,剩余箭头减 1 箭头被移除,飞出动画正常 通过
T02 点击前方有阻挡的箭头 箭头不消失,生命减 1 箭头弹回并变色,生命减 1 通过
T03 四个方向的边界检测 上、下、左、右都能正确判断 四个方向路径检测正确 通过
T04 清空当前关卡全部箭头 显示通关界面并进入下一关 最后一支箭头飞出后进入通关状态 通过
T05 生命值耗尽 显示失败界面 第三次碰撞后进入失败状态 通过
T06 重新开始 棋盘、生命、连击和提示次数恢复 当前关卡状态恢复 通过
T07 得分和连击 正确消除加分,连击提高单次得分;碰撞重置连击 分数和连击变化符合设计 通过
T08 提示功能 高亮一个当前可点击箭头,提示次数减 1 高亮和次数更新正常 通过
T09 10 个关卡可解性 每个关卡都存在可通关顺序 --selftest 全部通过 通过
T10 开始、游戏、通关、失败界面 四个页面均能正常显示和切换 GUI 冒烟测试通过 通过

5.3 人工试玩

我实际运行了游戏,逐个测试 10 个关卡,观察箭头的阻挡关系并按正确顺序点击。碰撞、生命扣除、连击、提示、通关、失败和重新开始流程均正常,没有出现无法通关、越界或文字重叠的问题。

六、PSP 表格

下面是示例数据,请根据自己的实际开发时间调整。

阶段 预估耗时(小时) 实际耗时(小时)
需求分析与游戏规则整理 0.5 0.2
Python / Tkinter 学习 1.5 1.0
基础界面与状态切换 0.5 0.3
路径检测与碰撞逻辑 1.0 0.8
得分、生命、连击和提示 0.1 0.1
关卡设计与可解性验证 0.2 0.2
界面美化和主题调整 0.5 0.2
AIGC 协作与代码修改 0.5 0.1
测试与问题修复 0.2 0.1
README 与博客撰写 1.0 1.0
合计 6.0 4.0

七、心得体会

本次作业让我第一次完整经历了一个小游戏从需求分析、界面设计、核心逻辑、关卡设计、测试到博客总结的过程。

AI 给我的帮助主要在三个方面:

  1. 快速搭起一个可以运行的 Tkinter 游戏框架,减少了我从零开始熟悉图形界面的时间。
  2. 帮助我把“路径检测”从自然语言描述转换为逐格移动的判断逻辑,让我更容易理解方向增量、边界条件和占用集合。
  3. 在增加得分、生命、连击、提示和关卡时,提供了一些我原本没有考虑到的交互细节,例如飘分反馈和提示高亮。

开发过程中也出现了一些问题。比如一开始生命值放在右侧会和按钮重叠,后来通过实际运行发现问题并调整了 HUD 布局。又如关卡不能只靠随机摆放,必须先确保每一关都至少存在一种可通关顺序,否则玩家可能陷入死局。最后我加入了 level_has_solution 和 --selftest,让关卡可解性可以自动验证。

通过这次作业,我更清楚地认识到:AI 可以生成代码,但不能替我做“运行、试玩和判断”。规则是否准确、动画是否自然、界面是否清晰、关卡是否能通关,这些都需要自己实际操作后决定。我也更熟悉了 Tkinter 的事件处理、Canvas 绘图、after 动画调度,以及用回溯法验证关卡可解性的思路。


posted on 2026-09-16 20:03  Ha11oween  阅读(34)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3