Files
AICODE2026/3-lessons/AICODE-06/AICODE06-09 涂鸦PK(二)— 基础对战系统.md
Rocky 25ec5f0c9c feat: 新增涂鸦PK四课教案(第8-11课)及大纲更新
- 新增 AICODE06-08~11 完整逐字稿教案(每课600+行)
- 涂鸦PK主题:画图工具→基础对战→动画音效→班级锦标赛
- 核心工程思维:需求驱动→测试验证→增量迭代→数据驱动
- 更新 AICODE-06 课程大纲,追加第8-11课内容
- 新增 demo-pk/ 目录(画图工具/对战/动画三个demo)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 20:28:42 +02:00

606 lines
38 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
课时: 9
主题: 涂鸦PK— 基础对战系统
核心能力: [拆解力, 韧性力]
核心工具: [Trae IDE, Kimi]
时长: 90分钟
透明化层级: 过程层
适用路线: AICODE-06
---
### 1. 课程目标
**知识目标:**
- 理解「边界情况」的概念:任何系统都有正常路径以外的边缘场景,这些场景必须在需求里明确定义,否则 AI 的行为不可预测
- 理解「独立窗口审核」原则:需求文档、边界审核、代码生成、测试验证各用独立会话,防止 AI 自我偏袒
- 理解「测试脚本」的价值:用代码来验证代码,比人工点击效率高十倍,且可重复执行
**能力目标:**
- 能用 Plan Mode 整理战斗系统需求文档,并用窗口 B 发现边界情况(拆解力)
- 能把自己的 Spritesheet 导入对战系统,完成逐条验收,遇到 bug 能描述「步骤→预期→实际」(韧性力)
- 能让 AI 生成测试脚本,读懂「✅通过/❌失败」的输出,并定位到需求文档中对应的条款
**情感目标:**
- 建立「测试不是挑刺,是保护」的意识——有 bug 的游戏比没有游戏更让人沮丧,测试帮你在发布前修好它
- 体验「让 AI 测试 AI 写的代码」的效率感,而不是自己一条条人工验证
- 对「今天的角色真的打起来了」产生真实的成就感为第10课加动画做好期待
---
### 2. 核心概念与误概念预设
**核心概念认知层级:**
| 概念 | 学生类比 | 认知层级 |
|------|---------|---------|
| 边界情况 | 游戏规则书上写了「普通攻击」怎么算,但没写「两个人同时出手」怎么判——比赛现场这种情况真出现了,裁判不知道怎么判,整场比赛乱掉 | 理解层 |
| 独立窗口审核(新窗口原则) | 作文让同学评改:写作文的同学自己改,永远改不出大问题;换一个没看过你作文的同学来改,他会发现真正的漏洞 | 应用层 |
| 测试脚本 | 乐高玩具的「质检机器人」——每次按一个按钮,它自动把所有零件逐一检查一遍,告诉你哪个零件不对;比你自己一个个用眼睛看快一百倍,而且不会看漏 | 应用层 |
| 伤害公式 | 攻击力是出拳力气,防御力是护甲厚度,伤害 = 出拳力气 护甲厚度,最少也会有 1 点伤害(护甲再厚也会有点疼) | 识别层 |
| 先手机制 | 速度值高的人先出手,就像运动会百米跑步,反应快的人先起跑——如果两人反应时间一样,就抛硬币决定 | 识别层 |
**典型误概念表:**
| 编号 | 误概念 | 正确认知 | 激发策略 |
|------|--------|---------|---------|
| M1 | 游戏能跑就行,不用测试 | 有 bug 的游戏比没有游戏更难受;测试发现的 bug 才是可修复的 bug | 问:「你有没有玩过一个游戏,有个 bug 特别烦但一直不修?你是什么感受?」 |
| M2 | 测试脚本要自己写,太难了 | 测试脚本也可以让 AI 写,你只需要描述「我要验证什么结果」 | 演示:把「验证 ATK=15, DEF=5 时伤害=10」告诉 AI它直接给出测试代码 |
| M3 | 同速的情况 AI 会自动处理好 | 边界情况必须在需求里明确,否则 AI 行为不可预测(可能每次随机,也可能直接报错) | 问:「如果两个角色速度一样,谁先出手?你需求里写了吗?」 |
| M4 | 伤害公式在脑子里,不用写进需求 | 代码里的公式必须和需求文档一致,否则测试脚本无法验证;口头约定不算 | 演示需求里写「ATK 减 DEF」代码里却写成「ATK 乘以 DEF」逻辑完全不同 |
| M5 | 格挡和攻击同帧不会有问题 | 行动顺序是战斗公平性的核心;「同时出手」必须在需求里明确谁的优先级高 | 类比:石头剪刀布如果两人同时出,规则说谁赢?——必须有一个规则,不能靠 AI 猜 |
---
### 3. 教学准备
**工具与环境:**
- 每台电脑已安装 Trae IDEKimi 已登录,网络正常
- 每台电脑浏览器可以正常打开本地 HTML 文件
- 每台电脑上已有上节课完成的 Spritesheet PNG 文件128×64帧1待机+帧2攻击
- 每台电脑上已有上节课完成的角色属性 JSONhp/atk/def/spd/skill 字段20分预算制
- 投影可切换至任意学生屏幕
**教学资源:**
- 教师准备demo-2-pk-battle.html可直接运行的战斗演示开课前准备好用于 Connect 展示和 Contemplate 演示)
- 教师准备战斗需求文档范例见第5节完整版供学生卡壳时参考
- 教师准备测试脚本的预期输出截图4条全部 ✅ 通过的版本,用于对比)
- 学生资源:上节课完成的 Spritesheet PNG 和角色属性 JSON若有学生未完成教师提供默认模板
**教师备课体验任务:**
> 备课前,教师必须亲自完成以下操作:
>
> 1. 打开 demo-2-pk-battle.html完整打一局记录下「格挡+重击同回合」时伤害是怎么算的,以及「特技用完后再点特技按钮」的实际行为
> 2. 在窗口 A 整理一份战斗需求文档,然后在全新窗口 B 用审核提示词跑一遍,记录 AI 问出来的边界问题里哪几条最让你意外
> 3. 在窗口 D 生成测试脚本,验证伤害公式和先手机制,确认本课所有测试用例都能通过
> 4. 故意把伤害公式改成「ATK × DEF」重跑测试脚本截图「❌失败」的输出备课时展示用
---
### 4. 教学流程
---
**第一幕:联系 (Connect) — 10分钟** 🔗
*本幕目标:让学生展示上节课做的角色,说出打法定位和取胜策略,激活策略意识;教师演示可以运行的对战系统,建立「今天目标」的画面感*
**【环节】角色展示 + 打法定位 (7分钟)**
**师:** 上节课结束前,每个人都交了两样东西:一个 Spritesheet PNG一份角色属性 JSON。今天我们用这两样东西做什么
**生:** (预期:做游戏?让它打起来?)
**师:** 对。上节课大家做了什么,记得吗?
**生:** (预期:画了自己的角色 / 设计了角色属性)
**师:** 对。你们每个人手里有一个属于自己的角色:有自己画的图,有自己定的属性,还有自己选的特技。今天不是来欣赏它的——今天要让它真的打起来。
**师:** 在打之前,我先问每个人一个问题。谁来第一个回答——你的角色是什么打法定位?为什么你的角色应该赢?
【点一个学生,把他的 Spritesheet 投屏展示】
**生:** (预期 A「我是高攻击型我的 ATK 是 16我可以直接打穿对面」
**生:** (预期 B「我是高防御型我血多耗死对手」
**生:** (预期 C「我速度最快我先手每次都比对面早打」
**师:** 很好。你说的「先手」——如果两个角色速度值一样怎么办?
**生:** (预期:不知道 / 随机?/ 谁编号小谁先?)
**师:** 这就是我们今天第一件事要想清楚的——你脑子里的规则必须写成文字AI 才能按你想的来做。
【诊断点:学生能否意识到「打法逻辑」和「代码规则」之间有一层需要翻译的过程】【识别层】
**【分支A】若学生对打法定位有清晰的想法**
**师:** 很好,待会儿写需求文档的时候,你的打法定位就是你的出发点——你的角色是高攻击,那你的伤害公式、重击倍率、特技效果就都要围绕「攻击压制」来设计。
**【分支B】若学生说「我随便什么定位都行」**
**师:** 没关系,我们来帮你定位。你的 ATK 最高,还是 DEF 最高,还是 SPD 最高?
(引导学生从属性数值反推定位,而不是空想)
**【环节】展示今天目标 (3分钟)**
**师:** 我先给大家看一个东西。
【投屏打开 demo-2-pk-battle.html运行一局对战】
**师:** 你们看——左边是玩家角色,右边是 AI 对手,有血条,有行动按钮,有战斗日志。这就是今天下课前你们要做到的东西。
**师:** 但注意——你们做出来的版本,角色是你们自己画的,属性是你们自己定的。你的角色放在左边,跟 AI 对手打。今天不做动画,角色还是用矩形占位,但战斗逻辑是真实的。下节课我们把图换上去、加动画。
**师:** 今天的核心是:战斗规则要真的是你想的规则,而不是 AI 随机猜的规则。怎么保证?用 Plan Mode。
**师:** 今天我们会开 4 个窗口——窗口 A 写需求、窗口 B 审核边界、窗口 C 生成代码、窗口 D 做测试。这 4 个窗口,每个只做一件事,互相不干扰。记住这个结构,以后你做任何大一点的项目都可以用。
---
**第二幕:建构 (Construct) — 65分钟** 🛠️
*本幕目标:走完「需求文档→边界审核→代码生成→导入 Spritesheet→验收→测试脚本验证」完整闭环强化多窗口协作和边界意识*
---
**【分段一Plan Mode — 战斗系统需求文档】(20分钟)**
*本段重点:学生在窗口 A 整理战斗系统需求,在窗口 B 用「边界审核」提示词发现漏洞,补充进文档*
**预设误概念:**
- 误概念 M3同速情况 AI 会自动处理好,不用写
- 误概念 M4伤害公式在脑子里不用写进需求文档
- 误概念 M5格挡和攻击同帧不会有问题
**讲解与演示 (Teach & Demo): (7分钟)**
**师:** 我们先开窗口 A——这个窗口只做一件事整理需求文档。
**师:** 今天的需求文档比俄罗斯方块简单一点,但有一个新的挑战——这个系统里有很多「边界情况」。什么叫边界情况?就是不在「正常流程」里,但真实对战时会出现的场景。
**师:** 我给你们举几个例子。正常流程是什么玩家点攻击AI 点攻击,互相扣血,谁血量归零谁输。这是主路径,好想,好写。
**师:** 但是——如果两个角色速度值完全相同,谁先出手?这条你有没有想过?
**生:** (预期:没想过 / 随机?)
**师:** 还有——特技每场只能用一次。如果玩家特技已经用完了,再点「特技」按钮,游戏会怎样?按钮灰掉不能点?还是提示「已用完」?还是直接变成普通攻击?
**生:** (预期:好像要变灰 / 要提示吧)
**师:** 对。还有——格挡时受到的伤害减少 50%那对方用的是重击伤害×1.8),格挡减伤是基于重击后的伤害算,还是基于原始伤害算?
**生:** (预期:有区别吗……?哦,区别很大!)
**师:** 这些都是边界情况。这些情况如果你没有在需求里写清楚AI 会自己猜一个——可能猜得跟你想的不一样,可能每次结果还不同,可能直接崩掉。
**师:** 所以今天需求文档要写两轮。第一轮是窗口 A把主路径写出来。第二轮是窗口 B让 AI 扮演审核工程师,专门找你没考虑到的边界情况。
【投屏展示战斗需求文档的五个核心模块】
**师:** 战斗系统需求文档有五个必填模块。我过一遍每个的关键要点——
**师:** 模块一先手机制。你必须写清楚两条第一SPD 高的先出手——这好理解;第二,**同速时怎么处理**——你必须选一个方案,写进文档。你可以写「同速时随机决定」,也可以写「同速时玩家先手」,但必须选一个,不能空着。
**师:** 模块二伤害公式。写「ATK 减 DEF最低造成 1 点伤害」。注意「最低 1 点」这个细节必须写——如果不写当防御值大于攻击值时AI 可能算出负数伤害,变成治疗对手了。
**师:** 模块三行动类型。四种普通攻击、重击伤害×1.8)、格挡(本回合受伤减少 50%)、特技(每场只能用一次,效果来自角色 JSON 的 skill 字段)。
**师:** 模块四胜负判定。HP≤0 立即判输,游戏结束。
**师:** 模块五AI 对手决策逻辑。AI 对手不是乱打的——写清楚它的决策规则HP 低于 30% 时用特技25% 概率重击;否则普通攻击。
**师:** 我来快速演示一下这五个模块写出来是什么样的。
【投屏展示教师自己的需求文档草稿,只展示模块一和模块二,让学生对格式有直观感受,不逐字念,只指出关键字段】
**师:** 你们看模块一的「同速处理」我写了「同速时随机决定Math.random() < 0.5 为玩家先手」。你们不需要写代码,但要写清楚「同速时谁先」——随机、或者固定玩家先手,选一个写进去。
**师:** 模块二里,我特别标了「最低 1 点」并且加了验收标准:「当 ATK=3, DEF=8 时,伤害=1 而不是负数」。这就是一条可测试的需求——能写出具体数字的需求,才是真正写清楚了的需求。
**师:** 这五个模块写完,是你的「主路径」。然后我们开窗口 B让 AI 来挑刺。
**学生实践 (Practice): (10分钟)**
**师:** 现在打开 Kimi开一个新对话这是窗口 A。用我刚才说的五个模块把你的战斗系统需求文档写出来。不确定的地方先写一个版本待会儿窗口 B 会帮你发现问题。
> 教师走动观察重点:
> - 是否有学生跳过「同速处理」这条?走过去问:「你这里写了 SPD 高的先手,那两人 SPD 一样怎么办?」
> - 是否有学生漏写「最低 1 点伤害」?问:「如果对手 DEF 比你 ATK 还高,伤害是负数还是零?你想要哪个?」
> - 是否有学生把 AI 对手的决策逻辑写得很复杂(超过 3 条提醒「AI 对手逻辑先简单,战斗规则才是重点」
**进度同步 (Checkpoint): (3分钟)**
**师:** 五个模块都填了的举手。
**师:** 好,现在开窗口 B——新开一个 Kimi 对话,把你写好的需求文档整个复制过去,然后加上这句话:「你是一个游戏测试工程师,请列出这份需求文档里所有的边界情况和异常情况,只列问题,不需要解答。」提交。
【诊断点:学生是否能把「用窗口 B 挑需求漏洞」理解为「需求还没写完」,而不是「可以不管这些问题」】【理解层】
**【分支A】若学生窗口 B 得到了边界问题列表:**
**师:** 好,先把这些问题读一遍。你觉得哪条最重要——就是如果不处理,对战时一定会出问题的那条?
(让学生自己判断优先级,而不是逐条补充所有问题)
**【分支B】若学生说「AI 没问出什么有用的问题」:**
**师:** 我来帮你加一条——「同速时谁先出手」这条你文档里怎么写的?
(从教师预设的边界情况里选一条,帮学生发现漏洞)
**【分支C】若学生觉得「这些边界情况不重要先做再说」**
**师:** 好,我们来做个实验——你先做,遇到边界情况的时候我们再说。
(让学生先继续,在分段二验收时用真实 bug 来说明边界问题的后果)
**师:** 窗口 B 出来的问题,不需要全部解决——先挑最重要的 3 条,补充到你的需求文档里。什么叫「最重要」?就是如果不写清楚,对战时一定会出现的场景。「同速先手」、「特技用完后再点」、「格挡+重击叠加」——这三条必须在文档里有明确答案。
**师:**5分钟把窗口 B 给你的问题里最关键的几条回答了,补到需求文档里。
> 教师走动:重点帮学生判断哪条边界问题「必须解决」。判断标准——对战时能触发的频率高不高?触发了但没处理会崩游戏还是只是显示不对?优先处理会崩游戏的。
---
**【分段二:生成 PK 系统 → 导入 Spritesheet → 逐条验收】(25分钟)**
*本段重点:在窗口 C 生成战斗系统骨架,替换为自己的角色数据,验收核心功能*
**预设误概念:**
- 误概念 M1能跑就行不用验收每一条
- 误概念 M4遇到 bug 直接让 AI 改代码,不回需求文档溯源
**讲解与演示 (Teach & Demo): (5分钟)**
**师:** 需求文档确认好了,进入执行阶段。打开 Trae IDE新开一个文件命名为 pk-battle.html。
**师:** 这次生成分两步走。**第一步**:先生成「带占位图的骨架」——角色先用彩色矩形代替,重点让战斗逻辑跑通。**第二步**:骨架验收通过后,再把你的 Spritesheet 换进去。
**师:** 为什么要分两步?如果你一开始就把 Spritesheet 传进去,战斗逻辑有 bug 的话,你不知道是逻辑问题还是图片问题——两个问题混在一起,很难调试。先把逻辑跑通,再换图,问题清晰。
**师:** 现在开窗口 C——这个窗口专门做代码生成。把你的需求文档复制进去加上保底提示词提交。
【投屏展示学生保底提示词见第5节教师演示提交过程展示骨架生成结果】
**师:** 生成出来之后,把代码复制到 Trae IDE 里的 pk-battle.html保存用浏览器打开开始验收。
**师:** 验收怎么做?还是我们之前说的三步——「步骤→预期→实际」。你做了一个操作,你期望看到什么,实际看到了什么。如果期望和实际不一样,记下来,这就是一个 bug。
**师:** 验收清单,我们一起来定:
```
验收清单(至少验这 5 条):
1. 普通攻击 → 对手 HP 减少,减少量 = ATK - DEF最低 1
2. 格挡 → 下一次受到伤害减少 50%
3. 重击 → 伤害比普通攻击×1.8
4. 特技按钮 → 用完一次后变灰或显示「已用」
5. HP≤0 → 游戏结束,显示胜负
```
**学生实践 (Practice): (17分钟)**
第一步8分钟用保底提示词在窗口 C 生成战斗骨架,复制到 Trae IDE浏览器打开
第二步4分钟按验收清单逐条点击验收记录「通过/不通过」
第三步5分钟把验收通过的骨架里的角色数据替换为自己的角色属性 JSON把矩形占位符的颜色改成自己角色的代表色
> 教师走动观察重点:
> - 学生是否在逐条验收,还是点一下「感觉可以」就算通过?走过去问:「第 3 条重击倍率你验了吗?怎么确认它是 1.8 倍?」
> - 学生遇到 bug 时,是直接跟 AI 说「帮我修复」,还是先回需求文档确认这条需求怎么写的?
> - 有学生进展很快的:引导他多做一步——把 Spritesheet 也导入,用 `drawImage` 替换矩形,不需要动画,只是让图片显示出来
**进度同步 (Checkpoint): (3分钟)**
**师:** 谁来说一条验收结果——哪条通过了,哪条没通过?
**生:** (预期 A「普通攻击通过了格挡没通过格挡好像没有减伤」
**生:** (预期 B「特技用完之后按钮没变灰还能继续按」
**师:** 格挡没有减伤——这个 bug 我们用「步骤→预期→实际」来描述。步骤是什么?
**生:** 点格挡,然后对面攻击我。
**师:** 预期是什么?
**生:** 受到的伤害应该是正常伤害的 50%。
**师:** 实际是什么?
**生:** 受到的伤害跟没格挡一样。
**师:** 对。这个描述发给 AI加上一句「请检查需求文档里的格挡逻辑修复这个 bug」。注意——不是说「帮我改代码」是「检查需求文档对应的逻辑」让 AI 溯源。
【诊断点:学生是否会用「步骤→预期→实际」三要素描述 bug而不是只说「格挡不对」】【应用层】
**【分支A】若学生能准确描述 bug 三要素:**
**师:** 这就是专业的 bug 报告。真正的软件工程师报 bug 就是这个格式,你今天已经在用了。
**【分支B】若学生描述模糊「格挡感觉不太对」**
**师:** 「感觉不对」AI 不知道从哪里改。你告诉我——你点了格挡之后,对面攻击你,你的 HP 掉了多少?你预期应该掉多少?
(帮学生把感受翻译成具体数字)
---
**【分段三:窗口 D 生成测试脚本 → 验证核心逻辑】(15分钟)**
*本段重点:在独立窗口 D 生成测试脚本,运行 4 条测试用例,读懂「✅通过/❌失败」输出,体验「让 AI 测试 AI」的效率*
**预设误概念:**
- 误概念 M2测试脚本要自己写太难了我不会代码
- 误概念 M1能跑就行不需要写测试
**讲解与演示 (Teach & Demo): (5分钟)**
**师:** 你们刚才用手工逐条验收——点按钮,看结果。这样做是对的,但有一个问题:下次你改了一段代码,你要把所有条目再点一遍吗?
**生:** (预期:要的 / 好累 / 不想点)
**师:** 有一个更高效的方法——**测试脚本**。你告诉 AI「我要验证哪些规则预期结果是什么」AI 写一个 HTML 文件,你一打开,它自动跑完所有验证,每条显示「✅通过」或者「❌失败+原因」。
**师:** 这叫「用代码测试代码」。以后你每次改完代码打开测试脚本跑一遍5 秒看完所有结果,知道改了哪里有没有破坏原来的逻辑。
**师:** 注意——测试脚本必须在全新窗口 D 生成。为什么?因为如果你在窗口 C 生成测试脚本AI 知道自己刚刚写了什么代码,它的测试会偏向「帮自己的代码辩护」——故意写成能通过的测试,而不是真正验证逻辑是否正确。
**师:** 独立窗口 D让一个「什么都不知道」的 AI 来写测试,它才会真的按需求文档来验证。
【投屏展示窗口 D 测试脚本提示词见第5节演示把需求文档粘贴进去提交】
【投屏展示测试脚本的运行结果4条全部✅效果直观】
**师:** 这 4 条测试验证了什么——
```
测试 1ATK=15, DEF=5 → 伤害=10 ✅
测试 2ATK=5, DEF=10 → 伤害=1最低
测试 3SPD=8 vs SPD=5 → SPD=8 先手 ✅
测试 4ATK=10, DEF=2, 重击 → 伤害=14 ✅
```
**师:** 现在我把伤害公式故意改错——把「ATK - DEF」改成「ATK × DEF」再跑一遍。
【演示:故意修改代码,重跑测试脚本,出现 ❌ 失败】
**师:** 你们看——测试脚本立刻告诉我「测试1失败期望10实际75」。这就是测试脚本的价值改完代码立刻能发现问题不用自己重新点一遍。
**学生实践 (Practice): (8分钟)**
**师:** 现在你们来做。打开全新窗口 D用测试脚本提示词把你的需求文档粘贴进去生成测试脚本保存为 pk-test.html浏览器打开看结果。
> 教师走动观察重点:
> - 是否有学生在窗口 C 生成测试脚本(违反独立窗口原则)?立刻叫停,强调「必须是窗口 D全新对话」
> - 学生的测试结果有 ❌ 吗?引导他们找对应的需求条款,而不是直接改代码
> - 进度快的学生:引导拓展任务——「让 AI 帮你写一条需求里没有的边界测试,看是否通过」
**进度同步 (Checkpoint): (2分钟)**
**师:** 谁的 4 条测试全部通过的举手。
**师:** 有没有哪条测试失败了的?能说一下是哪条,失败的原因是什么?
**生:** 预期「测试3失败了说期望8先手但实际是5先手」
**师:** 这就是测试脚本的价值——它告诉你具体哪里不对。现在打开你的需求文档,找「先手机制」那条,看看写的是什么,再对照你生成的代码,找差异。这才是正确的调试方式。
【诊断点:学生是否能从「❌失败」的输出里,找到对应的需求文档条款进行溯源】【应用层】
**【分支A】若学生能自己完成溯源**
**师:** 你刚才做的就是「测试驱动调试」——测试报告告诉你哪里不对,你去需求里找根因,然后修代码。这是专业开发者的工作方式。
**【分支B】若学生看到 ❌ 直接去改代码而不溯源:**
**师:** 等等——你要改什么?测试说失败,但测试是按需求文档验证的。先问:你的需求文档里这条是怎么写的?再问:代码里是不是按这条写的?最后才改代码。
**【分支C】若学生的测试脚本全部通过但游戏实际有 bug**
**师:** 这很有趣——测试通过但游戏有 bug说明两件事之一第一测试脚本用的是独立实现和游戏代码逻辑不一样第二你的 bug 不在测试覆盖的范围里——是一个「需求没写到的边界情况」。你知道是哪种吗?
(引导学生区分「需求定义的 bug」和「需求未覆盖的 bug」
---
**第三幕:反思 (Contemplate) — 10分钟** 🤔
*本幕目标:两学生角色现场对战演示(投屏全班围观),展示「同一规则、不同角色」下的策略差异*
**【环节】角色对战演示 (6分钟)**
**师:** 好,现在我们来见证今天最重要的时刻——让两个同学的角色真的打一场。
【选两个进度最快的学生,把他们的 pk-battle.html 分别投屏,或者其中一个学生的对战画面投屏全班观看】
**师:** 我们先看左边——这个角色是什么打法?
**生(观察者):** (预期:高攻击型 / 速度型 / 防御型)
**师:** AI 对手用的是默认属性。先看第一回合谁先出手——
【运行对战,全班实时观看,教师边打边念战斗日志】
**师:** 看到没先手机制起作用了——SPD 高的先出手。现在玩家用重击——
【展示重击效果,强调伤害计算是按需求文档的公式来的】
**师:** 这场对战里有哪条规则你们觉得体现得最清楚?
**生:** (预期:先手 / 格挡减伤 / 特技限制次数)
**【环节】互评与讨论 (4分钟)**
**师:** 现在回顾今天的工作。今天你们打开了几个窗口,每个窗口做什么?
**生:** (预期:窗口 A 写需求,窗口 B 找边界,窗口 C 生成代码,窗口 D 做测试)
**师:** 对。这四个窗口,缺一个会出什么问题?比如如果跳过窗口 B——
**生:** (预期:边界情况没想到,游戏对战时可能出 bug
**师:** 如果窗口 D 不开新窗口,在窗口 C 里让 AI 测自己的代码——
**生:** 预期AI 会偏袒自己,测试结果不可信)
**师:** 今天遇到最大的挑战是什么?
**生:** (预期 A「边界情况想不到」/ 预期 B「看懂测试失败的原因」/ 预期 C「导入 Spritesheet」
**师:** 你们今天写需求、审核、生成、验收、测试——5 个步骤。这 5 步,哪一步对你来说最有收获?
**生:** (开放回应,教师倾听,不评判)
**师:** 我来说说我的观察——今天做得最好的事,是大家在遇到 bug 时,第一步不是「让 AI 帮我改」,而是先问「哪条需求没说清楚」。这个习惯,今天有人做到了,有人还在培养。没关系——这个习惯养成了,你做任何项目都会比别人少踩很多坑。
---
**第四幕:延续 (Continue) — 5分钟** 🚀
**【环节】抽象总结 (3分钟)**
**师:** 今天我们做了一件很重要的事——让「脑子里的规则」变成「代码里真正执行的规则」,中间经过了几个步骤?
**生:** (预期:写需求、找边界、生成代码、验收、测试脚本)
**师:** 对。这个流程不只是做游戏用的——以后你做任何项目,只要涉及「规则」,都要走这个流程。规则越复杂,「找边界」这步就越重要。
**师:** 今天你们掌握的能力有一个名字,叫**「测试驱动验证」**——先定规则,再写代码,再用测试检查代码是不是真的按规则跑。这是真实开发团队的工作方式,不是只有高手才能用的,你们今天已经用上了。
**师:** 还有一个能力——「边界意识」。以后遇到任何系统你的第一反应不是「正常情况怎么用」而是「边界情况、异常情况怎么处理」。这个意识让你的系统更稳定bug 更少。
**师:** 边界意识不只是写代码时用的。你们有没有玩过一个游戏,有个 bug 特别烦——比如某个角色在特定情况下无敌,或者某个技能叠加 20 层秒杀对手——这些 bug 从哪里来?就是设计师在写规则的时候,没有考虑到「如果玩家这样做怎么处理」。你们今天练习的,就是这个能力。
**【环节】下节预告 + 5分钟挑战 (2分钟)**
**师:** 现在你们的战斗系统能跑,逻辑是对的,但角色还是矩形占位符。下节课我们做什么?
**生:** (预期:换成自己的图?/ 加动画?)
**师:** 对——下节课我们把你的 Spritesheet 真正加进战斗系统,受击有闪烁效果,攻击有前摇后摇,死亡有倒下动画。你的角色会真的「活起来」。
**师:** 本周 5 分钟 AI 挑战——让 AI 帮你写一条需求文档里没有的边界情况测试,提交到测试脚本里,看是否通过。如果通过了,说明你的代码比需求文档还严格;如果没通过,说明你发现了一个新 bug。下节课分享。
**师:** 最后一件事——在 pk-battle.html 的顶部注释里,写上你的角色名、打法定位一句话总结,还有今天你发现的最有意思的一条边界情况。格式随意,只要下节课你打开文件,还能想起今天做了什么。
---
### 5. AI助教使用指南
**教师演示用提示词(窗口 A需求文档整理**
```
你是一个需求分析师。我要做一个基于 HTML/CSS/JS 的回合制战斗游戏,规则如下:
- 先手机制SPD 高的角色先出手;同速时随机决定(或编号小的先手,明确规定一种)
- 伤害公式ATK - DEF最低造成 1 点伤害
- 行动类型:普通攻击(按公式)/ 重击伤害×1.8/ 格挡本回合受伤减少50%/ 特技每场只能用一次效果来自角色JSON的skill字段
- 胜负判定HP≤0 判输,立即结束
- AI对手决策HP低于30%用特技25%概率重击;否则普通攻击
请把这些需求整理成规范需求文档,包含:功能描述、触发条件、功能规则、边界情况说明、验收标准。
```
**边界审核用提示词(窗口 B独立新对话**
```
你是一个游戏测试工程师。以下是战斗系统需求文档请列出所有你能想到的边界情况和异常情况例如同速时谁先出手特技已用完再点会怎样格挡叠加重击怎么算双方同时HP≤0怎么判只列问题不需要解答
[粘贴需求文档]
```
**测试脚本生成(窗口 D独立新对话**
```
以下是我的战斗系统需求文档:
[粘贴需求文档]
请帮我写一个 JavaScript 测试脚本(单文件 HTML验证以下4条规则
1. 伤害公式ATK=15, DEF=5 → 伤害=10ATK=5, DEF=10 → 伤害=1最低1点
2. 先手判定SPD=8 vs SPD=5 → SPD=8 的先出手
3. HP≤0 → 游戏结束标志为 true
4. 重击倍率ATK=10, DEF=2, 重击 → 伤害=(10-2)×1.8=14取整
每条测试显示"✅通过"或"❌失败期望XXX实际XXX"。用纯 HTML/JS不需要 Phaser.js。
```
**学生保底提示词(窗口 C生成战斗系统骨架**
```
请帮我用纯 HTML/CSS/JS单文件做一个回合制战斗游戏
角色数据从 JS 对象读取字段name/hp/maxHp/atk/def/spd/skill
- 玩家角色在左边AI 对手在右边
- 先用彩色矩形代替角色图片(稍后替换)
战斗规则:
- 先手SPD 高的先出手;同速时随机
- 伤害公式ATK - DEF最低 1 点
- 四种行动按钮:普通攻击 / 重击×1.8/ 格挡(本回合受伤-50%/ 特技(每场限用一次)
- AI对手逻辑HP<30%用特技25%概率重击;否则普通攻击
- HP≤0 判输,显示胜负结果,提供「再来一局」按钮
界面要求:
- 双方头顶有 HP 血条(数值显示)
- 底部有战斗日志最近3条
- 特技用完后按钮变灰不可点击
只给骨架,角色图片先用矩形占位,单文件 HTML。
```
**进阶提示词(替换 Spritesheet**
```
以下是我的 pk-battle.html 中绘制角色的代码片段:[粘贴相关代码]
请修改角色绘制逻辑,把左边玩家角色的矩形替换为 Spritesheet 图片显示:
- Spritesheet 文件名player-sprite.png128×64 像素
- 帧1x=0, y=0, w=64, h=64待机状态
- 帧2x=64, y=0, w=64, h=64攻击状态
- 平时显示帧1玩家攻击时显示帧2 持续 300ms 后恢复帧1
- 图片要等比缩放,显示在原来矩形的位置
```
---
### 6. 教师指南
**本课技术备注:**
- **Spritesheet 导入**`new Image()``onload``ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)`。sx/sy 是帧在图片中的起始坐标sw/sh 是帧的宽高dx/dy 是画布上的目标位置dw/dh 是目标大小。教师需要理解这 8 个参数的含义学生不需要记只需知道「帧1=x0帧2=x64」。
- **回合制 vs 实时战斗**:本课做的是回合制(玩家点一次按钮 = 一个回合)。教师不要混淆,不要和「帧循环/requestAnimationFrame」扯在一起那是下节课动画的内容。
- **先手机制的实现**:在回合开始时比较 SPD高的先执行攻击逻辑低的后执行。同速时 `Math.random() < 0.5` 决定。这个逻辑放在「玩家点击行动按钮」的事件处理函数里。
- **格挡状态**:格挡是一个「状态标记」(如 `isBlocking = true`),在本回合受到伤害时检查这个标记,伤害减半后重置标记。注意:格挡对「下一次受到的攻击」生效,还是「本回合」生效,需在需求里明确(本课设计为「格挡后敌方先手攻击时生效」)。
- **测试脚本独立窗口**:这是本课最重要的原则。测试脚本里的战斗逻辑函数是「从需求文档重新实现」的独立版本,不引用 pk-battle.html 的代码——所以必须在独立窗口生成,让 AI 按需求文档写,而不是看着自己的代码写测试。
**常见问题 FAQ**
| 问题 | 应对 |
|------|------|
| 「特技按钮用了还能继续按」 | 引导学生检查需求文档里「特技每场限用一次」的验收标准写了什么,再在代码里找特技的触发逻辑,看有没有加 `skillUsed` 标记 |
| 「测试脚本生成出来全部通过,但游戏实际打起来伤害不对」 | 说明测试脚本和游戏代码用的是两套独立实现。先确认测试脚本按需求文档写,再对照游戏代码里的实现,找两者差异 |
| 「Spritesheet 图片不显示,一片黑」 | 99% 是路径问题——图片文件和 HTML 文件要放在同一个目录,路径写相对路径。让学生把 HTML 和 PNG 放到同一个文件夹再刷新 |
| 「重击的伤害计算和我预期不一样」 | 让学生打开战斗日志,找重击那行,用计算器手算一遍:(ATK - DEF) × 1.8,取整,对比日志里的数值 |
| 「AI 对手一直用特技,根本不普通攻击」 | AI 对手的决策逻辑里「HP<30%用特技」的判断可能有 bug——HP 初始值设置不对,或者条件写反了。引导学生检查 AI 对手的 maxHp 和当前 hp 的比较逻辑 |
| 「窗口 B 没问出什么问题」 | 提示学生在提示词末尾加一句:「请特别关注:同速先手、特技用完再点、格挡叠加重击、双方同时归零 这四个场景」 |
| 「测试脚本里 ✅ 全通过,但我不知道这说明什么」 | 说明你的战斗逻辑函数在这 4 种情况下是正确的。测试脚本是「护栏」——以后你改代码,再跑一次,如果还是全通过,说明你没有破坏原来的逻辑 |
| 「怎么知道 AI 对手「25%概率重击」是不是真的 25%?」 | 这是个好问题。严格测试需要跑 100 次统计分布,但我们的课堂不做这个。你可以告诉 AI「请解释这段 AI 决策代码里重击概率是如何实现的」,让 AI 用中文解释给你看 |
**课堂风险预案:**
- **如果 AI 服务不可用Kimi 宕机)**:切换到 Trae IDE 的内置 AI 对话,或使用教师备用的 demo-2-pk-battle.html 直接展示;学生完成需求文档部分,代码生成推迟
- **如果学生进度差异过大**:进度快的学生做拓展(导入 Spritesheet + 写边界测试);进度慢的学生保证完成「战斗骨架能跑通 + 普通攻击验收通过」即可,其余留作课后
- **如果有学生上节课的 Spritesheet 未完成**:提供默认占位图(单色 128×64 PNG确保不因图片问题卡住当天进度
---
### 7. 5分钟日常AI挑战
**本周挑战:** 让 AI 帮你写一条「需求文档里没有的」边界测试,看看能不能通过
**挑战说明:**
打开窗口 D全新对话告诉 AI「我的战斗系统需求文档里有这些规则[粘贴你的需求文档]。请帮我写一条我没有明确写进需求的边界测试——就是那种「正常情况不会想到,但真实对战时可能出现」的场景。」把这条新测试加入你的 pk-test.html运行看是通过还是失败。把结果截图或描述带到下节课分享。
**下节课分享:** 下节课选 2-3 位同学展示——「我写的新边界是什么,测试结果如何,有没有发现 bug」
---
### 8. 拓展任务
**拓展一(推荐):** 把你的 Spritesheet 真正导入 pk-battle.html`drawImage` 替换矩形占位符;不需要动画,只要图片能显示在正确位置。验收标准:打开游戏,左边角色是你自己画的图,不是矩形。
**拓展二(挑战):** 给你的战斗系统加一条新的行动类型:「反击」——格挡时如果对方用了重击,本回合额外反弹 30% 伤害给对方。先把这条规则写进需求文档,在窗口 B 审核边界情况(格挡+反击叠加怎么算?反击触发条件是什么?),然后在窗口 C 生成新代码,在窗口 D 补充测试用例,确保测试通过。
**拓展三(终极挑战):** 做一个双人对战模式——两个玩家分别控制左边和右边的角色,轮流点行动按钮。需求文档里要写清楚:轮次如何切换、一方操作完后如何提示另一方、胜负后如何重新开始。先写需求,再生成,再测试。
---
> 本教案遵循穹狼科创 SDDT + 4C 教学方法论编写,配合 `教学方法论规则.md` 和 `标准教案模板.md` 使用。