diff --git a/3-lessons/AICODE-06/AICODE-06课程大纲.md b/3-lessons/AICODE-06/AICODE-06课程大纲.md index 3ef0bc5..4cd0a0b 100644 --- a/3-lessons/AICODE-06/AICODE-06课程大纲.md +++ b/3-lessons/AICODE-06/AICODE-06课程大纲.md @@ -17,6 +17,60 @@ --- +--- + +## 项目实战阶段:魔幻俄罗斯方块(第6-7课) + +> 面向已完成前5课的 AICODE-06 学员。以俄罗斯方块为载体,系统训练工程师思维:Plan Mode 先行、需求审核、自动测试、新窗口原则。 + +| 课时 | 课程主题 | 学习目标 | 核心概念 | 核心工具 | +|:----:|---------|---------|---------|---------| +| 6 | 魔幻俄罗斯方块(上)— Plan Mode 先行 | • 掌握 Plan Mode 三步流程:整理需求 → 需求审核 → 确认需求
• 理解需求质量 = 输出质量:需求越详细,AI 执行越准确
• 建立新窗口原则:审核必须在新窗口进行,避免上下文污染
• 能独立完成「需求文档 → 审核 → 生成 → 验收 → 结果溯源」完整闭环 | Plan Mode、需求文档、需求审核、结果溯源、新窗口原则、上下文污染 | Kimi 2.5 | +| 7 | 魔幻俄罗斯方块(下)— 魔改升级 + AI 自动测试 | • 掌握增量需求文档:在已有基础上只写新增功能
• 理解自动化测试:让 AI 生成测试脚本替代手动验收
• 能读懂测试脚本 ✅❌ 结果并溯源修复
• 建立「测试通过才算完成」的质量意识,利用测试脚本安全做第二版、第三版 | 自动化测试、测试覆盖、边界条件、增量需求、新窗口原则 | Kimi 2.5 | + +**两课核心工作流:** + +``` +Plan Mode(新窗口A:整理需求) + ↓ +需求审核(新窗口B:AI扮演审核工程师) + ↓ +执行生成(新窗口C:Kimi生成代码) + ↓ +手动验收 → 感受手动测试的局限 + ↓ +AI生成测试脚本(新窗口D:自动测试) + ↓ +测试全部 ✅ → 有了安全网 → 放心做第二版、第三版 +``` + +--- + +## 项目实战阶段:涂鸦PK(第8-11课) + +> 在工程流程(Plan Mode + 测试)已内化的基础上,以「自绘角色对战游戏」为载体,训练数据驱动设计、增量需求迭代、和设计决策表达力。 + +| 课时 | 课程主题 | 学习目标 | 核心能力 | 核心产出 | +|:----:|---------|---------|---------|---------| +| 8 | 涂鸦PK(一)— 画图工具 + 角色设计 | • 能用需求文档驱动生成自己的HTML5画图工具
• 能画出两帧角色Spritesheet(帧1待机+帧2攻击)
• 理解20分属性预算制,能根据打法定位分配属性 | 拆解力、审美力 | 自制画图工具 + 角色Spritesheet(128×64 PNG)+ 角色属性JSON | +| 9 | 涂鸦PK(二)— 基础对战系统 | • 能用需求文档描述战斗规则(公式/先手/特技),让AI生成完整对战系统
• 理解边界情况的重要性:需求文档必须覆盖所有异常情况
• 能用AI在新窗口生成测试脚本,验证伤害公式和胜负判定 | 拆解力、韧性力 | 可对战的PK系统(有血条/四种行动/AI对手)+ 测试脚本验证报告 | +| 10 | 涂鸦PK(三)— 动画 + 音效 + 特技 | • 能用自然语言描述动画「感觉」,让AI实现Phaser Tween动画
• 理解Web Audio API:用代码合成音效,零外部素材依赖
• 掌握增量需求写法:只写新增部分,不重写已验收功能 | 审美力、提问力 | 有完整动画+音效+特技特效的战斗体验版 | +| 11 | 涂鸦PK(四)— 班级锦标赛 | • 理解数据驱动设计:加JSON文件=加角色,不改代码
• 能用增量需求实现roles角色系统(从文件夹读取所有角色)
• 能用3分钟路演清晰表达设计决策(定位+意图+复盘) | 表达力、共创力 | roles系统 + 班级角色锦标赛 + 设计决策路演 | + +**四课核心工作流(延伸自第6-7课工程流程):** + +``` +需求驱动(窗口A整理 → 窗口B审核 → 窗口C执行) + ↓ +测试验证(窗口D生成测试脚本 → 验证核心逻辑) + ↓ +增量迭代(只写新增需求 → 已验收功能不重写) + ↓ +数据驱动扩展(加文件=加功能 → 代码与数据分离) +``` + +--- + ## 合流说明 > **合流时间点待定。** 原计划第5课合流,但考虑到 AICODE-03 学生打字和表达能力的成长节奏,合流点可能后延。 diff --git a/3-lessons/AICODE-06/AICODE06-06 魔幻俄罗斯方块(上).md b/3-lessons/AICODE-06/AICODE06-06 魔幻俄罗斯方块(上).md index f12e12d..b58f889 100644 --- a/3-lessons/AICODE-06/AICODE06-06 魔幻俄罗斯方块(上).md +++ b/3-lessons/AICODE-06/AICODE06-06 魔幻俄罗斯方块(上).md @@ -1,6 +1,6 @@ --- 课时: 6 -主题: 魔幻俄罗斯方块(上)— 工程师思维启蒙 +主题: 魔幻俄罗斯方块(上)— Plan Mode 先行 核心能力: [提问力, 拆解力] 核心工具: [Kimi 2.5] 时长: 90分钟 @@ -11,8 +11,8 @@ ### 1. 课程目标 **知识目标:** -- 理解「需求文档」的作用:把脑子里的想法变成 AI 能准确执行的指令 -- 理解「需求质量 = 输出质量」:AI 做出来的结果不符合预期,根本原因是需求没说清楚 +- 理解「Plan Mode(计划模式)」的概念:无论做什么,都要先开启计划模式,把需求写清楚再执行 +- 理解「需求质量 = 输出质量」:需求写得越详细,AI 执行越准确;需求写不清楚,执行过程中就会出问题 - 理解需求是迭代的过程,不是一次写完就能用 **能力目标:** @@ -21,7 +21,7 @@ - 能在看到生成结果后,定位是哪条需求没说清楚,修改并重新生成(共创力) **情感目标:** -- 建立「先想清楚再动手」的工程师直觉,体验「需求清晰 → 结果可预期」的成就感 +- 建立「先开 Plan Mode,再动手」的习惯——这是课程中所有项目的第一步,不可跳过 - 对「自己也能做出一个游戏」产生真实的兴奋感 - 建立「结果不对 = 需求没说清楚」而不是「AI 不行」或「我不行」的归因习惯 @@ -33,10 +33,11 @@ | 概念 | 学生类比 | 认知层级 | |------|---------|---------| +| Plan Mode(计划模式) | 盖房子前先画图纸——没有图纸直接开工,盖到一半发现方向错了,拆掉重来比画图纸贵十倍 | 理解层 | | 需求文档 | 装修前给师傅的设计图——口头说「弄好看点」和给一张详细图纸,结果完全不同 | 理解层 | | 需求压力测试 | 考试前找同学互出题——让别人挑毛病比自己检查更有效 | 应用层 | | 结果溯源 | 菜做咸了,往回找:是盐放多了,还是酱油放多了?找到根源才能改 | 应用层 | -| 需求迭代 | 第一版草稿 → 发现问题 → 修改 → 第二版,就像改作文 | 理解层 | +| 新窗口原则 | 让同一个同学既写作文又给自己改错,他永远改不出来——必须换一个人来审。审核、测试、评审全部要开新窗口,让「新的 AI」来做,才不会被原来的上下文带跑偏 | 应用层 | **典型误概念表:** @@ -46,7 +47,9 @@ | M2 | 需求文档写完就是写好了,直接提交 | 写完只是第一步,要经过压力测试才能发现漏洞 | 用「压力测试」提示词,让 AI 提出学生自己没想到的问题 | | M3 | AI 做出来的结果不对是 AI 的问题 | 结果不对说明需求里有没说清楚的地方 | 「你的需求文档里有没有写这一条?」——让学生自己发现根本没写 | | M4 | 需求文档要写得很长很详细 | 精准 > 冗长。需求要「可测试」:能说出什么情况下算做对了 | 「你这条需求,我怎么知道 AI 做没做对?」 | -| M5 | 先动手做,遇到问题再想 | 先想清楚的时间,会节省后面改来改去的时间 | 对比两种路径的时间消耗:「先做 → 改 → 改 → 改」vs「先想清楚 → 做 → 小改」 | +| M5 | 先动手做,遇到问题再想 | 跳过 Plan Mode 直接做,出了问题再改来改去,总时间反而更长 | 对比两种路径:「跳过计划 → 做 → 改 → 改 → 改」vs「Plan Mode → 做 → 小改」 | +| M6 | 需求审核是在挑代码的问题 | 需求审核阶段只审需求本身——哪里没说清楚、哪里有歧义,跟代码无关 | 「AI 现在还没写一行代码,怎么可能审代码问题?」 | +| M7 | 在同一个对话框里写需求、审核、执行、迭代全部搞定 | 这叫「上下文污染」——AI 会被之前的对话带着走,审核时会偏向为自己生成的内容辩护。正确做法:写需求在一个窗口,审核开新窗口,执行再开一个窗口 | 演示:在写了需求的窗口里让 AI 审核自己,AI 的回答会非常保守;换新窗口审核,AI 会找出更多问题 | --- @@ -75,159 +78,368 @@ ### 4. 教学流程 +--- + **第一幕:联系 (Connect) — 10分钟** 🔗 +*本幕目标:通过「侦探模式」玩游戏,让学生主动发现俄罗斯方块的规则;展示「一句话版」对比引出 Plan Mode 的价值,建立「先写需求再动手」的第一印象* + **【环节】侦探模式导入 (10分钟)** **师:** 今天我们要做一个游戏。但在做之前,先玩两分钟。 + 【投屏展示俄罗斯方块,或让学生在自己电脑上打开】 **师:** 你们的任务不是拿高分,而是当侦探——把这个游戏所有的规则找出来,写在纸上。你能找到多少条就写多少条。两分钟,开始。 -【学生玩游戏同时记录规则,教师走动观察学生找到了哪些规则】 + +> 教师走动观察:学生在记录哪些规则,是停在「方块会下落」这种表层,还是注意到了「碰到边界会停」「满行才消除」这类细节规则。不要打扰,只观察。 **师:** 好,停。谁来说一条规则? -**生:** 方块会往下落。 -**师:** 好,这是一条。还有呢? -**生:** 可以左右移动,可以旋转。满一行就消掉。 -**师:** 不错。这些都是游戏规则。现在我问一个问题——如果我让 AI 帮我做这个游戏,我直接说「帮我做一个俄罗斯方块」,你们觉得 AI 能做出来吗? -**生:** 能!/ 应该能? + +**生:** (预期:方块会往下落) + +**师:** 好,这是一条。写得比较浅,但没错。还有呢? + +**生:** (预期:可以左右移动,可以旋转) + +**师:** 对,左右移动、旋转。还有没有发现更多的? + +**生:** (预期:满一行就消掉) + +**师:** 消行——这个很关键。消了之后上面的积木会怎样? + +**生:** (预期:往下掉 / 往下移一行) + +**师:** 对,会往下补。还有吗?积木碰到边界的时候会怎样? + +**生:** (预期:停下来,不能再移了) + +**师:** 对,碰到边界就停,不能移出去。那碰到底部呢? + +**生:** (预期:就固定在那里了) + +**师:** 对,固定住,不动了。那什么时候游戏结束? + +**生:** (预期:积木堆到顶了就结束) + +**师:** 好——你们刚才说出来的这些,就是俄罗斯方块的基本规则。你们注意没有——这些规则,全是游戏的「需求」。每一条都是「这个游戏应该怎么运行」。 +【识别层:让学生意识到「游戏规则 = 需求描述」】 + +**师:** 现在我问一个问题——如果我让 AI 帮我做这个游戏,我直接说「帮我做一个俄罗斯方块」,你们觉得 AI 能做出来吗? + +**生:** (预期:能!/ 应该能?) + **师:** 我们来试试。 + 【投屏展示教师提前生成的「一句话版」俄罗斯方块】 **师:** 做出来了。但你们来找找看,这个游戏里,有没有什么地方跟你心里想的「俄罗斯方块」不一样? + +> 教师给 20 秒让学生仔细看屏幕,甚至可以让一个学生上来玩几秒 + 【诊断点:学生是否能发现 AI 自作主张的细节——比如得分规则、速度、旋转方向等】【识别层】 **【分支A】若学生发现了不同的地方:** **师:** 你发现了。为什么 AI 做出来跟你想的不一样? -**生:** 因为我没有告诉它…… -**师:** 对!你没说,AI 就自己猜了一个。今天我们要学的,就是怎么把「脑子里的游戏」变成 AI 能准确执行的指令。这个东西叫需求文档。 + +**生:** (预期:因为我没有告诉它……) + +**师:** 对!你没说,AI 就自己猜了一个。这就是我们今天要解决的问题。 + +**师:** 从今天开始,我们做任何项目,第一步都是同一件事——**开启 Plan Mode(计划模式)**。Plan Mode 只做一件事:在动手之前,把你的需求写得越详细越好。需求写得越详细,AI 执行越准确;需求写不清楚,AI 就自己猜,猜出来的东西可能跟你想的完全不一样。 +【识别层:建立「Plan Mode 先行」的第一印象】 **【分支B】若学生觉得「都一样,没问题」:** **师:** 那我问你——这个游戏消一行得多少分?消四行一次呢? + **生:** (去看)……好像是 100 分? + **师:** 你想要的是这个分数吗? + **生:** 我没想过…… -**师:** 你没想过,AI 就帮你决定了。如果你想要自己的规则,就需要告诉 AI。这就是需求文档的意义。 + +**师:** 你没想过,AI 就帮你决定了。Plan Mode 就是在动手之前,把所有「你没想过」的地方都想清楚,写在文档里,让 AI 按你想的来做。 --- **第二幕:建构 (Construct) — 65分钟** 🛠️ -**【分段一:写 Level 0 需求文档】(20分钟)** +*本幕目标:完整走完 Plan Mode 三步——整理需求、需求审核、确认需求;再走完「提交生成 → 验收 → 结果溯源」的执行闭环;建立「需求驱动输出」的核心工作习惯* + +--- + +**【分段一:开启 Plan Mode — 第一步:整理需求】(20分钟)** + +*本段重点:学习 Plan Mode 三步总览,填写 Level 0 需求文档模板,建立「需求可测试性」的直觉* **预设误概念:** -- 误概念 M1:「帮我做俄罗斯方块」就够了,不需要写文档 +- 误概念 M1:「帮我做俄罗斯方块」就够了,不需要 Plan Mode - 误概念 M4:需求文档要写得很长很全面 -**讲解与演示 (Teach & Demo): (5分钟)** +**讲解与演示 (Teach & Demo): (7分钟)** + +**师:** 现在我们正式开启 Plan Mode。Plan Mode 分三步走,我们先把三步过一遍,再动手。 + +**师:** **第一步——整理需求。** 把你想要的游戏写成一份需求文档。这一步的目标是:把你脑子里「模糊的感觉」变成「具体可以测试的文字」。就像设计师画图纸——不是说「大概这个形状」,而是标出每个尺寸。 + +**师:** **第二步——审核需求。** 写完不等于写好。让 AI 扮演一个审核工程师,专门找你文档里没说清楚的地方。它不帮你回答,只问问题——「这里如果出现了 XXX 情况,怎么处理?」 + +**师:** **第三步——确认需求。** 把审核工程师问的问题,一条条回答,补充进你的文档。这样你的需求文档才是「经过压力测试的版本」,可以提交给 AI 执行了。 + +**师:** 三步走完,才动手生成。听起来麻烦?我来给你算一笔账—— + +【投屏展示对比】 + +``` +路径一(跳过 Plan Mode): +说一句话 → AI 做出来 → 不对 → 让 AI 改 → 还不对 +→ 再改 → 加乱了 → 从头来 → 又不对……(无限循环) + +路径二(Plan Mode 先行): +写需求文档 10分钟 → 压力测试 5分钟 → AI 做出来 +→ 小幅微调 → 完成! +``` + +**师:** 路径一的「快」是假的快,路径二的「慢」是真的快。 + +**师:** 好,现在进入第一步。我给你们一个 Level 0 需求文档模板,里面有 5 个必须填的部分。 -**师:** 现在我们要写一份需求文档。我给你们一个模板,里面有 5 个必须填的部分。 【投屏展示 Level 0 需求文档模板,见第5节】 -**师:** 这 5 个部分,每一个都是 AI 「必须知道才能做对」的信息。我们来看第一条——游戏区域:宽多少列、高多少行? -**生:** 10×20? -**师:** 这是默认值,但你可以改。重点是:你必须明确告诉 AI,否则它自己决定。 +**师:** 这 5 个部分,每一个都是 AI「必须知道才能做对」的信息。我带你们看一遍每个字段是什么意思—— -**师:** 有一个原则:每条需求,你都要能说出「什么样的结果算做对了」。比如「消行规则:横向填满一整行就消除」——这条我怎么测试? -**生:** 把一行填满,看它有没有消掉。 -**师:** 对,这条可以被测试。好的需求就是这样——写完之后,你知道怎么验收。 +**师:** 第一部分「游戏区域」——游戏画面有多大?10列×20行是经典俄罗斯方块的标准尺寸,你可以改,也可以保持默认。这条如果不写,AI 可能给你做个 6×6 的迷你版,也可能做个 20×40 的超高版。 + +**师:** 第二部分「方块移动规则」——注意这里有一个关键字段:「碰到左右边界」。这条要写清楚。什么意思?就是方块走到最边上了,再按左/右键,会发生什么? + +**生:** (预期:就停下来不动 / 不能再往那边移了) + +**师:** 对。但如果你不写,AI 可能给你做出一个方块可以穿过边界、从另一侧出来的效果——像贪吃蛇穿墙那种。你想要这个效果吗? + +**生:** (预期:不想!/ 哦那要写清楚) + +**师:** 所以每一条都得写。第三部分「消行规则」,这里特别要注意「验收标准」这个概念——每条需求,你都要能说出「什么样的结果算做对了」。 + +**师:** 比如「消行规则:横向填满一整行就消除」——我怎么测试这条需求 AI 做没做对? + +**生:** (预期:把一行填满,看它有没有消掉) + +**师:** 对。能被测试的需求,才是写清楚了的需求。反过来,「游戏体验要流畅」——这条能测试吗? + +**生:** (预期:不能……怎么叫流畅?) + +**师:** 对,「流畅」是感受,不是能测试的需求。如果要写,你得改成「初始速度每800毫秒下落一格」——这才是可以测试的。 【理解层:建立「需求可测试性」的直觉】 -**学生实践 (Practice): (13分钟)** +**学生实践 (Practice): (11分钟)** -学生独立填写 Level 0 需求文档模板,完成 5 个必填部分。 +**师:** 现在开始填。5 个部分,把模板里的空格全填上。不确定的地方保持默认值也可以,但不能空着不填。 > 教师走动观察重点: > - 是否有学生在「移动规则」里只写了「可以左右移动」,但没写「碰到边界怎么处理」? > - 是否有学生在「消行规则」里写了消行但没写「消多行的得分是否不同」? -> - 这些漏洞不要直接告诉学生,留给下一步「压力测试」去发现 +> - 是否有学生把「游戏体验流畅」这类不可测试的需求填进去了? +> - 这些漏洞先不要直接告诉学生,留给下一步「压力测试」去发现 **进度同步 (Checkpoint): (2分钟)** **师:** 5个部分都填完的举手。 -**师:** 好,你觉得你的需求文档,AI 能根据它做出你想要的游戏吗? -**生:** 应该可以? -**师:** 我们来测试一下你写的文档够不够清楚。 + +**师:** 好,先不着急提交。我来问你一个问题:按照你写的需求,一个不认识这个游戏的人拿到这份文档,能不能把一局游戏从头玩到结束——开始游戏、移动方块、消行、游戏结束?这个流程能跑通吗? + +**生:** (预期:能?/ 好像……方块怎么消行没写清楚?/ 游戏结束之后怎么重新开始没写) + +**师:** 对,就检查这一件事——游戏流程能不能跑通。先别想加什么特殊功能,那是后面的事。 + +【诊断点:学生的需求是否覆盖了「开始→玩→消行→升级→结束」这个基础流程】【理解层】 --- -**【分段二:AI 压力测试 → 完善需求文档】(15分钟)** +**【分段二:Plan Mode 第二步:需求审核】(20分钟)** + +*本段重点:用 AI 扮演审核工程师对需求做压力测试,区分「审需求」和「审代码」,发现自己看不见的漏洞* **预设误概念:** -- 误概念 M2:需求文档写完就可以直接提交了 -- 误概念 M3:AI 生成不对是 AI 的问题 +- 误概念 M2:需求文档写完就可以直接提交执行了 +- 误概念 M6:需求审核是在挑代码的问题 -**讲解与演示 (Teach & Demo): (3分钟)** +**讲解与演示 (Teach & Demo): (5分钟)** -**师:** 接下来用一个技巧——让 AI 扮演挑剔的工程师,来「审问」你的需求文档。 -【投屏展示「压力测试」提示词,见第5节】 +**师:** 需求文档写完了,进入 Plan Mode 第二步——需求审核。在做这一步之前,我要告诉你们一个非常重要的规则:**审核必须在新窗口进行。** -**师:** 注意这里:不是让 AI 帮你补全需求,是让 AI 问你问题。这两个完全不同——一个是 AI 替你决定,一个是 AI 帮你发现你自己没想到的地方。 -**师:** 我来演示一次。 -【教师用自己的需求文档执行压力测试,展示 AI 提出的问题列表】 +**师:** 为什么一定要新窗口?因为 AI 有一个特质——它不会主动承认自己的问题。你在同一个窗口里跟它说「帮我看看需求有没有问题」,它会被之前的对话「污染」,倾向于觉得「之前做得挺好的」。这叫**上下文污染**。 -**师:** AI 问了我哪些问题?有哪些是你们的需求文档里也没有答的? +**师:** 打个比方——让同一个同学既写作文又给自己改错,他永远改不出大问题。必须换一个没看过你作文的同学来审,他才会发现真正的漏洞。换新窗口,就是换一个「什么都不知道」的新 AI 来看,它没有偏见,才会客观地找出问题。 -**学生实践 (Practice): (10分钟)** +**师:** 记住这条规则,以后做任何项目都要遵守:**写需求——一个窗口;审核需求——新窗口;执行生成——再新一个窗口。** 不同阶段,不同窗口,互不干扰。 +【投屏展示「需求审核」提示词,见第5节】 + +**师:** 现在的操作是:复制你的需求文档内容,打开一个全新的 Kimi 对话,把审核提示词粘贴进去。注意——审核的不是代码,是需求本身。审核工程师只负责问问题,不帮你回答,不帮你修改。 + +**师:** 我来演示一次。我把自己的需求文档粘贴进去,看 AI 会问什么问题。 + +【教师用自己的需求文档执行审核,投屏展示 AI 提出的问题列表】 + +**师:** 你们看,AI 问了我这些问题——我们一起来分析分析: + +**师:** 第一个问题:「方块旋转到边界时,如果旋转后的形状超出边界,是直接禁止旋转,还是自动向内移动?」——我的文档里有没有写这条? + +**生:** (看文档)……没有…… + +**师:** 对,我没写。这个「踢墙旋转」问题我根本没想到。接着看—— + +**师:** 第二个问题:「如果方块落下时速度极快(玩家按了加速键),落地瞬间玩家还没松开方向键,方块会继续移动吗?」——我的文档里呢? + +**生:** 也没写…… + +**师:** 再看第三个——「当积木消除多行时,是一行一行消,还是同时消除?视觉效果有没有要求?」——我写了得分,但消除的视觉顺序有没有说清楚? + +**生:** 没说…… + +**师:** 最后一个——「游戏结束画面,除了「游戏结束」和得分,还需要「重新开始」按钮吗?」——这条很关键,游戏结束了玩家怎么重玩? + +**生:** 对!要有重新开始。 + +**师:** 你看——四个问题,我的文档里一条都没写。这不是 AI 在刁难我,是它在帮我找漏洞。这就是「需求审核」的价值。 +【识别层:直观感受审核的价值,澄清 M6 误概念——这些问题全是「需求层面」,跟代码无关】 + +**学生实践 (Practice): (12分钟)** 1. 学生把自己的需求文档粘贴进「压力测试」提示词,提交 Kimi -2. 把 AI 提出的问题复制到文档里 -3. 逐条回答——每个问题写上自己的答案,补充进需求文档 +2. 把 AI 提出的问题复制下来 +3. 逐条读问题,判断哪些问题「我真的没想到」,哪些「我已经写了但 AI 没看清楚」 +4. 对「真的没想到」的问题,写上自己的回答,补充进需求文档 -> 教师走动观察:学生是否对某个问题感到惊讶——「这个我真的没想过」是好的信号 +> 教师走动观察重点: +> - 学生是否对某个问题感到惊讶——「这个我真的没想过」是好的信号,主动靠近问「这个问题你打算怎么回答?」 +> - 学生是否对 AI 的问题感到不耐烦「这些问题没必要」——这是 M6 误概念的表现,需要介入 +> - 学生是否在逐条认真回答,还是全部跳过直接提交——走过去让学生读出一条来分析 -**进度同步 (Checkpoint): (2分钟)** +**进度同步 (Checkpoint): (3分钟)** -**师:** AI 问了你最意外的是哪个问题? -**生:** (分享1-2条) -**师:** 如果不补上这条,AI 会自己猜一个答案。那个答案不一定是你想要的。 -【识别层:建立「每个没说清楚的地方,AI 都会自己决定」的意识】 +**师:** AI 审核出来,问了你最意外的问题是哪条?谁来说说? + +**生:** (预期 A:「方块落到底部前能不能再移动」我没想到) + +**生:** (预期 B:「游戏结束要不要有重玩按钮」) + +**师:** 很好。这就是 Plan Mode 第二步的价值——你自己看不出来的漏洞,让 AI 来挖。 + +【诊断点:学生能否说出「因为 AI 问了这个问题,我补充了 XXX 这条需求」】【理解层】 + +**【分支A】若学生能说出具体被触发的漏洞:** +**师:** 对,你补充了这条之后,需求文档就更完整了一步。这就叫「需求迭代」——不是一次写完,是一次次补充完善。 + +**【分支B】若学生说「AI 问的问题我都已经写了,没有漏洞」:** +**师:** 好,那你现在需求文档里,有没有写「方块旋转到边界时怎么处理」? +(引导学生发现一个真实存在的漏洞,避免学生误以为文档已经完整) + +**【分支C】若学生觉得「AI 问的这些问题都不重要,不影响游戏」:** +**师:** 我们来测试一下——现在先不补充这条,等 AI 做出来,如果这个情况出现,游戏会怎样? +(用结果验证的方式让学生自己发现「小漏洞可以让整个游戏崩掉」) + +**师:** 现在进入第三步:回答这些问题,把需求补充完整,然后提交生成。 --- **【分段三:提交生成 → 验收 → 结果溯源】(20分钟)** +*本段重点:建立「按需求逐条验收」的习惯;发现问题时用「结果溯源」找需求根源,而非直接改代码* + **预设误概念:** - 误概念 M3:生成完了就算完成了,不需要验收 - 误概念 M3:结果不对直接改代码 -**讲解与演示 (Teach & Demo): (3分钟)** +**讲解与演示 (Teach & Demo): (5分钟)** **师:** 需求文档完善好了,现在提交给 Kimi 生成。但是——生成完不等于完成。生成完之后要做一件事:按需求文档逐条验收。 -**师:** 验收方法:你需求文档里写了什么,就测什么。比如你写了「满一行消除」,就在游戏里把一行填满,看它消没消。 +**师:** 验收方法:你需求文档里写了什么,就测什么。比如你写了「满一行消除」,就在游戏里把一行填满,看它消没消。比如你写了「碰到边界停止移动」,就在游戏里把方块推到最边上,按方向键,看它有没有停。 + +**师:** 我来示范验收清单是什么样的。你们跟着我一起来建—— + +【投屏在白板/文档上逐条写出来,让学生也在自己文档里写】 + +**师:** 第一条——「方块能左右移动」。怎么测? + +**生:** 运行游戏,按左右键,看方块有没有动。 + +**师:** 对,动了就打勾,没动就标叉,写上「实际表现:XXX」。第二条——「方块能旋转」。第三条——「方块碰到左边界就停」。第四条——「满一行自动消除」。第五条——「消行后上方积木下移」。 + +**师:** 5条验收清单。注意——**每条都要你真的去操作,不能只是「看起来好像对」。** 看起来对,跟测试过是对,是不一样的。 + +**师:** 验收清单怎么记录?用三列格式:需求描述 → 实际结果 → 通过/不通过。比如: + +``` +消行规则:横向填满整行就消除 +→ 实际测试:把最下一行填满,方块消失了,上方积木下移了 +→ 通过 ✓ + +碰到左边界停止移动 +→ 实际测试:方块移到最左边,继续按左键……还能继续移出去 +→ 不通过 ✗ → 需要溯源 +``` + +**师:** 写「不通过」的时候,把你看到的现象写清楚——「方块能移出边界」比「边界有问题」好得多,因为这是下一步溯源的线索。 + +【理解层:建立「验收 = 逐条测试」的意识,不是「感觉还行」】 + **师:** 遇到「结果跟预期不一样」时,**先不要让 AI 改代码**。先做一个动作:找回需求文档,找到是哪一句话没说清楚。这叫结果溯源。 -**学生实践 (Practice): (14分钟)** +**师:** 我给你们看一个具体例子——假如我测到这条:「方块可以移出右边界,一半跑出屏幕了」。我怎么溯源? + +**师:** 打开需求文档,找「移动规则」这一节,看「碰到左右边界」这条。 + +【投屏展示需求文档】 + +**师:** 发现了——我写的是「碰到边界停止」,但没说「停止」是指什么——是方块的中心碰到边界停,还是方块的边缘碰到边界停?AI 理解成了方块中心碰到边界才停,所以有半个方块出界了。 + +**师:** 这就是溯源的结果:找到了是需求里的哪句话没说清楚。现在怎么修? + +**生:** (预期:把那条需求改得更清楚) + +**师:** 对,把需求改成「方块的任意一侧碰到边界就停止移动,不能超出游戏区域」,然后重新提交生成。不需要动代码,需求说清楚了,AI 会自己重新做对的。 +【应用层:掌握「结果 → 溯源 → 修改需求 → 重新生成」的完整闭环】 + +**学生实践 (Practice): (12分钟)** 1. 把完善后的需求文档提交 Kimi 生成游戏 -2. 运行游戏,对照需求文档逐条测试 +2. 运行游戏,对照刚才建立的 5 条验收清单逐条测试 3. 遇到「结果跟预期不一样」时: - 回到需求文档 - 找到是哪条需求没说清楚,或者根本没写 - - 标注「这里有问题,原因:___」 + - 在文档里标注「这里有问题,原因:___」 - 修改需求文档,重新提交生成第二版 > 教师走动观察重点: -> - 学生测试完一条直接跳过 → 走过去问「这条算做对了吗?你的需求是怎么写的?」 -> - 学生说「不对」但直接让 AI 改代码 → 叫停,引导回到需求文档:「先找找是哪条需求没说清楚」 +> - 学生测试完一条直接跳过 → 走过去问「这条算做对了吗?你的需求是怎么写的?对比一下」 +> - 学生说「不对」但直接让 AI 改代码 → 叫停,引导回到需求文档:「先找找是哪条需求没说清楚,找到了再来修改」 +> - 学生说「全部都对了!」但第一版生成很少能完全通过 → 走过去追问「你测了消行那条了吗?消两行得分对不对?」 **进度同步 (Checkpoint): (3分钟)** **师:** 谁的第二版比第一版有改善?具体改了什么,改完效果怎样? + 【诊断点:学生是否能量化进步——不是「感觉好多了」,而是「之前 XXX 不对,改了需求之后 XXX 对了」】【应用层】 **【分支A】若学生能说出具体改善:** -**师:** 这个进步是因为你把需求文档的 XXX 改得更具体了。记住这个感觉——这就是需求驱动输出。 +**师:** 你找到了根源,改了需求,结果变对了——这个进步不是运气,是因为你走了溯源流程。记住这个感觉——这就是需求驱动输出。需求写清楚了,AI 就做对了。 -**【分支B】若学生说「改了但没变化」:** -**师:** 说明改的地方不是真正的根源。我们再来找——测试结果里还有哪里跟预期不一样? -【帮学生重新溯源,找到真正的问题所在】 +**【分支B】若学生说「改了但没变化,还是不对」:** +**师:** 说明改的地方不是真正的根源。我们再来找——你改了哪条需求?游戏里不对的现象是什么?一起来对照看看——你改的那条,跟这个现象有没有直接关系? +【帮学生重新溯源,找到真正对应的需求字段】 + +**【分支C】若学生说「我全部验收通过了,没有问题」:** +**师:** 很厉害!那我问你——你验收的是哪 5 条?能说一遍吗? +(让学生逐条念,引导回顾验收过程,确认是真的测试过还是只是「感觉对」) +**师:** 如果真的都通过了,你现在已经有一个基础版可玩的俄罗斯方块了!那你可以进下一段——想想你想给它加什么功能,留到下节课来做。 --- **【分段四:自由探索 + 下节课铺垫】(10分钟)** +*本段重点:在基础版可玩的基础上,允许学生做少量视觉微调;同时引导学生开始想下节课的扩展功能。只有基础版已经跑通的学生才进入本段,进度慢的学生继续完善分段三的最小闭环* + **学生实践 (Practice): (7分钟)** 游戏基本跑起来了之后,学生自由探索: @@ -235,6 +447,7 @@ - 或者调整一下速度和得分规则 **师:** 你现在手上有一个可以玩的俄罗斯方块了。下节课,你们可以给它加一个你自己想要的功能。现在开始想——你想给你的游戏加什么? + 【诊断点:观察学生自然产生的功能需求,作为下节课教学素材】 学生说出 1-2 个想加的功能(不要求写清楚,只是发散): @@ -245,26 +458,50 @@ **进度同步 (Checkpoint): (3分钟)** **师:** 说说你想加什么,一句话就行。 + (每人说一个,教师快速记录在白板/投屏上) + **师:** 下节课,你们每个人选一个功能,用今天学到的方法——写需求文档、压力测试、生成、验收——把这个功能加进去。 --- **第三幕:反思 (Contemplate) — 10分钟** 🤔 +*本幕目标:通过成果展示和互评,让学生复述 Plan Mode 流程,并从「需求层面」评价他人作品,而非只评价游戏好不好玩* + **【环节】成果展示 (6分钟)** -**师:** 谁来展示一下你今天做的游戏? +**师:** 谁来展示一下你今天做的游戏?不只是展示游戏——要说三件事: -(邀请 2 名学生展示,展示重点不只是游戏本身,还要说:) -- 你的需求文档里加了什么特别的设计? -- AI 压力测试问了你什么最意外的问题? -- 第一版和第二版有什么不同? +(投屏列出三个展示要点) + +``` +1. 你的需求文档里,有没有加什么你自己特别设计的规则? +2. AI 压力测试问了你什么最意外的问题?你最后怎么回答的? +3. 你第一版和第二版有什么不同?是溯源到了哪条需求? +``` + +(邀请 2 名学生上来展示,每人约 2-3 分钟) + +**师:** (第一位展示后)你刚才说需求审核问了你「方块是否能踢墙旋转」——你怎么回答这个问题的? + +**生:** (预期:我写了「不可以踢墙,碰到边界就禁止旋转」) + +**师:** 好,你做了一个具体的设计决定。有没有人觉得另一种方案——可以踢墙——更好玩? + +(让其他学生发表意见,引出「需求可以有不同的设计选择」这个意识) **【环节】互评 (4分钟)** -**师:** 看完 XXX 同学的游戏,你们能不能从他的需求文档里找出一个还没说清楚的地方? -【诊断点:学生是否建立了「挑剔工程师」的眼光】 +**师:** 看完 XXX 同学的游戏,我想让你们不只评价「好不好玩」,而是看他的需求文档——能不能找出还有没说清楚的一个地方? + +【诊断点:学生是否建立了「挑剔工程师」的眼光,能从需求角度评价作品】【应用层】 + +**生:** (预期:「他的需求文档里消多行的得分没写具体」/ 「游戏暂停功能没有需求描述」) + +**师:** 很好!这不是在批评他,这是工程师的职业习惯——总是看「还有什么没说清楚」。你刚才找到的这条,就是下节课可以迭代的方向。 + +**师:** 互评用一个结构:**一个优点**——需求文档里什么地方写得很具体、很清楚?**一个建议**——需求层面(不是游戏体验),还有什么地方可以更精准? **师:** 今天最难描述清楚的规则是什么?你最后是怎么写清楚的? @@ -274,16 +511,20 @@ **【环节】抽象总结 (3分钟)** -**师:** 今天我们做了什么? -**生:** 做了一个俄罗斯方块。 -**师:** 对,但更重要的是用什么方法做的? -**生:** 写了需求文档,然后让 AI 做…… -**师:** 对。我们今天学的这个方法,有一个名字——工程师思维。工程师做任何事情之前,都先把「要做什么」说清楚。说清楚了,才开始动手。 -**师:** 今天这个能力,不只是做游戏用——以后让 AI 做任何事,需求越清晰,结果越接近你想要的。 +**师:** 今天我们用了一个贯穿整个课程的核心流程——Plan Mode。谁来说说 Plan Mode 的三步是什么? + +**生:** (预期:整理需求、审核需求、确认需求……) + +**师:** 对。从今天开始,无论做什么项目,第一步永远是开启 Plan Mode。不管你多想直接动手,都先走这三步。 + +**师:** 为什么?因为需求写得越详细,AI 执行越准确。需求写不清楚,执行过程中就会出问题,改来改去反而更慢。 + +**师:** 今天做游戏是这样,以后做任何东西——网页、工具、应用——都是同一个流程。Plan Mode 是你跟 AI 合作的基础动作。 **【环节】下节预告 + 5分钟挑战 (2分钟)** **师:** 下节课,每人选一个你想加的功能,用同样的方法——写需求文档、压力测试、生成、验收——把它加进你的俄罗斯方块里。你的游戏会跟任何人的都不一样。 + **师:** 本周5分钟挑战:想好你下节课要加的功能是什么,在脑子里想一想:这个功能如果要写需求文档,最难描述清楚的是哪一条?不用写,想一想就行,下节课说给我听。 --- @@ -321,16 +562,32 @@ - 结束后显示:___(游戏结束画面 + 最终得分) ``` -**「压力测试」提示词:** +**⚠️ 新窗口使用规则(必须遵守):** + +``` +本课三个阶段的窗口规则: + +第一步:整理需求 → 窗口 A(写需求文档用这个窗口) +第二步:需求审核 → 窗口 B(全新窗口,不要用窗口A!) +第三步:执行生成 → 窗口 C(全新窗口) + +原因:AI 不会承认自己的问题。在同一个窗口里审核,AI 会受 +到之前对话的影响(上下文污染),很难客观找出真正的漏洞。 +换新窗口 = 换一个全新的 AI 来看,没有偏见,更客观。 +``` + +**Plan Mode 第二步:「需求审核」提示词:** ``` 我写了一份俄罗斯方块的需求文档,内容如下: [粘贴你的需求文档] -请你扮演一个非常挑剔的工程师,读完这份文档后, -找出所有你觉得「没有说清楚」「可以有多种理解」「遇到特殊情况不知道怎么处理」的地方, -用问题的形式列出来(每条一行,以问号结尾)。 +请你扮演一个需求审核工程师,读完这份文档后, +找出所有你觉得「没有说清楚」「可以有多种理解」「遇到特殊情况不知道怎么处理」的地方。 + +注意:你审核的是需求本身,不是代码。现在还没有任何代码。 +请用问题的形式列出来(每条一行,以问号结尾)。 不要帮我回答这些问题,不要帮我修改文档,只负责提问。 ``` @@ -366,19 +623,35 @@ 俄罗斯方块核心数据结构(教师理解用,不讲给学生):游戏核心是一个二维数组代表游戏区域,每个格子存 0(空)或颜色值(有方块)。方块用形状矩阵 + 当前位置表示。学生不需要理解这些,只需要知道「我的需求文档决定了游戏的行为」。 +「踢墙旋转」技术说明(教师理解用):标准俄罗斯方块有「超级旋转系统(SRS)」,允许方块在边界旁旋转时自动内移。让 AI 默认生成的版本通常不包含这个细节。如果学生需求里没写,AI 可能实现的是「碰到边界禁止旋转」或「可以踢墙」两种之一,建议教师在压力测试环节主动提示学生考虑这条规则。 + **常见问题 FAQ:** | 问题 | 应对 | |------|------| | 「Kimi 生成的代码打开没有反应」 | 检查文件是否保存为 .html 格式;用浏览器(不是记事本)打开 | -| 「方块可以移动出边界」 | 需求文档里「碰到边界怎么处理」这条没写清楚,引导学生溯源并补充 | -| 「消行了但积木没有下移」 | 需求文档里消行后的处理没说清楚,引导溯源 | -| 「游戏结束了但还能继续操作」 | 需求文档里游戏结束条件对应的处理没写,引导补充「结束后禁止操作」 | +| 「方块可以移动出边界」 | 需求文档里「碰到边界怎么处理」这条没写清楚,引导学生溯源并补充「方块任意一侧碰到边界就停止移动,不能超出游戏区域」 | +| 「消行了但积木没有下移」 | 需求文档里「消行后上方积木全部下移一行」没有写,或者 AI 理解成消行后积木消失但不下移,引导溯源并在需求里明确写出「消行后上方所有积木整体下移填补空位」 | +| 「游戏结束了但还能继续操作」 | 需求文档里游戏结束条件对应的处理没写「结束后禁止玩家操作」,引导补充 | | 「我想直接改代码」 | 「你能看懂这段代码是做什么的吗?如果不能,改了可能引发新的问题。先改需求文档,让 AI 重新生成更安全。」 | +| 「AI 审核出来问了很多问题,我不知道怎么回答」 | 先问学生「这些问题里,哪一条你有自己的想法?」——通常能说出 2-3 条,剩下的保持默认值,在需求文档里写「保持默认行为」也是合法的回答 | +| 「需求文档写了但 AI 生成的完全没有按需求来」 | 检查提交时有没有把需求文档完整粘贴;也可能是 Kimi 单次生成的结果质量波动,重新提交一次,如果还不行,引导学生检查需求是否有歧义 | +| 「我的游戏做好了,同学的还差很多,我要做什么」 | 可以进入分段四自由探索,或者帮教师整理一份「你发现的 AI 自作主张细节」作为下节课的展示素材 | +| 「旋转之后方块超出边界怎么回事」 | 这是「踢墙旋转」的问题,引导学生在需求文档里补充「旋转后如超出边界,禁止该次旋转」或「旋转后自动内移一格」,选择哪个方案让学生自己决定 | +| 「游戏跑起来了但速度太快,根本玩不了」 | 引导溯源:「你的需求文档里初始速度写的是多少毫秒?」——如果填了 100 毫秒(很快),改成 800 毫秒(默认值);如果没填,这就是漏洞,补充进去 | + +**课堂节奏控制(重要):** + +本课的核心节奏:**先做出基础可玩版本,再做扩展**。教师要守住这条线,不能让学生在第一版都没跑通的情况下就开始想「加炸弹」「加 Boss」。 + +具体做法: +- 分段三开始前,教师快速巡场确认每个学生的需求文档覆盖了基础流程(开始→移动→消行→结束) +- 发现学生需求里加了复杂功能(比如道具、反重力):引导他先注释掉,等基础版跑通再加 +- 分段四的自由探索,只有基础版已经可玩的学生才能进入 **课堂风险预案:** -- 如果 Kimi 一次生成就完全符合预期:恭喜学生,但仍要做压力测试——「这次 AI 猜对了,你能保证下次加新功能时也能猜对吗?」需求文档的价值在于每次都可预期,不只是修复当次问题。 -- 如果学生进度差异很大:进度快的学生开始探索「想加什么功能」并尝试写第一版 Level 1 需求文档;进度慢的学生只要完成「生成 + 发现一个问题 + 溯源到需求」这个最小闭环即可。 +- 如果 Kimi 一次生成就完全符合预期:恭喜学生,但仍要做需求审核——「这次 AI 猜对了,你能保证下次加新功能时也能猜对吗?」 +- 如果学生进度差异很大:进度快的学生进入分段四自由探索;进度慢的学生只要完成「基础版可玩 + 发现一个需求漏洞 + 修复」这个最小闭环即可,不强求扩展功能。 --- diff --git a/3-lessons/AICODE-06/AICODE06-07 魔幻俄罗斯方块(下).md b/3-lessons/AICODE-06/AICODE06-07 魔幻俄罗斯方块(下).md index 42e239a..87e63ca 100644 --- a/3-lessons/AICODE-06/AICODE06-07 魔幻俄罗斯方块(下).md +++ b/3-lessons/AICODE-06/AICODE06-07 魔幻俄罗斯方块(下).md @@ -1,7 +1,7 @@ --- 课时: 7 -主题: 魔幻俄罗斯方块(下)— 魔改升级 + 成果路演 -核心能力: [拆解力, 共创力, 表达力] +主题: 魔幻俄罗斯方块(下)— 魔改升级 + AI 自动测试 +核心能力: [拆解力, 共创力, 韧性力] 核心工具: [Kimi 2.5] 时长: 90分钟 透明化层级: 过程层 @@ -11,19 +11,19 @@ ### 1. 课程目标 **知识目标:** -- 理解「功能扩展」的本质:在已有基础上,通过新一轮需求文档 + 生成 + 验收来增加功能 -- 理解「需求冲突」的概念:新功能的规则可能跟已有功能产生交互,需要提前想清楚 -- 理解路演不只是展示结果,而是展示「设计决策」——你为什么这样设计 +- 理解「自动化测试」的概念:不靠人工玩,让代码自己验证代码,更快更全面 +- 理解「测试覆盖」:需求文档里每一条规则,都应该有一条对应的测试 +- 理解功能扩展的增量思维:新功能只写「增量」,不重写整体 **能力目标:** -- 能独立完成「想法 → 需求文档 → 压力测试 → 生成 → 验收 → 迭代」完整流程(共创力) -- 能在验收时主动测试功能之间的交互,发现潜在冲突(拆解力) -- 能用 3 分钟路演清楚说明:加了什么功能、需求文档改了几版、遇到什么问题怎么解决的(表达力) +- 能把需求文档转化为测试条件,交给 AI 生成测试脚本(拆解力) +- 能读懂测试脚本的 ✅❌ 结果,把失败的测试溯源到需求文档(韧性力) +- 能独立完成「需求 → 审核 → 生成 → 测试 → 修复」完整闭环(共创力) **情感目标:** -- 体验「每个人的游戏都不一样」带来的成就感和个性化自豪感 -- 建立「我能用需求文档控制 AI 做出我想要的东西」的自信 -- 感受从「做一个大家都一样的游戏」到「做一个只属于我的游戏」的跨越 +- 体验「一键跑测试,马上知道哪里有问题」带来的效率感 +- 建立「测试通过才算完成,不是能玩就算完成」的质量意识 +- 感受从「每次手动点来点去找 bug」到「测试脚本自动找 bug」的升级 --- @@ -33,20 +33,22 @@ | 概念 | 学生类比 | 认知层级 | |------|---------|---------| -| 功能扩展 | 在基础款手机上加功能——不是重新做一台手机,而是在已有基础上增加 | 理解层 | -| 需求冲突 | 新加了一条规则,跟原来的规则打架了——就像「所有人说话不准超过10秒」和「发言人可以不限时间」同时存在 | 应用层 | -| 增量需求文档 | 只写「新加的部分」以及「新部分跟原有部分的交互规则」,不需要把全部需求重写一遍 | 理解层 | -| 路演 = 决策展示 | 路演不是说「我做了什么」,而是说「我为什么这样设计」——设计背后的思考才是最有价值的 | 迁移层 | +| 自动化测试 | 与其自己每次手动检查作业有没有写对,不如写一个「答案核对程序」,把你的答案输进去,自动判断对错 | 理解层 | +| 测试覆盖 | 需求文档里写了10条规则,测试脚本就要测10件事——少测一条,那条出了 bug 你就不知道 | 应用层 | +| 边界条件 | 不只测「正常情况」,还要测「极端情况」——比如方块刚好在边角旋转、同时消4行、积木堆到最顶 | 应用层 | +| 增量需求文档 | 只写「新加的部分」,不重写整体——就像给手机升级系统,不是重新买一台手机 | 理解层 | +| 新窗口原则 | 让同一个人既写方案又审方案,他永远找不出大问题——审核和测试必须开新窗口,让没有上下文的新 AI 来做,才能客观找出漏洞 | 应用层 | **典型误概念表:** | 编号 | 误概念 | 正确认知 | 激发策略 | |------|--------|---------|---------| -| M1 | 加新功能要把整个游戏重新做一遍 | 在已有代码基础上增加功能,只需要写「新功能的需求文档」 | 演示「增量需求文档」的写法,只写新加的部分 | -| M2 | 新功能加进去就算完成了,不用测试已有功能 | 新功能可能跟已有功能冲突,必须测试两者的交互 | 举例:加了「炸弹」,炸弹爆炸后会不会触发消行?触发的话是几分? | -| M3 | 需求文档越来越长越好,把所有想法都写进去 | 本次迭代只写「这次新加的功能」,保持文档聚焦 | 「这次 AI 只需要知道新加什么,不需要把整个游戏重新理解一遍」 | -| M4 | 路演只要展示游戏好不好玩就行 | 路演的核心是展示你的思考:你加了什么、为什么加、需求文档改了几版、遇到什么问题 | 对比两种路演:一个只展示功能,一个讲设计决策,让学生投票哪个更精彩 | -| M5 | 没写清楚的需求可以让 AI 自己发挥 | 「让 AI 自己发挥」的部分你就失去了控制,结果可能跟你想的完全不同 | 「你让 AI 自己发挥了哪里?那里 AI 做出来的跟你想的一样吗?」 | +| M1 | 测试就是自己玩一遍,没出问题就算通过 | 手动测试只能发现你刚好测到的问题;自动测试每次都覆盖所有条件,不会遗漏 | 「你刚才玩的时候,有没有特意测『同时消4行的得分是不是800』?」 | +| M2 | 测试脚本是程序员才会写的东西 | 把你的需求文档给 AI,AI 就能帮你把每条需求变成一个测试 | 现场演示:需求文档→AI→测试脚本,5分钟完成 | +| M3 | 加新功能要把整个游戏重新做一遍 | 增量需求文档只写新加的部分,在已有代码上加,不是重做 | 演示增量需求文档的写法 | +| M4 | 测试通过了就说明没有 bug | 测试只能覆盖你想到的情况;没覆盖的情况仍然可能有 bug——所以需求文档要写详细 | 「你的测试脚本有没有测『反重力期间消行』?」 | +| M5 | 测试失败说明代码写错了 | 测试失败可能是代码问题,也可能是需求文档没说清楚——先溯源,再决定改哪里 | 展示一个「测试失败但代码没错,是需求文档漏写了」的案例 | +| M6 | 需求审核、测试脚本生成可以在写需求的同一个窗口里做 | 上下文污染——AI 会受之前对话影响,不会客观审核自己生成的东西。审核和测试必须开新窗口 | 演示:同一窗口让 AI 审核自己写的需求,回答很保守;新窗口审核,问题暴露更多 | --- @@ -59,165 +61,350 @@ - 准备路演计时器(3分钟倒计时) **教学资源:** -- 教师准备:「增量需求文档」提示词(见第5节) -- 教师准备:几个功能想法的参考清单(防止学生没有灵感,见第5节) -- 教师准备:路演结构引导卡(见第5节,路演前发给学生) -- 学生资源:第6课完成的俄罗斯方块 HTML 文件 +- 教师准备:增量需求文档模板(见第5节) +- 教师准备:生成测试脚本的提示词(见第5节) +- 教师准备:一份提前生成好的测试脚本演示(包含1个 ✅ 和1个 ❌,用于导入展示) +- 教师准备:功能灵感参考清单(见第5节) +- 教师准备:路演结构引导卡(见第5节) +- 学生资源:第6课完成的俄罗斯方块 HTML 文件 + Level 0 需求文档 **教师备课体验任务:** > 备课前,教师必须亲自完成以下操作: > -> 1. 选2-3个功能(比如炸弹方块、速度加成、颜色主题),各写一份增量需求文档,实际提交 Kimi 测试生成质量 -> 2. 故意在一个功能的需求文档里漏写「与消行的交互规则」,观察 AI 会怎么处理 -> 3. 练习一遍 3 分钟路演,讲「设计决策」而不只是展示游戏 +> 1. 用自己的俄罗斯方块代码 + 需求文档,让 Kimi 生成测试脚本,实际运行并记录结果 +> 2. 故意在需求文档里漏写一条规则,观察测试脚本是否能发现对应的 bug +> 3. 准备一个演示用的「测试结果页面」,包含至少1个 ✅ 和1个 ❌,用于课堂导入 +> 4. 提前试跑「炸弹方块」功能的增量需求文档完整流程,记录 AI 审核会问什么问题 --- ### 4. 教学流程 +--- + **第一幕:联系 (Connect) — 10分钟** 🔗 -**【环节】上节课回顾 + 功能发布 (10分钟)** +*本幕目标:用每人的功能构想激活学生兴趣,制造「今天不只是加功能,还要学一个新技能」的认知悬念* -**师:** 上节课结束前,我让你们想一个下节课要加的功能。现在每个人说出来——你想给你的俄罗斯方块加什么? -【每人快速说一个,教师写在白板/投屏上】 +**【环节】上节课回顾 (4分钟)** -**师:** 我们来看一下大家想加的功能。 -(读出清单)有没有一模一样的? +**师:** 上节课结束前,我让你们想一个今天要加的功能,而且在出门前每人说了一句话。我们来回顾一下——上节课我们用了 Plan Mode,它有几步?谁来说? +【诊断点:检测 Plan Mode 三步流程的记忆保持度】【识别层】 -**【分支A】若有学生选了相同的功能:** -**师:** 你们选了同样的功能,但你们的需求文档可能完全不一样——因为每个人对这个功能的设计可能不同。比如同样是「炸弹方块」,炸弹爆炸多大范围?爆炸后会不会消行?这些都是你自己决定的。 +**生:** (预期:打开 Plan Mode → 写需求文档 → 让 AI 审核……) -**【分支B】若所有人都选了不同的功能:** -**师:** 大家选的都不一样——这节课结束,每个人的游戏都会跟别人的不一样。这就是今天最有意思的地方。 +**【分支A】若学生能说出三步(写文档、审核、执行):** +**师:** 说得很准。今天还是这三步,但是有一点不一样——今天写的是「增量需求文档」,不是重新写整个游戏。等会儿我会解释区别在哪里。 -**师:** 来简单说一下——你想加的功能,最难描述清楚的是哪一条规则? -**生:** (各自说出预感最难写的部分) -**师:** 很好,记住这个预感。等会写需求文档的时候,那条规则要特别仔细写。 -【诊断点:学生上节课课后是否真的想了,还是现在才开始想】【识别层】 +**【分支B】若学生只说出一两步:** +**师:** 没关系,我帮你补一下。Plan Mode 三步:第一步,写需求文档,把你想做的东西说清楚;第二步,需求审核,让 AI 扮演审核工程师找漏洞;第三步,执行,生成代码。今天还是这三步,我们继续。 + +**师:** 好,现在说说你想加的功能——每人说一个,我把它们写在黑板上。 +【每人快速说一个,教师写在白板/投屏上,列成一列】 + +**生:** (各自说出功能:炸弹方块、速度加成、冻结方块、彩虹消行……) + +**师:** 大家看一下黑板——(指着功能列表)这里有六个不同的功能方向,没有两个人做一样的。你们今天各自在做一个完全不同的版本。 + +**师:** 我们来做一件有趣的事——互相评一下别人的功能想法。你觉得黑板上哪一个功能听起来最难描述清楚? +**生:** (讨论,指出某个功能) +**师:** 为什么觉得难? +**生:** (例如:「重力反转不知道要怎么写规则」「炸弹不知道爆炸范围算不算消行」) +**师:** 你们刚才说的这些「不知道」,就是今天需求文档里必须写清楚的部分。不写清楚,AI 就会自己决定,结果可能跟你想的完全不一样。 + +**【环节】引发认知冲突 + 悬念铺垫 (6分钟)** + +**师:** 我再问你们——你刚才说想加的功能,你觉得最难描述清楚的规则是哪一条?比如你想加炸弹方块,「炸弹爆炸」这件事,你要怎么告诉 AI? +【诊断点:探测学生对「把直觉转化为精确规则」的困难点认知】【理解层】 + +**生:** (各自说出难点——爆炸范围?爆炸后消行吗?得分怎么算?) + +**师:** 很好,你已经在思考这个问题了。等会儿写需求文档的时候,那条规则要特别仔细。 + +**师:** 今天除了加功能,我们还会学一个新技能。上节课你们手动测试游戏——自己玩、自己找 bug,对吗?手动测试有一个问题,一会儿让你们自己感受。 +【故意不展开,制造悬念】 + +**师:** 我问你们——你的游戏有5条规则,你在手动测的时候,你能保证5条都测到了吗? +**生:** (预期:不一定……有点难……) +**师:** 等会儿让你们亲身体验这个问题,我们先进建构。 + +**师:** 打开你上节课的游戏文件,确认能正常运行。我们进入建构阶段。 --- **第二幕:建构 (Construct) — 65分钟** 🛠️ -**【分段一:写增量需求文档 + 压力测试】(20分钟)** +--- + +**【分段一:增量需求文档 + 需求审核】(15分钟)** + +*本段重点:理解「增量」思维,写出可测试的需求文档,尤其是交互规则和验收标准* **预设误概念:** -- 误概念 M1:加新功能要把整个游戏重做 -- 误概念 M3:需求文档要把所有东西都写进去 +- 误概念 M3:加新功能要把整个游戏重做 +- 误概念:验收标准可以写成「功能正常」这种模糊的话 **讲解与演示 (Teach & Demo): (5分钟)** -**师:** 今天写的需求文档,跟上节课不一样。上节课写的是「整个游戏的规则」,今天只写「新加的功能」。这叫增量需求文档。 -【投屏展示增量需求文档提示词,见第5节】 +**师:** 今天继续用 Plan Mode。但今天写的是「增量需求文档」——只写新加的部分,不重写整个游戏。 -**师:** 有一个特别重要的部分——「与原有功能的交互规则」。我举个例子:你加了一个炸弹方块,炸弹爆炸了,爆炸范围里刚好有一整行被清空了——这算消行吗?算消行的话,得多少分? -**生:** ……这个我没想过。 -**师:** 对,这就是功能交互。新功能和原有功能之间,总会有一些「撞在一起」的情况,需要提前想清楚。 -【理解层:建立「功能之间有交互」的设计意识】 +**师:** 类比一下——你手机升级系统,是重新买一台手机,还是只更新改变的那一部分? +**生:** (预期:只更新改变的部分) +**师:** 对。增量需求文档就是这个意思:你的游戏核心逻辑不动,你只描述「要在这个基础上加什么」。 -**师:** 我来演示一次——用「炸弹方块」功能写一份增量需求文档,然后做一次压力测试。 -【教师演示:写需求 → 压力测试 → AI 提问 → 补漏洞,重点展示「交互规则」这部分】 +**师:** 增量需求文档有一个特别重要的部分,叫「与原有功能的交互规则」。我举一个具体例子——你加了炸弹方块。炸弹落地,爆炸了。爆炸之后刚好把整行都消干净了——这算消行吗?得多少分?是按炸弹规则算,还是按消行规则算,还是两个叠加? -**学生实践 (Practice): (13分钟)** +**师:** 如果你没写清楚,AI 自己决定,结果可能跟你想的完全不一样。所以交互规则必须写。 -1. 学生写自己的功能的增量需求文档(重点写清楚:功能规则 + 与消行/得分的交互规则) -2. 执行「压力测试」提示词 -3. 针对 AI 提出的问题,补充完善需求文档 +**师:** 还有一个字段叫「验收标准」。它的格式是这样的: +**「[情况] → [预期结果]」** +比如:「炸弹落地时周围没有积木 → 爆炸动画播放,得分+50,无消行」。 +验收标准必须是可以测试的——能测试 = 说清楚了具体情况,说清楚了预期结果。不能写「功能正常运行」,那不是验收标准,那是废话。 -> 教师走动观察重点: -> - 学生是否写了「交互规则」这一部分? -> - 对于「AI 问了什么」感到最意外的问题是什么? +**师:** 我来考考你们——以下两条验收标准,哪条是可测试的? +- A:「炸弹功能运行正常」 +- B:「炸弹落地后,落点周围3×3格内的积木清除,得分+50」 + +**生:** (预期:B) +**师:** 对,B 是可测试的——它告诉了 AI「清除3×3范围」和「+50分」。A 是废话——AI 不知道「正常」是什么意思。你的验收标准必须全部像 B 这样写。 +【投屏展示增量需求文档模板,见第5节】 + +**学生实践 (Practice): (8分钟)** + +1. 学生填写增量需求文档(重点:功能规则 + 交互规则 + 验收标准) +2. **⚠️ 开新窗口**:复制需求文档内容,打开全新的 Kimi 对话,执行「需求审核」提示词 + - 不能在写需求的同一个窗口里审核——AI 会受上下文影响,不会客观指出问题 +3. 回答 AI 的问题,把答案补充进需求文档(回到原来的窗口补充) + +> 教师走动:检查以下三项——是否写了「与原有功能的交互规则」?验收标准是否是「情况 → 预期结果」格式?验收标准条数是否至少3条? **进度同步 (Checkpoint): (2分钟)** -**师:** AI 压力测试问了你最意外的问题是什么? -**生:** (分享1-2条,重点是「交互规则」相关的问题) -**师:** 这类问题,如果不写清楚,加进去的功能会跟原来的规则「打架」,产生奇怪的结果。 +**师:** AI 审核出了什么?有没有让你意外的问题? +**生:** (分享,例如:「AI 问我炸弹同时触发消行怎么算」) + +**【分支A】若学生说 AI 问出了没想到的问题:** +**师:** 这个问题你之前有想到吗? +**生:** 没有…… +**师:** 所以 AI 审核是真的有用的——它问的问题不是废话,是你确实需要回答的问题。 + +**【分支B】若学生说 AI 没审出什么问题:** +**师:** 把你的需求文档发我看一下。(观察)——你的验收标准里有没有写边界情况?比如「功能触发时恰好也消行」这种情况?如果没有,让 AI 专门针对边界情况再审一遍。 + +**师:** 好,需求文档基本确认了,进入执行阶段。 --- -**【分段二:提交生成 → 测试交互 → 溯源迭代】(25分钟)** +**【分段二:生成第一版 → 手动测试 → 感受痛点】(15分钟)** + +*本段重点:先让学生亲身体验手动测试的局限,再自然引出「让电脑帮我们测」的需求* **预设误概念:** -- 误概念 M2:新功能加进去之后,只测新功能就行 -- 误概念 M5:没写清楚的部分让 AI 自己决定 +- 误概念 M1:手动玩一遍没出问题就算通过 +- 误概念:测试只需要测「好不好玩」,不需要逐条对照需求 -**讲解与演示 (Teach & Demo): (3分钟)** +**讲解与演示 (Teach & Demo): (2分钟)** -**师:** 把需求文档提交 Kimi,有一个特别的要求——告诉 AI 「在已有代码基础上增加功能」,而不是「重新做一个游戏」。 +**师:** 把确认好的增量需求文档提交 Kimi,基于上节课的代码增加新功能。 【投屏展示「增量生成」提示词,见第5节】 -**师:** 生成之后,验收的时候要测两件事: -- 第一:新功能有没有按需求做出来 -- 第二:原来的功能还正常吗(消行、得分、游戏结束,都要测) +**师:** 生成之后,先手动测几条——自己玩一玩,看看新功能有没有按需求做出来。特别注意:不是随便玩,是对照着你的验收标准一条条测。 -**师:** 遇到不对的地方,还是同样的动作——溯源到需求文档,找到是哪条没说清楚,改需求,重新生成。 +**学生实践 (Practice): (10分钟)** -**学生实践 (Practice): (19分钟)** +1. 提交增量需求文档 + 旧代码给 Kimi,生成第一版 +2. 打开游戏,手动测试:新功能触发了吗?原有消行/得分还正常吗? +3. 对照验收标准逐条检查,记录发现的问题 -1. 把需求文档提交 Kimi,基于已有代码增加新功能 -2. 验收:新功能测试 + 原有功能回归测试 -3. 记录「结果跟预期不一样」的地方 -4. 溯源到需求文档 → 修改 → 重新生成 -5. 重复迭代,直到功能符合预期 - -> 教师走动观察重点: -> - 新功能和消行之间的交互是否符合需求文档的设计? -> - 是否有学生因为新功能导致原有功能出问题(回归 bug)? -> - 学生是否在需求文档里找到了回归 bug 的根源? +> 教师走动观察:故意不干预,让学生自己感受「手动测试的局限」。观察:是否有学生只是「玩了一会儿」而没有逐条对照验收标准?是否有学生根本没有测「新功能和消行同时触发」的边界情况?是否有学生测了3条就觉得「差不多了」? **进度同步 (Checkpoint): (3分钟)** -**师:** 你加的新功能,有没有让原来的某个功能出问题?怎么溯源到需求文档的? -【诊断点:学生是否理解「新功能可能影响旧功能」,并能溯源到需求文档里的交互规则】【应用层】 +**师:** 手动测了哪几条?对照你的验收标准,你测了几条? +**生:** (预期:2条、3条……) -**【分支A】若学生发现了回归 bug 并成功溯源:** -**师:** 非常好!你刚才发现的问题,在需求文档里是哪条交互规则没有写清楚? +**师:** 你的验收标准里一共有几条? +**生:** 5条…… -**【分支B】若学生说「没有出问题,一切正常」:** -**师:** 那我们来测一个边界情况——你的新功能触发的同时,刚好消了一行,得分是怎么算的? -【主动暴露交互场景,测试是否真的没问题】 +**师:** 你测了3条,还有2条没测。你确定那2条没有问题吗? +**生:** 不确定…… + +**师:** 还有一个问题——就算今天你把所有5条都测了,下次你改了代码,你还要重新手动测一遍。如果你做了第二版、第三版,每次都要从头手动测一遍。需求文档越来越长,要测的条数越来越多,手动测试需要的时间也越来越长。 + +**师:** 有没有办法,让电脑帮我们测,而且每次都自动把所有条件测完? + +**【分支A】若有学生说「那肯定有程序能做这个」:** +**师:** 你说对了!这个东西叫测试脚本。我们现在就去做一个。 + +**【分支B】若学生面面相觑,不知道答案:** +**师:** 答案就是——用 AI 帮我们写一个测试脚本。这个脚本会自动运行你的游戏逻辑,逐条对照需求文档,告诉你哪条通过了、哪条失败了。我来给你们看一下它长什么样。 --- -**【分段三:路演准备】(10分钟)** +**【分段三:AI 生成测试脚本 → 跑测试 → 修复】(25分钟)** + +*本段重点:生成并运行测试脚本,学会读懂 ✅❌ 结果并溯源,建立「测试才算完成」的质量意识* **预设误概念:** -- 误概念 M4:路演只要展示游戏好不好玩就行 +- 误概念 M2:测试脚本是程序员才会写的 +- 误概念 M5:测试失败说明代码写错了,不可能是需求问题 +- 误概念:看不懂代码就没法用测试脚本 + +**讲解与演示 (Teach & Demo): (6分钟)** + +**师:** 我来给你们看一个东西。 +【投屏展示教师提前准备好的测试结果页面,显示 ✅❌ 列表】 + +**师:** 在看之前,先讲一个重要规则——**生成测试脚本必须开新窗口。** 这和上节课需求审核的原因一样:AI 不会承认自己的问题。你在写游戏代码的同一个窗口里让 AI 生成测试,它会倾向于「测试通过」,因为它觉得自己写的代码没问题。换新窗口,让新的 AI 来测,它才会客观地发现问题。 + +**师:** 整个项目的窗口规则是这样的:写需求一个窗口、审核需求一个新窗口、生成代码一个新窗口、生成测试一个新窗口。**每个独立的任务,都在自己干净的窗口里做,避免上下文污染。** + +**师:** 这是一个测试脚本跑出来的结果。你们来读一下—— +- ✅ 消1行得分100分:通过 +- ✅ 消2行得分300分:通过 +- ✅ 消4行得分800分:通过 +- ❌ 炸弹爆炸得分:期望50,实际得到0 +- ✅ 游戏结束条件:通过 +- ❌ 炸弹+消行叠加得分:期望150,实际得到100 + +**师:** 它自动测了6条规则,告诉我哪些通过了、哪些失败了,还说明了失败的具体原因——期望是多少,实际是多少。我没有玩游戏,是代码自己测自己。 + +**师:** 你们说,这个测试脚本是怎么工作的?它是怎么知道「消1行应该得100分」的? +**生:** (预期:从需求文档里知道的?) +**师:** 对!测试脚本的工作方式就三步:第一步,构造一个具体的场景——比如「棋盘最底行全满了一行」;第二步,调用游戏里的消行函数;第三步,对比结果和需求文档里写的数字。需求文档说100分,结果也是100分,就是 ✅;结果是别的数字,就是 ❌。 + +**师:** 你不需要看懂每一行代码。你只需要:能读 ✅❌ 结果、能看懂失败原因、能判断是代码问题还是需求文档问题。 + +**师:** 怎么判断失败原因?方法是这样的—— +**师:** 如果 ❌ 显示「期望50,实际0」,你先查需求文档:文档里有没有写「炸弹爆炸得50分」? +**师:** 如果需求文档写了,但代码算出来是0,那是代码问题——让 AI 修代码。 +**师:** 如果需求文档漏写了这条规则,那是需求问题——先补需求文档,再重新生成代码。 + +【投屏展示「生成测试脚本」提示词,见第5节】 + +**学生实践 (Practice): (15分钟)** + +1. 把需求文档 + 游戏代码提交 Kimi,生成 `test.html` +2. 双击打开 `test.html`,查看测试结果 +3. 对每一个 ❌,按以下步骤处理: + - 读失败原因:「期望 X,实际 Y」 + - 查需求文档:这条规则文档里写清楚了吗? + - 如果是代码问题 → 告诉 Kimi「这个测试失败了:[失败信息],帮我修复」 + - 如果是需求问题 → 先补充需求文档,再让 AI 重新生成代码 +4. 修复后重新跑测试,目标:全部 ✅ + +> 教师走动观察重点: +> - 学生是否看到 ❌ 就直接让 AI「修代码」,而没有先判断是需求问题还是代码问题? +> - 是否有学生测试结果全是 ✅,但游戏实际上还有问题?此时引导:「哪条 bug 对应的规则,在需求文档里没有写到?」 +> - 是否有学生 `test.html` 打开是空白?提示使用「测试失败溯源」提示词 + +**进度同步 (Checkpoint): (4分钟)** + +**师:** 你的测试脚本发现了几个 ❌?哪一个让你最意外? +【诊断点:学生是否发现了手动测试时没有发现的问题】【应用层】 + +**【分支A】若测试发现了手动没发现的 bug:** +**师:** 这个 bug 你刚才手动玩的时候发现了吗? +**生:** 没有…… +**师:** 这就是自动测试的价值——你没想到去测的地方,它帮你测了。想象一下,如果你发布了这个版本,别人玩到这个 bug 会怎么样? +**生:** 会觉得游戏有问题…… +**师:** 但是因为你有测试脚本,你在发布之前就知道了。这就是「安全网」。 + +**【分支B】若测试全部通过:** +**师:** 全部通过——说明你的需求文档写得很清楚,AI 也执行得准确。但我再问一下:测试脚本测了几条?你的验收标准里有几条? +**生:** (如:测了5条,文档里写了7条……) +**师:** 有2条没有被测到。是不是那2条在生成测试脚本的时候,AI 没找到对应的逻辑?或者写得不够清楚,没办法生成测试?把那2条拎出来,让 AI 单独补测。 + +**【分支C】若测试脚本打不开或全是错误:** +**师:** 不要慌,这种情况很正常。我们用「最小化调试法」——不是让 AI 修整个测试脚本,而是只请它「单独测一条最简单的规则,比如消1行得100分」,先让一条测试跑起来,再逐步扩展。 + +--- + +**【分段四:有了安全网,放心魔改——第二版、第三版】(10分钟)** + +*本段重点:建立「跑测试 → 确认安全 → 再改代码」的迭代习惯,鼓励学生大胆扩展* + +**预设误概念:** +- 误概念:有了测试脚本,每次改完不用跑,「应该没问题」 +- 误概念:第一版做到及格就行,没必要做第二版 **讲解与演示 (Teach & Demo): (3分钟)** -**师:** 接下来每个人做一个 3 分钟路演。但我们的路演跟一般的展示不一样——不是「看,我做了个游戏」,而是「我为什么这样设计」。 -【发放路演结构引导卡,见第5节】 +**师:** 你现在有了一个测试脚本。这个测试脚本是你的「安全网」。它的具体意义是什么? -**师:** 路演要说三件事: -1. 我加了什么功能,这个功能是什么效果 -2. 我的需求文档改了几版,每次改了什么 -3. 遇到的最难的地方是什么,怎么解决的 +**师:** 没有安全网的时候,你怕改出问题,所以不敢改太多。每次改完要自己手动测半天,万一改出新 bug 还得找半天。结果是——你不敢大胆加功能。 -**师:** 注意第二和第三点——这才是最有价值的部分。任何人都能展示一个游戏,但你经历了哪些思考和决策,是只有你有的。 +**师:** 有了安全网之后:每次改完代码,双击 `test.html`,10秒钟看结果。全部 ✅,说明原有功能没被破坏,可以继续加。出现 ❌,马上知道哪里出问题,立刻修。这就是「安全网」的具体作用——让你敢放心改代码。 -**学生实践 (Practice): (7分钟)** +**师:** 所以现在,有了安全网,我们才敢做更大胆的第二版。去做——比第一版更酷、更复杂。每加完一个功能,跑一遍测试,确认 ✅ 再继续加下一个。 -学生准备路演,按三点结构整理思路(不需要写逐字稿,想清楚就行)。 -教师走动帮助学生回忆「需求文档改了几版」「哪里卡住了怎么解决的」。 +**学生实践 (Practice): (5分钟)** + +1. 在第一版基础上继续扩展——加第二个功能,或者把第一个功能做得更完整 +2. 每次生成新代码后,跑 `test.html`,确认没有破坏原有逻辑 +3. 有余力的学生继续做第三版,目标:做出功能灵感清单里「⭐⭐⭐」的功能 + +> 教师走动:鼓励学生跑测试,发现有学生只靠手动玩来验证时,提示:「跑一遍测试脚本,10秒就有答案,比手动玩快多了。」 + +**进度同步 (Checkpoint): (2分钟)** + +**师:** 做了第二版的举手。你加了什么?跑测试了吗?结果怎样? +【诊断点:学生是否形成「加功能 → 跑测试 → 检查结果」的迭代习惯】【应用层】 + +**【分支A】若学生说「跑了测试,全部通过,然后继续加」:** +**师:** 这就是正确的迭代节奏。以后做任何项目都是这个节奏。 + +**【分支B】若学生说「加了功能但忘记跑测试」:** +**师:** 现在跑一遍。——有没有 ❌? +**生:** (跑完结果) +**师:** 如果有 ❌,这就是「不跑测试的代价」——你可能在不知情的情况下,新加的功能破坏了原来的逻辑。 --- **第三幕:反思 (Contemplate) — 10分钟** 🤔 -**【环节】成果路演 (8分钟)** +*本幕目标:通过路演和互评,让学生反思「测试覆盖」的本质,以及「需求文档质量 = 测试质量」的核心认知* -每位学生 3 分钟路演(按人数调整,6人小班每人约 1.5 分钟,重点展示设计决策)。 +**【环节】成果路演 (7分钟)** -**师:** (每人路演后)你的需求文档改了几版?最关键的那次修改是什么? +**师:** 每人1.5分钟路演(6人小班)。路演有引导卡,大家拿一张。 +【发放路演结构引导卡,见第5节】 -**【环节】互评 (2分钟)** +**师:** 路演不是「打开游戏给大家看」——那只是演示,不是路演。路演要讲三件事:你加了什么功能、测试脚本发现了什么、你怎么修的。开始。 -**师:** 刚才大家展示的游戏里,哪个功能的需求文档你觉得写得最清楚? -**师:** 哪个功能的设计,是你之前没想到可以这样做的? -【诊断点:学生是否能评价「需求清晰度」,而不只是「游戏好不好玩」】 +(每人依次路演,教师计时。路演要点:) +- 展示最终版本游戏(20秒演示) +- 展示测试脚本的 ✅❌ 结果(告诉大家发现了几个 ❌) +- 重点讲:最意外的那个 ❌ 是代码问题还是需求问题?怎么修的? +- 一句话总结:「如果重来一次,需求文档哪里会写得不一样?」 + +> 教师观察:是否有学生的路演只说了「我加了炸弹方块」,但没有说测试相关的内容?提示:「测试脚本发现了什么?」 + +**【环节】互评与讨论 (3分钟)** + +**师:** 刚才大家的路演里,哪一个测试脚本发现的问题最有价值? +**生:** (讨论) + +**师:** 我们来做一个结构化互评——选一位刚才路演的同学,给他的作品说「一个你觉得做得好的地方」和「一个你觉得可以改进的地方」。 +**生:** (互评,例如:「他的炸弹功能很酷,但是我觉得爆炸范围可以更大一点」) +**师:** 「更大一点」——具体怎么大?你能告诉他怎么写到需求文档里吗? +**生:** (尝试表达:「爆炸范围从3×3改成5×5」) +**师:** 这就是一条可测试的需求改进建议。他可以把这条加到需求文档里,然后让 AI 重新生成。 + +**师:** 有没有人的测试结果全是 ✅,但路演时我们发现游戏还是有问题? +**生:** (可能有学生举手) +**师:** 这说明什么? +**生:** (预期:测试没有覆盖到那个情况……) +**师:** 对。测试只能发现「你写进需求文档的问题」。你没写的,它不知道要测。这就是为什么需求文档要尽量详细——需求文档越完整,测试覆盖越全,漏掉的 bug 越少。 + +**师:** 给今天的工作做一个评分——需求文档 100 分、测试脚本 100 分、游戏功能 100 分,你自己的三项各给多少分? +(让学生自评,不需要出声,心里有数就好) + +**师:** 哪位愿意说说自己的分? +**生:** (分享,例如:「需求文档70,测试80,功能90」) +**师:** 三项里面,哪一项你觉得下次会做得更好? +**生:** (分享) +**师:** 记住这个答案。这就是你下一个项目要重点改进的地方。 --- @@ -225,23 +412,44 @@ **【环节】抽象总结 (3分钟)** -**师:** 两节课,你们从零做了一个俄罗斯方块,还加了自己设计的功能。我们用的核心方法是什么? -**生:** 写需求文档,让 AI 做,然后验收,有问题就改需求文档…… -**师:** 对。这个流程有个名字:需求 → 设计 → 实现 → 验收 → 迭代。这是真实的工程师每天都在做的事情。 -**师:** 你们今天做的,跟真实的产品开发,步骤上是完全一样的。 +**师:** 两节课,我们走了一个完整的流程。谁来说说是哪几步? +**生:** Plan Mode → 需求文档 → 审核 → 生成 → 测试 → 修复…… -**师:** 最后一个问题:如果今天你的功能需求文档第一版就做对了,是因为你运气好,还是需求写得好? -**生:** 需求写得好? -**师:** 对。运气不可靠,清晰的需求才可靠。这是今天最重要的一句话。 +**师:** 对。这个流程有个名字:需求 → 实现 → 测试 → 修复。真实的工程师每天都在走这个循环。 +**师:** 今天最重要的一句话:**「测试通过才算完成,不是能玩就算完成。」** +**师:** 能玩是 60 分,测试通过是 90 分,需求文档里每一条都有测试覆盖是 100 分。 -**【环节】下节预告 (2分钟)** +**师:** 还有一件事——今天你们体验了什么是「安全网」。这不只是测试脚本的概念,这是一种工作方式:在做危险操作之前,先建立一个保护机制。以后你们做任何项目,都可以问自己:「我有没有安全网?」 -**师:** 接下来的课程,你们会进入更大的项目。今天学到的方法——需求文档、压力测试、结果溯源——会一直用到。你们已经会了,后面只是把项目变得更复杂。 +**师:** 最后,我想让你们想一个问题——今天学到的「需求文档 → 测试 → 修复」这个流程,除了做游戏,还能用在哪里? +**生:** (讨论:做网站?做 App?……) +**师:** 对。你们今天走的这个流程,和真实的工程师在公司里走的流程是一样的。只不过他们的项目更大、需求文档更长、测试脚本更复杂。但方法是一样的。 + +**【环节】下节预告 + 5分钟挑战 (2分钟)** + +**师:** 接下来的课程,你们会做更大的项目。今天学到的——Plan Mode、需求审核、自动测试——会一直用到,只是项目变得更复杂。你们已经有了完整的工具箱。 + +**师:** 本周5分钟AI挑战:找到你需求文档里一条没有被测试覆盖到的规则,把它补进需求文档,然后让 Kimi 给测试脚本加上这条测试,跑一下看是 ✅ 还是 ❌。下节课说出你补的是哪条规则,测试结果是什么。 --- ### 5. AI 助教使用指南 +**⚠️ 新窗口使用规则(必须遵守):** + +``` +本课四个阶段的窗口规则: + +窗口 A:写增量需求文档(整理新功能需求用这个窗口) +窗口 B:需求审核(全新窗口——AI 不会承认自己写的有问题) +窗口 C:执行生成(全新窗口——基于原代码增加新功能) +窗口 D:生成测试脚本(全新窗口——让新 AI 客观测试) + +核心原则:审核、测试必须换新窗口。在同一个窗口里又写又审 +又测,叫「上下文污染」——AI 会偏向为自己生成的内容辩护, +找不出真正的问题。 +``` + **增量需求文档模板(学生填写):** ``` @@ -261,58 +469,139 @@ - 与得分的交互:[这个功能会影响得分吗?怎么影响?] - 与游戏结束的交互:[游戏结束时,这个功能有没有特殊处理?] -## 验收标准 -[我怎么测试这个功能做对了?列出2-3条可以测试的情况] +## 验收标准(每条都要能自动测试) +1. [情况] → [预期结果] +2. [情况] → [预期结果] +3. [情况] → [预期结果] ``` **「增量生成」提示词:** ``` 我已经有一个俄罗斯方块游戏(代码在下面)。 -现在我需要在这个基础上增加一个新功能,需求如下: +现在需要在这个基础上增加一个新功能,需求如下: -[粘贴你的增量需求文档] +[粘贴增量需求文档] 要求: -1. 在已有代码基础上增加这个功能,不要改变原有功能的行为 +1. 在已有代码基础上增加,不要改变原有功能的行为 2. 严格按照需求文档实现,不要添加文档里没有提到的内容 -3. 输出完整的 HTML 文件(内联 CSS 和 JS) +3. 核心逻辑函数(collides、clearLines、rotate 等)必须保持独立, + 不要把逻辑和渲染混在一起(方便后续生成测试脚本) +4. 输出完整的 HTML 文件(内联 CSS 和 JS) 已有代码: -[粘贴你的游戏 HTML 代码] +[粘贴游戏 HTML 代码] ``` -**功能灵感参考清单(学生没有想法时参考):** - -| 功能 | 一句话说明 | -|------|---------| -| 炸弹方块 | 特殊方块,落地后炸掉周围一圈 | -| 速度加成方块 | 碰到就让下落速度加快 5 秒 | -| 冻结方块 | 碰到就让当前方块暂停 3 秒不下落 | -| 彩虹模式 | 消行的时候屏幕闪一下彩虹色 | -| 双人模式 | 两个人在同一个游戏区域交替操控 | -| Boss 行 | 每隔 10 行出现一行不能被普通消行消掉的「Boss 行」 | -| 方块预言家 | 显示接下来 3 个方块而不只是 1 个 | -| 重力反转 | 消 4 行一次触发 5 秒重力反转,方块往上飞 | - -**路演结构引导卡(课前发给学生):** +**「生成测试脚本」提示词(本课核心):** ``` -我的路演(3分钟) +我有一个俄罗斯方块游戏,代码如下: -1. 我加了什么功能(30秒) +[粘贴游戏 HTML 代码] + +我的需求文档如下: + +[粘贴需求文档] + +请帮我生成一个独立的 test.html 文件,要求: +1. 把游戏的核心逻辑函数(碰撞检测、消行、得分计算等)提取出来 +2. 根据需求文档里的每一条规则,编写一个对应的测试 +3. 每个测试构造一个具体的场景,调用函数,验证结果是否符合需求 +4. 在页面上显示测试结果:✅ 通过 / ❌ 失败(失败时说明期望值和实际值) +5. 不需要任何外部依赖,双击 test.html 就能在浏览器里运行 + +重点测试的边界条件: +- 方块在左/右边界的碰撞 +- 底部锁定 +- 消1行/2行/4行的得分是否符合需求文档 +- 消行后上方积木是否正确下移 +- 游戏结束条件 +- [新功能]的触发条件和结果 +``` + +**测试脚本示例输出(教师用于课堂展示):** + +``` +俄罗斯方块测试结果 +─────────────────────────────────── +✅ 消1行得分 100 分 通过 +✅ 消2行得分 300 分 通过 +✅ 消4行(Tetris)得分 800 分 通过 +✅ 游戏结束条件(积木超出顶行) 通过 +❌ 炸弹方块落地得分 失败 + 期望:50 实际:0 + → 提示:clearBomb() 函数未返回得分 +✅ 消行后积木正确下移 通过 +❌ 炸弹 + 消行叠加得分 失败 + 期望:150(50+100) 实际:100 + → 提示:爆炸触发消行时,炸弹得分未累加 +─────────────────────────────────── +6/8 通过 2/8 失败 +``` + +**「测试失败溯源」提示词:** + +``` +我的测试脚本显示这个测试失败了: +测试名称:[测试名称] +期望结果:[期望值] +实际结果:[实际值] + +我的需求文档里关于这条规则写的是: +[粘贴相关需求] + +请帮我分析: +1. 是代码实现有问题?还是需求文档没有说清楚? +2. 如果是代码问题,具体是哪里需要修改? +3. 如果是需求问题,我需要在需求文档里补充什么? +``` + +**测试失败溯源示例对话:** + +``` +学生输入: +测试名称:炸弹方块落地得分 +期望结果:50 +实际结果:0 +需求文档写的是:炸弹方块落地时,播放爆炸动画,得分+50 + +AI 回答: +这是代码问题。你的需求文档写得很清楚——「落地得分+50」。 +问题出在 clearBomb() 函数:当前函数只处理了爆炸效果, +没有调用得分更新逻辑。建议修改: +在 clearBomb() 函数末尾加一行 score += 50 并调用 updateScore()。 +``` + +**功能灵感参考清单:** + +| 功能 | 复杂度 | 一句话说明 | +|------|--------|---------| +| 炸弹方块 | ⭐⭐ | 落地后炸掉周围3×3范围 | +| 速度加成方块 | ⭐⭐ | 碰到就让下落速度加快5秒 | +| 冻结方块 | ⭐⭐ | 碰到就让当前方块暂停3秒 | +| 彩虹消行 | ⭐ | 消行时屏幕闪彩虹色 | +| 方块预言家 | ⭐⭐ | 显示接下来3个方块 | +| Boss 行 | ⭐⭐⭐ | 每隔10行出现一行无法普通消除的行 | +| 重力反转 | ⭐⭐⭐ | 消4行触发5秒方块往上飞 | + +**路演结构引导卡(路演前发给学生):** + +``` +我的路演(每人约1.5分钟) + +1. 我做了几个版本,加了什么功能(20秒) → 演示给大家看 -2. 我的需求文档改了几版(1分钟) - → 第一版写完之后,AI 问了我什么让我意外的问题? - → 我改了哪里?改完之后结果有什么变化? +2. 需求文档改了几版(20秒) + → AI 审核问了我什么让我意外的问题? -3. 最难的地方(1分钟) - → 我遇到的最难描述清楚的规则是什么? - → 最后是怎么写清楚的? - → 有没有发现新功能让原来的功能出了问题?怎么解决的? +3. 测试脚本发现了什么(30秒) + → 发现了几个 ❌? + → 最意外的 ❌ 是什么?是代码问题还是需求问题?怎么修的? -4. 如果重来一次(30秒) +4. 如果重来一次(10秒) → 需求文档哪里会写得不一样? ``` @@ -322,35 +611,54 @@ **本课技术备注:** -增量开发策略:把已有的 HTML 代码粘贴给 Kimi,让它在基础上增加功能,比重新生成稳定得多。如果 Kimi 倾向于重写整个游戏,在提示词里加「请务必基于我提供的代码修改,不要重新生成整个游戏」。 +测试脚本的原理:游戏的核心逻辑函数(`collides`、`clearLines`、`rotate`)是纯函数——给定输入,返回确定的输出,不依赖渲染。测试脚本把这些函数复制出来,构造特定的棋盘状态作为输入,调用函数,然后检查输出是否符合需求文档的描述。整个过程在浏览器里运行,不需要任何安装。 -功能复杂度控制:炸弹方块、速度加成、冻结方块是低复杂度功能,适合大多数学生。重力反转、双人模式是高复杂度功能,适合进度快的学生挑战。教师可以根据学生能力在发清单时口头引导。 +需求文档与测试的关系:测试脚本的质量取决于需求文档的质量。需求文档里写「消行得分」但没写具体数字,AI 就无法生成有意义的测试。这是本课的核心教学点——需求越具体,测试越有效。 + +增量需求文档的代码实现原理:教师需要了解,增量功能是在已有代码的基础上「插入」新逻辑,而非替换。Kimi 在生成增量代码时会查找合适的插入位置(比如 `clearLines()` 函数内部)并添加新逻辑。如果原有代码结构混乱(逻辑和渲染混在一起),AI 会很难找到插入点,导致生成失败。这就是为什么第6课的「增量生成」提示词里要求「核心逻辑函数保持独立」。 **常见问题 FAQ:** | 问题 | 应对 | |------|------| -| 「加了新功能之后原来的功能坏了」 | 先检查需求文档里「与原有功能的交互规则」写了什么;如果没写,补上去重新生成 | -| 「Kimi 加功能之后把整个游戏重写了,之前的功能不见了」 | 提示词里强调「在已有代码基础上修改」;或者把原有代码中关键的函数名告诉 Kimi,要求保留 | -| 「我想要的功能 AI 做不出来」 | 先检查需求文档是否足够具体;可以要求 AI「只实现这一个功能,不要改其他任何部分」;确实做不到的记录进 Backlog 留待下次 | -| 「路演不知道说什么」 | 引导卡上的4个问题逐一回答就够了;重点提醒「不需要说得很完整,说你觉得最有意思的那件事就行」 | -| 「时间不够,功能还没做完」 | 没关系,路演时说「我加了什么功能、需求文档写到第几版、还差什么没完成」也是完整的路演——这本身就是真实工程师的日常 | +| 「测试脚本打开是空白页」 | 检查 HTML 文件是否完整;让 Kimi 检查生成的代码有没有语法错误 | +| 「测试全部 ❌」 | 很可能是函数提取时出了问题;让 Kimi「只提取 clearLines 函数写一个最简单的测试」,逐步调试 | +| 「测试全部 ✅ 但游戏还是有 bug」 | 引导学生找到:哪条 bug 对应的规则,在需求文档里没有写到?这就是测试覆盖不足 | +| 「Kimi 生成的测试脚本太复杂看不懂」 | 「你不需要看懂每一行代码,只需要看 ✅❌ 结果和失败原因」;理解结果比理解实现更重要 | +| 「测试失败但不知道是代码问题还是需求问题」 | 使用「测试失败溯源」提示词,让 AI 帮你判断 | +| 「AI 审核问了太多问题,不知道怎么回答」 | 让学生先回答最好回答的那一条,其他的暂时写「待定」,先生成第一版,跑测试的时候再补 | +| 「增量生成后原有消行功能不见了」 | 说明 Kimi 误修改了原有逻辑;把原版代码重新提交,强调「不要改变原有功能的行为」 | +| 「验收标准不知道怎么写」 | 用「情况 → 预期结果」句式套一遍:「[什么情况] → [应该看到什么]」;如果写不出来,说明还没想清楚这条规则 | +| 「第二版加完功能跑测试有 ❌,但不知道是新功能的问题还是旧功能出了问题」 | 先把新功能注释掉,跑测试,确认旧功能全部 ✅;再把新功能打开,重新跑,锁定是新代码引入的问题 | +| 「路演超时怎么办」 | 路演前说清楚:演示只需要展示「最酷的那一个功能」,不需要演示全部;测试部分只说「最意外的 ❌」 | + +**课堂节奏控制:** + +- 分段一(15分钟):最容易超时的环节是「AI 审核」——有学生会和 AI 进行很长的对话。给学生一个限制:AI 审核最多回答3轮问题,然后就进入执行。 +- 分段二结束时,学生手动测完后,教师主动提问「你需求文档里有几条规则,你测了几条」——制造认知冲突,让学生自己感受手动测试的不完整性,再引出自动测试。 +- 分段三的核心是「看懂 ✅❌ 结果并溯源」,不是「让每个学生都把测试写完」。进度慢的学生只要跑出测试结果、理解一个 ❌ 的原因即可。 +- 分段四时间有限,对于进度慢的学生,「跑一遍测试确认第一版没问题」就算达标,不强求做第二版。 +- 路演时间(第三幕)要严格控制在1.5分钟/人。如果有学生的功能特别复杂,教师可以帮助提炼:「你只需要说最意外的那个 ❌,其他的可以跳过。」 **课堂风险预案:** -- 如果多名学生选了同一个功能(比如炸弹方块):利用这个机会对比两个人的需求文档——相同的功能,两份需求文档有什么不同?最终生成的结果有什么不同?这是很好的教学素材。 -- 如果某个学生的功能过于复杂(比如联机对战):引导学生做「最小可行版本」——先只实现最核心的规则,其余的加进 Backlog,下次再加。 +- 如果 Kimi 生成的测试脚本无法运行:教师用提前准备好的演示版本讲解概念,让学生理解「测试脚本是什么、能发现什么问题」即可,不强求每人都跑成功。 +- 如果学生进度差异大:进度快的学生尝试「给测试脚本加更多边界条件测试」;进度慢的学生重点完成「生成第一版 + 跑一次测试 + 理解结果」。 +- 如果网络不稳定导致 Kimi 响应慢:提前在教师电脑上缓存一份完整的增量生成 + 测试脚本生成示例,用于离线演示。 --- ### 7. 5分钟日常AI挑战 -**本周挑战:** 再加一个功能,或者把这次没做完的功能完成 -**挑战说明:** 用同样的方法——写增量需求文档、压力测试、生成、验收——自己在家给游戏再加一个功能(或者完成这节课没完成的部分)。下节课展示。 -**下节课分享:** 选 2-3 位同学展示在家加的功能,重点说「需求文档是怎么写的」 +**本周挑战:** 给你的游戏补一条没有被测试覆盖的规则 +**挑战说明:** 找到你需求文档里一条没有被测试脚本覆盖到的规则,把它补进需求文档,然后让 Kimi 给测试脚本加上这条测试,跑一下看是 ✅ 还是 ❌。 +**下节课分享:** 说出你补的是哪条规则,测试结果是什么 --- ### 8. 拓展任务 -**拓展一(推荐):** 给你的游戏加一个「暂停功能」——按 P 键暂停,再按 P 键继续;暂停时显示一个半透明遮罩 -**拓展二(挑战):** 给你的游戏写一份「完整的 Level 0 + Level 1 需求文档合并版」——把上节课的需求文档和今天的增量需求文档合并成一份完整的文档,让任何人读了都能理解整个游戏的所有规则 +**拓展一(推荐):** 让你的测试脚本覆盖所有需求文档里的规则——对照需求文档逐条检查,补上缺少的测试。目标:测试脚本的条数 = 验收标准的条数。 + +**拓展二(挑战):** 在需求文档里加一个你自己想出来的「边界情况」,写清楚预期结果,让 AI 生成对应的测试,看游戏能不能通过。参考方向:「同时消4行 + 炸弹爆炸」这种极端叠加情况的得分是多少? + +**拓展三(超级挑战):** 试着把你的增量需求文档写得让另一个同学能看懂——交换给同桌,让他/她用你的需求文档,在他/她的游戏上生成同样的功能。看看你的需求文档清不清楚。 diff --git a/3-lessons/AICODE-06/AICODE06-08 涂鸦PK(一)— 画图工具 + 角色设计.md b/3-lessons/AICODE-06/AICODE06-08 涂鸦PK(一)— 画图工具 + 角色设计.md new file mode 100644 index 0000000..f6b27dc --- /dev/null +++ b/3-lessons/AICODE-06/AICODE06-08 涂鸦PK(一)— 画图工具 + 角色设计.md @@ -0,0 +1,602 @@ +--- +课时: 8 +主题: 涂鸦PK(一)— 画图工具 + 角色设计 +核心能力: [拆解力, 审美力] +核心工具: [Trae IDE, Kimi] +时长: 90分钟 +透明化层级: 过程层 +适用路线: AICODE-06 +--- + +### 1. 课程目标 + +**知识目标:** +- 理解「精准需求 > 冗余需求」:需求文档的价值在于可测试性,不在于篇幅长短 +- 理解「新窗口审核」的本质:不同上下文的 AI 才能发现你看不见的漏洞 +- 理解角色属性是「打法定位」的策略设计,不是随意填写的数字 + +**能力目标:** +- 能用 Plan Mode 三步(窗口A整理→窗口B审核→窗口C执行)完成画图工具的需求文档(拆解力) +- 能用自己生成的画图工具画出两帧角色(帧1待机 + 帧2攻击),差异度清晰可见(审美力) +- 能根据20分预算制,选定自己的打法定位,合理分配属性点(拆解力) + +**情感目标:** +- 建立「工具是自己做的」的自豪感——不是用别人的软件,而是先造工具再用工具 +- 发现「像素画」的审美乐趣:小小的64×64格子里也能表达角色个性 +- 体验「打法定位」带来的策略感:我的角色是有设计意图的,不是随便画的 + +--- + +### 2. 核心概念与误概念预设 + +**核心概念认知层级:** + +| 概念 | 学生类比 | 认知层级 | +|------|---------|---------| +| Spritesheet(精灵图集) | 动画书里的一页纸上排了多幅连续图,快速翻动就成了动画;Spritesheet 就是把所有帧拼成一张图,程序按顺序裁取每一帧 | 识别层 | +| 帧(Frame) | 动画里每一张静止的画面;两帧之间的差异越大,动画的动感越强 | 识别层 | +| 属性预算制 | 创建角色时只有20个技能点,花在HP多了ATK就少——这就是策略,不是加法题 | 理解层 | +| 需求可测试性 | 「字要好看」不可测试;「字体大小16px、颜色白色」可以测试。只有写得出来测试步骤的需求,才是写清楚了的需求 | 应用层 | +| 打法定位 | 篮球队里有中锋/控卫/得分手,分工不同;坦克型靠血厚扛伤害,刺客型靠高攻一击必杀——每种打法都有对应的属性分配 | 应用层 | + +**典型误概念表:** + +| 编号 | 误概念 | 正确认知 | 激发策略 | +|------|--------|---------|---------| +| M1 | 需求写得越多越好,越详细越安全 | 冗余需求会制造更多歧义和 bug;精准的需求才是关键——每条需求都要能写出测试步骤 | 展示一份100行需求文档生成的混乱代码 vs 精准15行需求生成的干净代码;问「这条需求,你怎么测试它对不对?」 | +| M2 | 让 AI 直接写代码更快,需求文档浪费时间 | 没有需求文档,验收时你不知道从哪里查;出了 bug 无法溯源,只能靠直觉瞎改 | 问:「如果 AI 做出来画布不是64×64,你怎么知道是哪条需求没说清楚?」 | +| M3 | 需求审核就是自己再读一遍 | 新窗口审核:上下文不同的 AI 能发现你看不见的漏洞;自己审等于让同一个人既出题又判卷 | 演示:把需求文档发给同一窗口的 AI,它说「没问题」;发给新窗口,它提了3个你没想到的问题 | +| M4 | 两帧画一样就行,动画不重要 | 帧1待机姿势 + 帧2攻击姿势,差异越大动画越有冲击力;帧2完全复制帧1等于没有动画 | 打开 demo-3-animation:展示两帧相同 vs 帧2明显前冲的动画对比,让学生自己感受差距 | +| M5 | 属性随便填,反正都是数字 | 属性是角色的「打法定位」,这是策略设计,不是填表格;20分预算是有限资源,怎么分配决定了这个角色的战斗风格 | 类比:篮球队里有中锋/控卫/得分手,不是每个人都练同一个技能;问「你是想先手打爆对方,还是慢慢耗死对方?」 | + +--- + +### 3. 教学准备 + +**工具与环境:** +- 每台电脑已登录 Kimi(网页版),网络正常 +- 每台电脑装有 Trae IDE,可以创建 HTML 文件并用浏览器预览 +- 教师电脑准备好 demo-pk 目录下的两个 demo 文件: + - `demo-1-draw-tool.html`(完整画图工具,备用展示) + - `demo-3-animation.html`(角色动画展示,Connect 环节使用) + +**教学资源:** +- 教师准备:打开 `demo-3-animation.html`,导入一个提前画好的临时涂鸦角色 Spritesheet,用于 Connect 导入 +- 教师准备:「画图工具需求文档模板」文字版(见第5节,投屏展示) +- 教师准备:一份「属性分配表」展示四种打法定位(见第5节) +- 学生资源:上节课完成的俄罗斯方块作品(精神延续,不需要文件) + +**教师备课体验任务:** +> 备课前,教师必须亲自完成以下操作: +> +> 1. 走完完整的 Plan Mode 三步:用窗口A整理画图工具需求文档 → 窗口B审核(记录 AI 问了哪些你没想到的问题)→ 窗口C生成画图工具 +> 2. 用生成的画图工具画一个角色(帧1待机 + 帧2攻击),感受64×64像素格子的限制和乐趣 +> 3. 故意画一个「两帧完全相同」的角色,导出预览,体验「没有动画感」的效果——备用作为 M4 反例 +> 4. 验证 `demo-3-animation.html` 的导入功能是否正常,准备一张 128×64 的 Spritesheet PNG + +--- + +### 4. 教学流程 + +--- + +**第一幕:联系 (Connect) — 10分钟** 🔗 + +*本幕目标:用上周挑战回顾激活工程思维记忆;用 demo-3-animation 的动画展示制造「哇!」的感受,建立今天的项目目标* + +**【环节】上节课挑战回顾 (3分钟)** + +**师:** 上节课我布置了一个5分钟挑战——给测试脚本补一条没有被覆盖的规则。谁补了?补了什么? + +**生:** (预期 A:我补了一条,测试「方块碰到左边界不能出去」) + +**师:** 具体怎么补的?你是发现了哪条规则测试脚本没写? + +**生:** (预期:测试脚本里没有检查边界,我就加了一个模拟按键到最左边的测试) + +**师:** 很好——你不只是「加了一条」,你先发现了漏洞,再去补。这就是工程师的思维方式:不是随便加,而是找到没覆盖的地方补上去。 + +【诊断点:学生能否清晰描述「我发现了什么漏洞 → 我用什么方法补上去了」,而不只是「我加了一条测试」】【理解层】 + +**【分支A】若学生能说出具体的漏洞和补法:** +**师:** 这条补得很到位。以后做任何项目,验收脚本里「没写到的地方」就是最容易漏 bug 的地方。 + +**【分支B】若学生说「我没有补,不知道怎么补」:** +**师:** 没关系,今天我们马上会用到同样的思路——先写需求,需求就是验收的标准。你今天会自己搞清楚这个流程。 + +**【分支C】若没有学生做了挑战:** +**师:** 好,我来快速过一遍——测试脚本的核心作用是什么? + +**生:** (预期:验证游戏规则有没有做对) + +**师:** 对。「没被覆盖的规则」就是「测试脚本没想到的情况」。记住这个概念,今天会继续用到。 + +--- + +**【环节】情景导入 (7分钟)** + +**师:** 上节课我们用 Plan Mode 完成了俄罗斯方块。今天我们开启一个全新项目——涂鸦PK。 + +**师:** 先不解释「PK」是什么,我先让你们看一个东西。 + +【投屏打开 demo-3-animation.html】 + +**师:** 这是一个角色动画展示器。你们看——这两个角色在做什么? + +**生:** (预期:在动!/ 一个在走路,一个在打架) + +**师:** 对,这是两帧动画——帧1是待机状态,帧2是攻击状态,快速交替播放就有了动感。但是这两个角色,是我临时画的,我花了大概5分钟。 + +**师:** 现在,我要把这个临时角色换成你们自己画的角色。 + +【教师演示导入提前准备的临时涂鸦 Spritesheet,动画播放起来】 + +**师:** 这个动画里的角色,是用一个 HTML 画图工具做的。这个画图工具——是我们今天自己写出来的。 + +**师:** 今天的任务,两件事:第一,用 Plan Mode 做出一个画图工具;第二,用这个工具画你自己的战斗角色——帧1待机,帧2攻击。 + +**师:** 上节课用的 Plan Mode 三步,还记得吗? + +**生:** (预期:记得!窗口A整理需求,窗口B审核,窗口C执行) + +**师:** 对,一模一样的流程。只是这次做的不是游戏,而是工具。先造工具,再用工具。 + +【诊断点:学生是否能自己说出 Plan Mode 三步,而不是被教师提示】【识别层】 + +--- + +**第二幕:建构 (Construct) — 65分钟** 🛠️ + +*本幕目标:完整走完 Plan Mode 三步生成画图工具;逐条验收画图功能;用生成的工具画出两帧角色并填写属性 JSON* + +--- + +**【分段一:Plan Mode — 画图工具需求文档】(25分钟)** + +*本段重点:引导学生从「我要做什么」出发,用窗口A整理需求文档,再用窗口B(新窗口审核工程师)发现漏洞,补充完整后准备提交* + +**预设误概念:** +- 误概念 M1:需求写得越多越好,越长越安全 +- 误概念 M2:直接让 AI 写代码更快,不需要文档 +- 误概念 M3:需求审核就是自己再读一遍,不用开新窗口 + +**讲解与演示 (Teach & Demo): (8分钟)** + +**师:** 开始 Plan Mode 第一步——整理需求。我们要做的画图工具有哪些功能?先不急着写,我们来想一想,这个工具要能做什么。 + +**师:** 用这个画图工具,最后要交出一张图。这张图有什么要求? + +**生:** (预期:要是方块组成的 / 要有两帧 / 颜色要能选) + +**师:** 我来把这些需求点梳理一下,一共6个部分。你们跟着我一起确认每个部分的内容,然后我们用 AI 整理成规范文档—— + +**师:** 第一部分——画布大小。我们用 64×64 像素,但显示的时候放大 8 倍显示,这样格子就有 512×512 的大小,不会太小看不清。 + +**师:** 第二部分——工具。需要三个:画笔(点击涂色)、橡皮(把像素变透明或白色)、填充桶(把一片同色区域一起换色)。 + +**师:** 第三部分——调色板。至少 16 种颜色,支持自定义颜色选择器。 + +**师:** 第四部分——多帧编辑。这是最关键的——我们有两帧,帧1是待机姿势,帧2是攻击姿势,可以切换编辑,而且可以把帧1复制到帧2作为修改起点。 + +**师:** 第五部分——动画预览。在工具里就能看到两帧切换的动画效果,不用每次都导出去看。 + +**师:** 第六部分——导出。生成一张 128×64 的 PNG 图片,两帧横向拼在一起,就是 Spritesheet。 + +**师:** 这 6 个部分,每一个都有一个关键问题:「怎么测试它做对了?」这叫需求可测试性。比如「画布 64×64 像素」——怎么测试? + +**生:** (预期:在画布上画一条线,看有没有 64 格 / 在画布最边上点,看坐标是不是(63,63)) + +**师:** 对,能说出测试步骤,说明需求写清楚了。如果是「颜色要好看」——怎么测试「好看」? + +**生:** (停顿)……好像测不了…… + +**师:** 对,「好看」不可测试。所以需求文档里不能出现「好看」「流畅」「方便」这类词。要写具体的、能测试的描述。 +【理解层:建立「需求可测试性」的直觉,澄清 M1 误概念】 + +**师:** 现在看一下今天用的三步流程—— + +**师:** 窗口A——打开 Kimi,把这6个需求要点告诉 AI,请它整理成规范的需求文档(五部分格式:功能描述/触发条件/功能规则/交互规则/验收标准)。 + +**师:** 窗口B——全新 Kimi 对话,把文档发给「审核工程师」,让它只问问题不给答案,找出所有描述不清楚的地方。 + +**师:** 窗口C——再新一个 Kimi 对话,把补充完整的需求文档发给它,生成画图工具的 HTML 代码。 + +**师:** 我来演示窗口A这一步。 + +【教师打开 Kimi,用保底提示词一(见第5节)提交,投屏展示 AI 整理出来的需求文档结构】 + +**师:** 你看 AI 给我整理出来的格式——每个功能都有「功能规则」和「验收标准」。你们对比一下:AI 加的这些验收标准,我在口头说的时候有没有提到? + +**生:** (预期:有几条我没说 / 填充桶的那条我没想到边界情况) + +**师:** 对,AI 帮我补了一些我没说清楚的细节。但注意——AI 整理的内容可能有你不想要的,也可能漏掉你想要的。整理完之后要自己过一遍,确认每条都是你真正想要的。 +【应用层:学生开始区分「AI 帮我补充的」和「我自己想要的」】 + +**学生实践 (Practice): (12分钟)** + +学生操作: +1. 打开 Kimi,新建对话(窗口A) +2. 根据教师给出的保底提示词一,补充自己想要的特殊需求,提交 +3. 拿到 AI 整理的需求文档,自己读一遍,圈出「这条我没提到的」和「这条说法我不认可的」 +4. 打开新的 Kimi 对话(窗口B),把文档和审核提示词一起提交 + +> 教师走动观察重点: +> - 学生在窗口A拿到文档后,有没有真的读了一遍?还是直接复制粘贴给窗口B?「读一遍」是诊断这步的关键行为。 +> - 窗口B的 AI 问了哪些问题?有没有学生对某个问题感到惊讶——「这个我真的没想过」是好信号。 +> - 是否有学生在同一个对话窗口里同时做整理和审核?这是 M3 误概念的表现,需要介入。 + +**进度同步 (Checkpoint): (5分钟)** + +**师:** 窗口B审核出来了,AI 问了你哪个最意外的问题?谁来说一下? + +**生:** (预期 A:它问我「橡皮是把像素变透明还是变白色」,我没想过这两种不一样) + +**师:** 好——这两种有什么区别? + +**生:** (预期:透明就是真的没颜色,白色就是变成白色格子) + +**师:** 对,区别很重要。如果背景是黑色的,你用橡皮想抹掉一块,变成「白色」就是留了个白点,变成「透明」才是真正删掉。你准备选哪个? + +**生:** 透明! + +**师:** 那就在你的需求文档里补上:「橡皮擦除后像素变为透明(alpha=0)」。 + +【诊断点:学生能否说出一条「因为 AI 审核问了这个问题,我补充了这条描述」,而不是「AI 问了很多,我不知道填哪些」】【理解层】 + +**【分支A】若学生能说出具体补充了什么:** +**师:** 很好。需求每补充一条,代码出问题的概率就降低一点点。这就是 Plan Mode 的价值。 + +**【分支B】若学生说「AI 问了很多但我觉得都不重要」:** +**师:** 好,拿出来看看。最意外的那条是哪个?我们一起判断——这条如果不补,代码生成出来会发生什么? +(引导学生预测后果,建立「需求漏洞→代码行为异常」的因果感) + +**【分支C】若学生在同一窗口做了整理和审核:** +**师:** 我注意到你在同一个对话框里做的审核。还记得上节课说的「上下文污染」是什么意思吗?现在再开一个全新对话,把文档重新发过去,对比一下这次 AI 问的问题和刚才有没有不同。 + +--- + +**【分段二:窗口C生成画图工具 → 逐条验收 → 溯源修复】(20分钟)** + +*本段重点:提交需求文档生成画图工具;建立「按需求逐条验收」的习惯;遇到问题先溯源需求再修改* + +**预设误概念:** +- 误概念 M2:直接改代码比溯源需求更快 +- 误概念:看起来能用就算完成,不需要逐条验收 + +**讲解与演示 (Teach & Demo): (3分钟)** + +**师:** 需求文档补完了,进入窗口C——提交生成。把补充完整的需求文档粘贴进新的 Kimi 对话,加上保底提示词三,提交。 + +**师:** 生成完之后,你会拿到一段 HTML 代码。把这段代码复制出来,在 Trae 里新建一个 `draw-tool.html` 文件,粘贴进去,保存,用浏览器打开。 + +**师:** 打开之后——不要急着画。先做一件事:用你的需求文档,逐条验收。验收方式:你需求文档里写了什么,就测什么。 + +**师:** 我给你们一个最快的验收清单——五条最关键的: + +【投屏展示验收清单】 + +``` +1. 画笔工具:选颜色,点击画布能涂色 +2. 橡皮工具:点击有颜色的格子,变为透明/白色 +3. 填充桶:点击一片同色区域,整体换色 +4. 多帧切换:点「帧1」「帧2」Tab,画的内容各自独立 +5. 动画预览:点播放,两帧交替显示 +``` + +**师:** 这五条,每条真的去操作一次,不能只「看起来好像对」。有一条不通过就标叉,写下「实际看到了什么现象」。 +【应用层:建立「验收 = 逐条测试 + 记录现象」的习惯】 + +**学生实践 (Practice): (13分钟)** + +学生操作: +1. 在 Trae 新建 `draw-tool.html`,粘贴 AI 生成的代码,浏览器打开 +2. 按五条验收清单逐条测试,记录「通过✓」或「不通过✗ + 实际现象」 +3. 遇到「不通过」先不改代码——找回需求文档,找到是哪条需求没说清楚,标注出来 +4. 把找到的漏洞描述清楚(「步骤→预期→实际」格式),让 AI 针对性修复 + +> 教师走动观察重点: +> - 有没有学生遇到 bug 直接问 AI「帮我改这个 bug」,而没有先溯源需求?主动走过去问「你知道是哪条需求没说清楚吗?」 +> - 有没有学生卡在代码生成失败(如 AI 输出不完整)?准备好备用的 demo-1-draw-tool.html,但先引导学生尝试重新生成 +> - 验收清单有没有学生不知道「如何测试填充桶」?示范:先用画笔画一个封闭区域,再用填充桶点内部 + +**进度同步 (Checkpoint): (4分钟)** + +**师:** 五条验收,全部通过的举手。 + +**师:** 好。有没有人验到「不通过」的?说一下你发现了什么。 + +**生:** (预期 A:帧1和帧2切换,但画的内容是共用的,切换没效果) + +**师:** 好,你溯源到需求文档了吗?哪条需求没写清楚? + +**生:** (预期:我写了「可以切换帧」,但没写「两帧的数据是独立存储的」) + +**师:** 对,这就是漏洞。「切换帧」和「数据独立」是两件事,你只说了一件。现在补上这条,用「步骤→预期→实际」格式描述给 AI,让它修复。 + +【诊断点:学生能否从「出了 bug」出发,溯源到「是哪条需求没写清楚」,而不是直接「AI 帮我改一下」】【应用层】 + +**【分支A】若学生完成了溯源并修复了 bug:** +**师:** 这是真正的工程师思维——不是改代码,是改需求,然后重新生成。 + +**【分支B】若学生直接把代码发给 AI 说「帮我改」:** +**师:** 先停一下。你现在让 AI 改的是代码,但 AI 不知道你要的是什么效果。你能不能先找到需求文档里「两帧切换」那一条,把它描述得更清楚再提交? + +**【分支C】若 AI 生成的代码完全无法运行(语法错误):** +**师:** 遇到这种情况,先用「步骤→预期→实际」描述给 AI:「我打开 HTML 文件,浏览器显示空白/报错,期望看到画图工具界面」。让 AI 自己排查哪里有问题。如果还不行,可以用老师电脑上的备用 demo 继续后面的步骤——画角色才是今天更重要的部分。 + +--- + +**【分段三:用工具画角色(帧1待机 + 帧2攻击)+ 填属性JSON】(20分钟)** + +*本段重点:用画图工具完成角色设计;理解两帧差异的审美原则;用20分预算制选定打法定位并填写属性* + +**预设误概念:** +- 误概念 M4:两帧画一样就行,动画不重要 +- 误概念 M5:属性随便填,反正都是数字 + +**讲解与演示 (Teach & Demo): (5分钟)** + +**师:** 画图工具做好了。现在正式开始画你的战斗角色。 + +**师:** 先确认一件事——帧1和帧2要画什么? + +**师:** 帧1是「待机」姿势——就是角色站在那里,什么都没发生。这一帧决定了角色的整体外形和配色。 + +**师:** 帧2是「攻击」姿势——角色在出击的那一瞬间。这一帧决定了动画的冲击感。 + +**师:** 我让你们看一个对比。 + +【投屏打开 demo-3-animation.html,分别导入两个角色:一个帧1和帧2完全一样,一个帧2明显前冲】 + +**师:** 哪个更有打击感? + +**生:** 第二个!第一个完全没动…… + +**师:** 对,帧1和帧2差异越大,动画的冲击感越强。帧2复制帧1不修改,等于没有动画。攻击帧要做什么?肢体前冲、武器伸出去、颜色变化——让角色看起来「正在做某件事」。 +【识别层:建立「帧1待机 vs 帧2攻击」的视觉差异意识,澄清 M4 误概念】 + +**师:** 画完之后,我们要给角色填属性。属性系统用的是「20分预算制」——你有20分,分配完就没了,怎么分是你的策略。 + +**师:** 四个属性: + +【投屏展示属性表】 + +``` +HP(生命值):1分 = 10血 范围 3-10分 +ATK(攻击力):1分 = 5伤害 范围 2-10分 +DEF(防御力):1分 = 3减伤 范围 0-6分 +SPD(速度):1分 = 1速度值 范围 1-6分 +``` + +**师:** 我给你们四种打法定位参考,你选一种,或者自己设计—— + +``` +坦克型:HP 8 + ATK 4 + DEF 6 + SPD 2 = 20分(耗死对方) +刺客型:HP 4 + ATK 10 + DEF 0 + SPD 6 = 20分(一击毙命) +平衡型:HP 5 + ATK 5 + DEF 4 + SPD 6 = 20分(没有弱点) +速攻型:HP 6 + ATK 7 + DEF 1 + SPD 6 = 20分(先手压制) +``` + +**师:** 注意——你的角色外观要和你的打法定位「匹配」。刺客型画个超大的圆圆的胖角色,感觉不对;坦克型画个细细的小人,也感觉不对。角色的视觉设计要传达出它的战斗风格。 + +**师:** 还有一个特技系统——每个角色可以选一个特技,不占预算: + +``` +🔥燃烧:每回合额外-5血,持续3回合 +🛡护甲:首次受击伤害归零 +⚡连击:25%概率攻击两次 +💉吸血:攻击回复伤害30%血量 +❄️冰冻:每场一次,对方跳过下回合 +🎯穿透:一次攻击无视防御 +``` + +**师:** 选好了吗?现在开始画。先定打法定位,再动手画角色外形。 +【应用层:学生开始从策略角度设计角色,而不是「随便画一个」】 + +**学生实践 (Practice): (12分钟)** + +学生操作: +1. 在画图工具里,先选定自己的打法定位(坦克/刺客/平衡/速攻,或自定义) +2. 在帧1画待机姿势——确定角色外形、配色、整体风格 +3. 点「复制帧1到帧2」,在帧2的基础上修改攻击姿势(肢体前冲、武器伸出、颜色变化等) +4. 预览动画,确认帧1和帧2有明显差异 +5. 完成后,在 Trae 新建一个 `character.json`,填写属性数据: + +```json +{ + "name": "你的角色名", + "hp": 50, + "atk": 25, + "def": 12, + "spd": 4, + "special": "⚡连击", + "description": "一句话描述你的打法" +} +``` + +> 教师走动观察重点: +> - 有没有学生帧2完全没改,只是复制了帧1?走过去问「攻击的时候角色在做什么动作?」 +> - 有没有学生分配完属性后发现「总分超了20分」?引导他重新算一下 +> - 关注速度慢的学生:如果卡在画角色,帧2可以暂时只改一两个像素,保证完成基本的两帧结构;细节可以之后优化 + +**进度同步 (Checkpoint): (3分钟)** + +**师:** 谁的帧2跟帧1有明显不同的,把动画预览给大家看一下。 + +**生:** (学生展示动画预览) + +**师:** 帧2里,角色做了什么动作? + +**生:** (预期:他的手臂伸出来了 / 整个身体往前倾了) + +**师:** 这就是攻击感。你们的打法定位是什么型? + +**生:** 刺客型! + +**师:** 刺客型——高攻低血。碰到坦克型怎么办? + +**生:** (预期:先手攻击!速度快,先打对方) + +**师:** 好,这说明你的策略是清晰的。你知道你的角色能赢谁,也知道怕谁——这才是策略设计。 + +【诊断点:学生能否说出自己的打法定位,并能解释「这个定位的优势和弱点」,而不只是「我觉得这个好看」】【应用层】 + +--- + +**第三幕:反思 (Contemplate) — 10分钟** 🤔 + +*本幕目标:2-3名学生展示角色并说出打法定位的策略思考;让其他学生从「对抗」角度给出评价* + +**【环节】成果展示 (6分钟)** + +**师:** 现在我们来做一个角色路演。每个人只说三件事:第一,你的角色叫什么名字;第二,你的打法定位是什么型;第三,你的特技是什么,为什么选这个。 + +**师:** 谁先来? + +【1-2名学生上来展示角色动画,说出三件事】 + +**师:** (对展示的学生)你是刺客型,特技选了「穿透」。你的思路是什么? + +**生:** (预期:因为刺客型攻击高,加上穿透直接无视防御,坦克型也扛不住) + +**师:** 这个搭配有意思——高攻 + 穿透,专门克制高防御的坦克。但是你血量很少,碰到先手比你快的角色怎么办? + +**生:** (预期:就……输了? / 要速度快才行) + +**师:** 所以你的角色有一个明显弱点。这不是坏事——有弱点才有对抗的乐趣。 + +**【环节】互评与讨论 (4分钟)** + +**师:** 大家来评价刚才展示的这个角色——一个优点 + 一句「如果我拿XX型去打他,我的策略是」。 + +**生:** (预期:优点是攻击穿透很厉害;如果我用速攻型,速度比他快,先手打他,因为他血少可能一下就输了) + +**师:** 很好——你在想「反制策略」了。这就是涂鸦PK的乐趣:不只是画角色,而是设计一个有自己思考的战斗方案。 + +**师:** 帧2动画有一个想问的——你们觉得帧2改变得最大、最有攻击感的是哪个角色? + +【学生投票或说出谁的】 + +**师:** 为什么你觉得那个最有攻击感? + +**生:** (预期:因为他帧2整个身体都往前扑了,和帧1差别很大) + +**师:** 对——**差异越大,冲击感越强。** 这是今天审美设计的核心原则,记住它。 + +--- + +**第四幕:延续 (Continue) — 5分钟** 🚀 + +**【环节】抽象总结 (3分钟)** + +**师:** 今天我们做了两件事:先用 Plan Mode 做出了画图工具,然后用工具画了角色、填了属性。我来问你们——今天用的三步流程(窗口A整理、窗口B审核、窗口C执行),和上节课做俄罗斯方块时有什么一样的地方? + +**生:** (预期:流程完全一样 / 都是先写需求再生成) + +**师:** 对——**流程是可以迁移的。** 这套流程不只用来做游戏,不只用来做画图工具。以后你们要做任何稍微复杂一点的项目,都可以用这三步。 + +**师:** 今天还有一个新东西——「先造工具,再用工具」。你们不是下载别人的画图软件来用,而是自己写了一个。这个思路以后还会用到:当你发现某个工具不好用,或者根本没有,你可以自己造。 + +**师:** 今天的「审美力」训练,核心是什么? + +**生:** (预期:帧1和帧2差异要大 / 攻击帧要有动感) + +**师:** 对,帧2差异越大,动画越有冲击感。这条原则不只用在像素画——你以后做任何动画、做任何交互,「差异对比产生冲击感」都是一条通用的审美原则。 + +【迁移层:将「先造工具」「差异产生冲击感」提炼为可迁移的思维模型】 + +**【环节】下节预告 + 5分钟挑战 (2分钟)** + +**师:** 下节课——涂鸦PK(二)。你们今天画好的角色和属性,会被真正用来对战。我们要搭建一个战斗引擎,让你的角色和同学的角色打起来,看看谁的策略赢。 + +**师:** 想一想——你的打法定位,碰到哪种对手会输?下节课我们来验证。 + +**师:** 本周 5 分钟挑战:用你今天做的画图工具,帮一个同学画一个角色,然后对比和他自己画的有什么不同——外形、配色、攻击姿势,哪里不一样?拍照或截图,下节课分享。 + +--- + +### 5. AI助教使用指南 + +**教师演示用提示词(需求文档整理,窗口A):** +``` +你是一个需求分析师。我要做一个HTML5像素画图工具,功能是:64×64画布、8倍缩放显示、支持画笔/橡皮/填充桶、有调色板、两帧编辑(帧1待机/帧2攻击)、可复制帧1到帧2、有动画预览、能导出128×64 Spritesheet PNG。请把这些需求整理成规范的需求文档,包含:功能描述、触发条件、功能规则、交互规则、验收标准五个部分。 +``` + +**审核用提示词(窗口B——新窗口,不要在整理窗口里使用):** +``` +你是一个挑刺工程师。下面是一份画图工具的需求文档,请只提出你觉得描述不清楚或有遗漏的问题(每个问题一行),不要给答案,不要写代码: + +[粘贴需求文档] +``` + +**学生保底提示词(生成画图工具,窗口C):** +``` +请帮我用HTML5 Canvas做一个像素画图工具:64×64像素画布、8倍缩放显示、支持画笔/橡皮/填充桶、有颜色调色板(至少16色)、有两帧(帧1待机/帧2攻击)可切换编辑、可复制帧1到帧2、有动画预览(循环播放)、能导出128×64 Spritesheet PNG。单文件HTML,不用任何外部库。 +``` + +**进阶提示词(属性 JSON 生成辅助):** +``` +我的角色是刺客型,打法是先手高爆发。20分预算制:HP/ATK/DEF/SPD各有范围限制(HP:3-10,ATK:2-10,DEF:0-6,SPD:1-6)。请帮我给出一个满足20分总预算、符合刺客型定位的属性分配方案,并说明每个属性为什么这样分配。 +``` + +**属性分配参考表(投屏展示用):** + +| 打法定位 | HP | ATK | DEF | SPD | 合计 | 核心优势 | +|---------|----|----|-----|-----|-----|---------| +| 坦克型 | 8 | 4 | 6 | 2 | 20 | 血厚扛伤害,慢慢耗死对方 | +| 刺客型 | 4 | 10 | 0 | 6 | 20 | 先手高爆发,一击毙命 | +| 平衡型 | 5 | 5 | 4 | 6 | 20 | 无明显弱点,应对各种对手 | +| 速攻型 | 6 | 7 | 1 | 6 | 20 | 先手压制,中等爆发 | + +--- + +### 6. 教师指南 + +**本课技术备注:** + +- **Spritesheet 格式**:128×64 PNG,左半(0-63像素宽)是帧1,右半(64-127像素宽)是帧2。对战引擎会按这个坐标裁取每帧。导出时必须确保两帧横向拼接,否则下节课的战斗引擎无法正确读取。 + +- **Canvas 像素操作**:画图工具底层用 `getImageData/putImageData` 操作像素数组。每个像素有 RGBA 四个值(各0-255)。橡皮设为「透明」等于把该像素的 alpha 通道设为 0。这部分不需要传达给学生,但教师需要了解,以便解释「橡皮变透明 vs 变白色」的区别。 + +- **填充桶(洪水填充)**:用 BFS 或 DFS 算法扩展同色区域。如果学生报告「填充桶没有反应」,可能是起点像素和周边颜色完全相同导致;让学生先用画笔画一个封闭区域再测试。 + +- **帧数据独立存储**:每帧用一个独立的 `Uint8ClampedArray` 存储像素数据。切换帧时先保存当前帧数据,再加载目标帧数据。如果生成的代码两帧共用数据,需要在需求里补充「每帧像素数据独立存储,互不影响」。 + +- **导出 PNG**:用 `canvas.toDataURL('image/png')` 获取 base64 编码后触发下载。导出前需要把两帧数据拼接到一个 128×64 的临时 canvas 上再导出。 + +**常见问题 FAQ:** + +| 问题 | 应对 | +|------|------| +| 「AI 生成的代码报错,打开是空白页」 | 让学生把报错信息(浏览器 F12 控制台)截图给 AI,用「步骤→预期→实际」描述问题让 AI 修复 | +| 「橡皮擦了但颜色还在」 | 先确认是否切换到了橡皮工具;如果工具选对但无效,可能是代码把橡皮当成了「白色画笔」,需要溯源需求文档里橡皮的功能描述 | +| 「填充桶整个画面都变色了」 | 这是填充桶「溢出」问题——起点像素周围没有封闭边界,颜色扩散到整个画布。让学生先用画笔封闭区域再用填充桶 | +| 「帧1和帧2切换后内容一样」 | 需求文档里需要补充「两帧像素数据独立存储」;溯源后让 AI 修复数据存储逻辑 | +| 「导出的 PNG 只有一帧」 | 需求里「128×64 Spritesheet」的描述可能没说清楚是「两帧横向拼接」;补充描述后重新生成导出功能 | +| 「20分分配不够,不知道怎么算」 | 给学生纸笔,列出四个属性的分值,加减法算一遍;主要目的是让学生思考优先级,不是数学练习 | +| 「帧2不知道怎么画才有攻击感」 | 给三个具体操作方向:1)身体/手臂前倾;2)把武器或特效从帧1的位置移动到「伸出去」的位置;3)帧2加一些颜色特效(爆炸光晕、冲击线条) | + +**课堂风险预案:** + +- **AI 服务不可用**:使用 `demo-1-draw-tool.html` 作为备用画图工具,跳过 Plan Mode 生成步骤,直接让学生用 demo 画角色。Plan Mode 三步可以在白板上演示讲解,不需要真的生成。 +- **学生进度差异过大**:画图工具生成完成的学生直接开始画角色;还在 Plan Mode 阶段的学生可以在分段三时使用教师备用的 demo-1-draw-tool.html 画角色,保证每位学生都能产出两帧角色。 +- **属性分配争议(学生觉得某个定位「必胜」)**:预先告知下节课会有实际对战,不同对手克制关系不同,没有「必胜型」。这个问题留到实战后讨论,今天重点是把角色画完。 + +--- + +### 7. 5分钟日常AI挑战 + +**本周挑战:** 用画图工具帮同学画一个角色,然后对比差异 + +**挑战说明:** +用你今天做好的画图工具,帮一个同学(家人或朋友也行)画一个角色(帧1待机 + 帧2攻击),然后让他自己也画一个版本,对比两个版本有什么不同:外形、配色、攻击姿势,哪里不一样?想一想:为什么会不一样?是因为你们对「好看」的标准不同,还是因为对「攻击感」的理解不同? + +**下节课分享:** 下节课选2-3位同学展示「你画的版本」和「同学画的版本」,说出最大的一处差异是什么。 + +--- + +### 8. 拓展任务 + +**拓展一(推荐):** 设计一个「克制链」——你的角色克制哪种打法定位的对手,被哪种打法定位克制?用文字写出来:「我是XX型,我克制XX型,因为……;我怕XX型,因为……。」然后想想下节课对战时要不要调整属性。 + +**拓展二(挑战):** 给你的角色再画一帧「受伤帧」——当角色被攻击时显示的状态(帧3)。试着修改画图工具的代码,让它支持三帧编辑,并在动画预览里加入「受伤」动画。 diff --git a/3-lessons/AICODE-06/AICODE06-09 涂鸦PK(二)— 基础对战系统.md b/3-lessons/AICODE-06/AICODE06-09 涂鸦PK(二)— 基础对战系统.md new file mode 100644 index 0000000..2eaa435 --- /dev/null +++ b/3-lessons/AICODE-06/AICODE06-09 涂鸦PK(二)— 基础对战系统.md @@ -0,0 +1,605 @@ +--- +课时: 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 IDE,Kimi 已登录,网络正常 +- 每台电脑浏览器可以正常打开本地 HTML 文件 +- 每台电脑上已有上节课完成的 Spritesheet PNG 文件(128×64,帧1待机+帧2攻击) +- 每台电脑上已有上节课完成的角色属性 JSON(hp/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 条测试验证了什么—— + +``` +测试 1:ATK=15, DEF=5 → 伤害=10 ✅ +测试 2:ATK=5, DEF=10 → 伤害=1(最低) ✅ +测试 3:SPD=8 vs SPD=5 → SPD=8 先手 ✅ +测试 4:ATK=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 → 伤害=10;ATK=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.png,128×64 像素 +- 帧1(x=0, y=0, w=64, h=64):待机状态 +- 帧2(x=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` 使用。 diff --git a/3-lessons/AICODE-06/AICODE06-10 涂鸦PK(三)— 动画 + 音效 + 特技.md b/3-lessons/AICODE-06/AICODE06-10 涂鸦PK(三)— 动画 + 音效 + 特技.md new file mode 100644 index 0000000..e530563 --- /dev/null +++ b/3-lessons/AICODE-06/AICODE06-10 涂鸦PK(三)— 动画 + 音效 + 特技.md @@ -0,0 +1,621 @@ +--- +课时: 10 +主题: 涂鸦PK(三)— 动画 + 音效 + 特技 +核心能力: [审美力, 提问力] +核心工具: [Trae IDE, Kimi] +时长: 90分钟 +透明化层级: 过程层 +适用路线: AICODE-06 +--- + +### 1. 课程目标 + +**知识目标:** +- 理解「游戏感(Game Feel)」的概念:每次操作必须有视觉反馈,玩家才知道自己的行动生效了 +- 理解「增量需求」的写法:在已有系统上叠加新功能,只描述新增部分,避免 AI 误改已验收的代码 +- 理解 Web Audio API 的核心思想:用纯代码合成音效,不需要任何音频文件 + +**能力目标:** +- 能用「感觉语言」描述动画需求(「快速冲过去然后弹回来」),让 AI 把感觉翻译成代码参数(审美力) +- 能写出增量需求文档,只描述新增的动画/音效,不重写已有战斗逻辑(提问力) +- 能在 AI 生成代码后,通过视觉对比和试玩,判断动画「感觉对不对」并给出精准修改意见(审美力) + +**情感目标:** +- 对「同样的游戏,有没有动画,体验天差地别」产生真实感受——建立「视觉反馈是游戏的灵魂」的审美直觉 +- 体验到「我说出一种感觉,AI 把它变成了代码」的成就感,增强自然语言驱动开发的自信 +- 对下节课的班级对战产生期待感 + +--- + +### 2. 核心概念与误概念预设 + +**核心概念认知层级:** + +| 概念 | 学生类比 | 认知层级 | +|------|---------|---------| +| 游戏感(Game Feel) | 打篮球投篮时「嗖」一声进了网——同样进了,但有没有这个声音感觉完全不一样 | 理解层 | +| 增量需求 | 你去装修只告诉工人「加一个书架」,不需要重新描述整个房子的结构 | 理解层 | +| 感觉语言→参数翻译 | 给厨师说「要辣一点」而不是「加5克辣椒粉」——厨师懂怎么翻译成具体操作 | 应用层 | +| Web Audio 合成音效 | 用嘴巴「嗖——」发出声音,不需要找一个录好的「嗖」的音频文件 | 理解层 | +| 特技视觉标记 | 超市商品的标签——没有标签你看不出这是打折商品;特技没有特效,玩家感知不到它生效了 | 应用层 | + +**典型误概念表:** + +| 编号 | 误概念 | 正确认知 | 激发策略 | +|------|--------|---------|---------| +| M1 | 动画只是装饰,不影响游戏质量 | 动画是「游戏感」的核心:每次操作必须有视觉反馈,玩家才知道自己的行动生效了 | 展示对比:无动画(只有数字变化)vs 有动画(角色冲刺),问学生哪个更爽 | +| M2 | 音效需要找音频文件,太麻烦了 | Web Audio API 用纯代码合成音效,零素材依赖,浏览器内置支持 | 演示:三行代码合成一个攻击音效,不需要任何音频文件 | +| M3 | 增量需求要把整个需求文档重写一遍 | 增量需求只写新增的部分;已验收的功能不重写,避免 AI 误改 | 类比:装修只说「加书架」,不需要重新描述整个房子 | +| M4 | 动画描述必须用技术参数(duration: 200ms) | 先用感觉描述(「快速冲过去然后弹回来」),AI 把感觉翻译成参数;感觉描述比参数描述更准确 | 让学生先说出感觉,再看 AI 翻译的参数,对比哪种方式更自然 | +| M5 | 特技效果只要触发就行,不需要视觉区分 | 特技必须有独特的视觉效果,玩家才能感知到特技生效了(如燃烧 = 橙色粒子,冰冻 = 蓝色闪烁) | 问:「如果燃烧特技触发了但什么都没发生,你怎么知道它触发了?」 | + +--- + +### 3. 教学准备 + +**工具与环境:** +- 每台电脑已安装 Trae IDE,可正常打开上节课(第9课)的战斗游戏文件 +- 每台电脑浏览器可正常播放 Web Audio(Chrome/Edge 均支持,确认未被系统静音) +- 投影可切换至任意学生屏幕 +- 准备两个演示文件:`demo-2-pk-battle.html`(无动画版)和 `demo-3-animation.html`(有动画版) + +**教学资源:** +- 教师准备:`demo-3-animation.html` 在本机调试好,各按钮动画流畅可用 +- 教师准备:「动画增量需求」保底提示词(见第5节)、「音效合成」保底提示词(见第5节) +- 教师准备:Web Audio 三行代码片段(在 Kimi 里提前验证过能正常合成音效) +- 学生资源:上节课(第9课)完成的战斗游戏 `index.html`,血条/行动/胜负判定已可用 + +**教师备课体验任务:** +> 备课前,教师必须亲自完成以下操作: +> +> 1. 打开 `demo-2-pk-battle.html`,实际点一遍「普通攻击、重击、格挡、特技」四个按钮,感受没有动画时的体验——记录「哪里感觉很空洞」 +> 2. 打开 `demo-3-animation.html`,同样点一遍四种行动,对比感受差距——这是课堂对比演示的素材 +> 3. 用「动画增量需求」保底提示词向 Kimi 提交一次,拿到动画代码片段,在自己的测试文件里跑通——记录可能遇到的报错 +> 4. 写一段 Web Audio 代码合成「攻击音效」,在浏览器里验证能正常播放(注意 Chrome 需要用户交互后才能触发音频) +> 5. 确认学生电脑音量未被静音,Web Audio 可正常发声 + +--- + +### 4. 教学流程 + +--- + +**第一幕:联系 (Connect) — 10分钟** 🔗 + +*本幕目标:通过无动画 vs 有动画的真实对比,让学生切身感受「游戏感」的差距,建立「视觉反馈是游戏的灵魂」的直觉* + +**【环节】上节课回顾 (2分钟)** + +**师:** 上节课我们做了什么?谁来说一下我们的战斗系统现在能做什么? + +**生:**(预期:有血条、可以攻击、有胜负、有特技) + +**师:** 对,上节课我们还跑了测试脚本,伤害公式和胜负判定都验证通过了。今天我问你们——你们觉得现在这个游戏,好玩吗?好看吗? + +**生:**(预期:还行 / 感觉有点无聊 / 就是点按钮数字变化) + +**师:** 嗯。现在先别回答,我让你们看两个版本——看完再说。 + +**【环节】对比演示——无动画 vs 有动画 (8分钟)** + +【投屏展示 demo-2-pk-battle.html,教师操作】 + +**师:** 这是我们现在的版本。我点一下「普通攻击」—— + +【点击普通攻击,血条数字变化,但角色没有任何动作】 + +**师:** 发生了什么? + +**生:**(预期:血量少了 / 没什么感觉 / 就是数字变了) + +**师:** 对,血条从 100 变成了 85。游戏逻辑是对的。那感觉呢? + +**生:**(预期:感觉很平淡 / 不知道攻击有没有打出去 / 没什么反应) + +**师:** 好,这个感受记住。现在看第二个版本。 + +【切换投屏到 demo-3-animation.html】 + +**师:** 同样的游戏,我点「普通攻击」—— + +【点击普通攻击,角色冲刺向对方,对方受击抖动,音效响起】 + +**师:** 现在感觉怎么样? + +**生:**(预期:爽多了!/ 有打击感 / 感觉真的在打架) + +【继续演示重击:角色蓄力放大→猛冲,屏幕震动】 +【演示格挡:角色后退,护盾闪烁】 +【演示特技:粒子效果爆发】 + +**师:** 这两个游戏,逻辑是完全一样的。血条、伤害、胜负——一模一样。唯一的区别是什么? +【诊断点:学生是否能说出「动画」「视觉反馈」「音效」等关键词】【识别层】 + +**【分支A】若学生说出「动画」「特效」「声音」:** +**师:** 对!动画、音效、视觉反馈。这些加在一起,有一个专门的词——叫做「游戏感(Game Feel)」。什么叫游戏感?就是每次你操作,都有看得见、听得到的反馈——你的动作「生效了」。没有游戏感的游戏,就算逻辑完美,玩起来也像在操作表格。 + +**【分支B】若学生说「好看多了但说不出为什么」:** +**师:** 你说好看多了,我问你——当你点普通攻击的时候,第一个版本你看到了什么? +**生:**(预期:数字变了) +**师:** 第二个版本呢? +**生:**(预期:角色冲过去了、对方抖了) +**师:** 对。第一个版本你的操作「发生了」但你看不到。第二个版本你的操作「生效了」,你看得到、感受得到。这种「每次操作都有反馈」的体验,叫「游戏感」。今天我们的任务就是把游戏感加到你们的战斗系统里。 + +**师:** 今天三件事:第一,给每种行动加动画;第二,加上音效;第三,让特技有独特的视觉标记。加完之后,你的战斗游戏就「活了」——可以参加下节课的班级对战了。 + +--- + +**第二幕:建构 (Construct) — 65分钟** 🛠️ + +--- + +**【分段一:动画系统——用感觉描述需求】(20分钟)** + +*本段重点:学会用「感觉语言」而不是技术参数来描述动画;学会写增量需求(只写新增的动画部分,不重写已有战斗逻辑)* + +**预设误概念:** +- 误概念 M3:增量需求要把整个需求文档重写一遍 +- 误概念 M4:动画描述必须用技术参数(duration: 200ms) + +**讲解与演示 (Teach & Demo): (5分钟)** + +**师:** 我们要给战斗系统加动画。但加动画不是从头重写游戏——我们用「增量需求」的方式,只告诉 AI 「新加什么」,已有的代码不动。 + +**师:** 有人知道为什么不能重写吗? + +**生:**(预期:不知道 / 会改坏 / 太麻烦) + +**师:** 你上节课的战斗逻辑,血条、伤害、胜负——都测试通过了,是吧?如果我现在把整个需求文档重写一遍提交给 AI,AI 很可能会「重新理解」你的战斗逻辑,把你已经调好的伤害公式改掉,或者把你的特技系统换一种方式实现。这叫「误改」。增量需求就是告诉 AI:「已有的代码已经验收通过,你只需要在这个基础上加动画,不要动其他东西。」 + +**师:** 就像你家装修完了,现在只想加一个书架——你不会让装修工人重新来一遍,你只说「加一个书架,其他不动」。 + +**师:** 然后——动画要怎么描述?我问你:你觉得「普通攻击」的感觉应该是什么样子的? + +**生:**(预期:冲过去 / 快速冲向对方 / 用力打一下) + +**师:** 好,「快速冲向对方」——再具体一点,冲过去之后呢? + +**生:**(预期:然后回来 / 弹回来) + +**师:** 对!「快速冲向对方,然后弹回来」——这就是动画描述。不需要说「x偏移100像素,duration 200ms,ease Power2」——你只需要说出感觉,AI 会把感觉翻译成参数。 + +【投屏展示对比】 +``` +❌ 技术参数描述: +普通攻击:x += 100, duration: 200, ease: 'Power2', yoyo: true + +✅ 感觉描述: +普通攻击:攻击方快速冲向对方,然后弹回原位,感觉轻快有力 +``` + +**师:** 我们来做个小练习——每个人说出四种行动的感觉,不要用技术词汇,就说你脑子里的画面。 + +【投屏展示四种行动,每个留5秒空白让学生思考】 + +| 行动 | 你脑子里的画面是什么? | +|------|---------------------| +| 普通攻击 | ? | +| 重击 | ? | +| 格挡 | ? | +| 受击 | ? | + +**师:** 说一下,「重击」你觉得是什么感觉? + +**生:**(预期:很用力冲过去 / 先蓄力然后猛冲 / 会震动) + +**师:** 「先蓄力然后猛冲」——太好了,这就是完美的感觉描述。AI 看到这个会知道要做两段动画:第一段蓄力(角色变大),第二段冲刺(快速位移)。 + +**学生实践 (Practice): (10分钟)** + +在窗口 A 里,学生用感觉语言写出增量需求,提交给 Kimi,获取动画代码。 + +> 教师走动观察:谁停下来不动超过2分钟立刻过去,观察他们写的感觉描述是否太技术化(「角色向右移动100px」)还是真的在用感觉语言 + +**学生写增量需求的结构提示(投屏展示):** +``` +我已有一个用 HTML/JavaScript 写的战斗游戏,战斗逻辑已经验收通过。 +现在我要新增动画系统,只描述新增部分,请不要修改已有的战斗逻辑。 + +普通攻击动画:[你的感觉描述] +重击动画:[你的感觉描述] +格挡动画:[你的感觉描述] +受击动画:[你的感觉描述] +死亡动画:[你的感觉描述] +``` + +**进度同步 (Checkpoint): (5分钟)** + +**师:** 谁来分享一下你写的感觉描述?用感觉语言写的举手。 +【诊断点:检验学生是否真的用了感觉语言,而不是技术参数】【理解层】 + +**【分支A】若学生写出了好的感觉描述(「像被闪电劈中一样抖动」):** +**师:** 这个描述太棒了!我们来看 AI 怎么翻译—— +【投屏展示 Kimi 返回的参数,对应学生的感觉描述】 +**师:** 你说「像被闪电劈中一样抖动」,AI 翻译成了「x 方向快速来回震荡5次,每次10像素,总时长150毫秒」。感觉对吗? + +**【分支B】若学生的描述还是偏技术(「角色向右移动」):** +**师:** 我来问你——你玩游戏里打人,那个「被打」的感觉是什么?能用一个词或一句话描述吗? +**生:**(预期:抖了一下 / 像撞墙一样 / 闪了一下) +**师:** 对,把这个感觉写进去,比说「向右移动」更准确——AI 更能理解你真正想要的效果。 + +**【分支C】若学生 AI 返回的动画代码与感觉不符:** +**师:** 你看一下动画效果,跟你想的感觉一样吗?哪里不对? +**生:**(预期:太慢了 / 感觉不够有力 / 角色跑的方向不对) +**师:** 好,现在你就直接告诉 AI:「重击感觉不够震撼,蓄力时间太短了,冲刺速度也不够快,能不能把蓄力时间加长一倍,冲刺速度加快?」——这就是用感觉来迭代。 + +--- + +**【分段二:音效系统——描述声音感觉】(20分钟)** + +*本段重点:用三行代码演示 Web Audio 合成原理;学会用「声音感觉」而不是技术参数描述音效需求;实现五种基础战斗音效* + +**预设误概念:** +- 误概念 M2:音效需要找音频文件,太麻烦了 +- 误概念 M4(延伸):描述音效也要用技术参数 + +**讲解与演示 (Teach & Demo): (5分钟)** + +**师:** 现在我们加音效。有人觉得加音效很麻烦的举手——要找音频文件、下载、导入…… + +**生:**(预期:举手 / 点头) + +**师:** 告诉你们一个秘密——我们不需要任何音频文件。我们用代码「生成」声音。 + +【投屏展示,教师打开浏览器控制台】 + +**师:** 这是 Web Audio API——浏览器内置的音频引擎。我现在在控制台里写三行代码,让浏览器发出一个「攻击音效」。 + +【现场演示,逐行输入并解释】 + +```javascript +const ctx = new AudioContext(); +const osc = ctx.createOscillator(); +osc.frequency.value = 300; // 音调——300 是中等音高 +osc.type = 'sawtooth'; // 波形——锯齿波比较「粗糙有力」 +const gain = ctx.createGain(); +gain.gain.value = 0.3; // 音量 +osc.connect(gain); +gain.connect(ctx.destination); +osc.start(); +setTimeout(() => osc.stop(), 80); // 只响 80 毫秒 +``` + +**师:** 听到了吗?这是攻击音效——短促有力,像轻击。全部代码就这几行,不需要任何文件。 + +**师:** 和动画一样,音效也用感觉来描述。我来问你——「重击」的声音是什么感觉? + +**生:**(预期:低沉 / 爆炸感 / 震动 / 轰的一声) + +**师:** 「低沉震撼,像爆炸」——这就是感觉描述。告诉 AI 这个感觉,AI 会帮你调频率、波形、时长。你不需要知道「锯齿波还是方波」——你只需要知道「你要什么感觉」。 + +【投屏展示感觉→参数对应表】 + +| 行动 | 声音感觉(你来填) | AI 可能翻译成 | +|------|----------------|-------------| +| 普通攻击 | 短促有力,像轻拍 | 频率300Hz,锯齿波,80ms | +| 重击 | 低沉震撼,像爆炸 | 频率150Hz,锯齿波,150ms | +| 格挡 | 硬邦邦,像金属碰撞 | 频率800Hz,方波,50ms | +| 受击 | 痛感,短促的「嗷」 | 频率400→150Hz扫频,120ms | +| 胜利 | 欢快,像叮当 | 三音符523→659→784Hz,正弦波 | + +**学生实践 (Practice): (10分钟)** + +学生打开窗口 B(独立于战斗游戏),用感觉描述让 Kimi 生成五种音效代码。验证每种音效能正常播放后,再把音效函数添加进战斗游戏的对应行动里。 + +> 教师走动观察重点: +> 1. 学生在描述音效时是否用了感觉语言还是乱写参数 +> 2. 音效代码添加进战斗游戏后,有没有整合进「行动触发」时机(不能只是独立的函数,要在攻击时自动调用) + +**进度同步 (Checkpoint): (5分钟)** + +**师:** 谁来演示一下?点一个行动,我们听听音效。 +【让1-2位学生上来演示战斗,播放音效】 +【诊断点:音效是否在正确的时机触发(点攻击时响,而不是游戏开始时就响)】【应用层】 + +**【分支A】若音效在正确时机触发且效果合理:** +**师:** 注意听——每次点攻击有没有声音?每种行动的声音有没有区别? +【让全班听对比,引导学生注意重击和普通攻击的音效差异】 +**师:** 好,把这个感觉记住——有音效和没音效,游戏感差距很大。 + +**【分支B】若音效能响但时机不对(比如每隔一秒自动响):** +**师:** 音效响了,但是时机有点问题——应该是点攻击时响,而不是自动响。你的音效函数是在哪里被调用的? +**生:**(查代码)……好像放到外面了? +**师:** 对,你需要把 `playSound_attack()` 这个函数的调用,放进你处理「普通攻击」按钮点击的那个函数里——告诉 AI:「请把音效调用放在行动触发时,不要自动播放」。 + +**【分支C】若音效完全没有声音(Chrome 浏览器 AudioContext 未激活):** +**师:** 先检查电脑音量,再检查——在 Chrome 里,必须是用户点击页面之后,音频才能播放。你有没有先点一下游戏页面,再点攻击按钮? +【引导学生先点一下页面,激活 AudioContext,然后再试】 + +--- + +**【分段三:特技视觉效果完善 + 平衡性调整】(15分钟)** + +*本段重点:给每个特技加上独特的视觉标记(粒子/颜色/光效),让玩家能感知特技「生效了」;同时微调特技触发概率让对战更平衡* + +**预设误概念:** +- 误概念 M5:特技效果只要触发就行,不需要视觉区分 + +**讲解与演示 (Teach & Demo): (4分钟)** + +**师:** 最后一段——特技。你们的特技现在已经有效果了,对吧?但我问你——燃烧特技触发了,你怎么知道它触发了? + +**生:**(预期:有文字提示 / 看日志 / 对方血量变化快) + +**师:** 靠文字提示来告诉玩家「特技触发了」——这叫什么?这叫「说给玩家听」。而好的游戏是「让玩家感受到」。 + +**师:** 每个特技必须有专属的视觉标记——就像每种英雄技能有自己的颜色。我来给你们看几个方向: + +【投屏展示特技视觉效果参考】 + +``` +🔥 燃烧:目标角色持续冒出橙红色小粒子,向上飘散 +🛡 护甲:角色周围出现蓝色光圈,护盾吸收伤害时闪烁 +⚡ 连击:第二次攻击时黄色闪光从角色身上爆发 +💉 吸血:攻击时绿色光线从对方身上流向自己 +❄️ 冰冻:对方角色整体变蓝(tint 0x4444ff),出现碎冰粒子 +🎯 穿透:攻击线变红色,穿过对方护盾 +``` + +**师:** 你的游戏里有哪种特技?现在打开需求文档,给你的特技加一条「视觉效果描述」——用感觉语言,告诉 AI 特技触发时玩家应该「看到什么」。 + +**学生实践 (Practice): (8分钟)** + +学生在窗口 A(增量需求)里补充特技视觉效果描述,提交给 Kimi 生成代码;同时,根据上节课测试结果,检查特技触发概率是否合理(可调整概率,让对战更有趣),把最终版战斗游戏跑通。 + +> 教师走动重点:检查学生的特技视觉效果是否真的有视觉差异,而不是所有特技都做成「同一种颜色的粒子」 + +**进度同步 (Checkpoint): (3分钟)** + +**师:** 好,现在所有人试玩一下自己的战斗游戏——从开始到有人胜利,完整走一遍。有动画、有音效、有特技视觉效果的请举手。 +【诊断点:完整游戏循环(动画+音效+特技视觉)是否全部正常运行】【应用层】 + +**【分支A】若学生完整游戏循环正常:** +**师:** 很好,你的涂鸦PK已经有游戏感了。下节课的班级对战,就用这个版本。给自己鼓个掌。 + +**【分支B】若学生动画有但音效没有(或相反):** +**师:** 没关系,少一项我们继续加。现在缺的是哪一个?告诉我——动画、音效、特技视觉,哪个没做完? +【针对性引导完成缺失的部分,优先保证动画完整,音效可以只有三种基础音效也算通过】 + +**【分支C】若学生整个游戏运行出错:** +**师:** 现在打开浏览器的控制台(F12),看一下有没有红色的报错信息,把报错信息截图或者复制下来,告诉 AI「我在运行时遇到了这个报错,请帮我定位问题」——这是你们最后一次用 AI 调试,我们在课堂上解决。 + +--- + +**第三幕:反思 (Contemplate) — 10分钟** 🤔 + +**【环节】成果展示 (6分钟)** + +**师:** 好,时间到。谁愿意来展示一下今天的战斗游戏?要展示三件事:第一,你的角色是谁;第二,你加了什么样的动画;第三,你设计了什么特技的视觉效果。 + +【邀请 2-3 名学生展示,每人 1.5 分钟】 + +**师:** 展示的时候,先说你「用感觉描述了什么」,再演示效果——让大家看你的感觉描述和 AI 翻译出来的代码,差距有多大。 + +【第一位学生展示】 + +**师:** 你说「重击感觉像被大锤砸到」,AI 做出来的效果,符合你的感觉吗? + +**生:**(预期:基本符合 / 比我想的还要好 / 有一点不对但我改了) + +**师:** 好——改了几次才满意? + +**生:**(预期:两三次) + +**师:** 两三次迭代就做到满意——这就是「用感觉描述 + 迭代优化」的效率。 + +**【环节】互评与讨论 (4分钟)** + +**师:** 谁来给刚才展示的游戏说「一个优点 + 一个改进建议」?要具体说,不能只说「很好看」。 + +**生:**(预期:动画很流畅,但是音效重击的声音感觉不够震撼) + +**师:** 好,「不够震撼」——怎么改? + +**生:**(预期:声音低一点 / 时间长一点 / 加个爆炸效果) + +**师:** 对,这就是具体的改进建议。今天我们训练的核心能力是什么? + +**生:**(预期:动画 / 音效 / 特效) + +**师:** 这些都是工具。背后的能力是——**审美力**:用感觉描述「好不好看、好不好听」,让 AI 把你的感觉变成代码。审美力不是说「画画好看」,是说「你能不能清楚地描述一个体验,并且判断 AI 做出来的是不是你要的」。 + +--- + +**第四幕:延续 (Continue) — 5分钟** 🚀 + +**【环节】抽象总结 (3分钟)** + +**师:** 今天三件事,我们来总结一下。第一件是什么? + +**生:**(预期:动画 / 加了动画) + +**师:** 对,我们加了动画。背后的方法是什么? + +**生:**(预期:用感觉描述 / 感觉语言) + +**师:** 对——「用感觉描述需求」。不用技术参数,直接说你脑子里的画面,AI 来翻译。这个能力不只能用在游戏开发里——你想做一个网页、一个动效、一个演示文稿,都可以这样描述:「我想要一种……的感觉」,AI 来实现。 + +**师:** 第二件事,音效。背后的发现是什么? + +**生:**(预期:不需要音频文件 / 代码可以直接合成声音) + +**师:** 对——Web Audio API 用代码合成声音。零文件,浏览器内置。这说明一件事:很多你以为「需要素材」的东西,代码都可以直接生成。 + +**师:** 第三件事,特技视觉效果。核心原则是什么? + +**生:**(预期:要让玩家看得见 / 每种特技要有独特的效果) + +**师:** 对——「让玩家感受到,而不是告诉玩家」。这是所有好游戏的共同原则。 + +**【环节】下节预告 + 5分钟挑战 (2分钟)** + +**师:** 下节课——班级大乱斗。你们的战斗游戏会互相对战,不同角色、不同特技。在对战之前,你有机会再调整一次你的特技参数——如果你觉得你的角色太弱,可以偷偷增强一点…… + +**生:**(预期:笑声 / 期待) + +**师:** ……但是太强了也不行,因为我会检查公平性。 + +**师:** 本周的5分钟挑战:给你的一个特技,加一个你自己设计的视觉特效——不用上课说的那些,完全自己想。描述感觉,让 AI 实现,下节课展示。 + +--- + +### 5. AI助教使用指南 + +**教师演示用提示词(动画增量需求):** +``` +我已有一个用 HTML + JavaScript 写的战斗游戏,代码在下面。 +战斗逻辑(血条、行动、伤害、胜负判定)已经验收通过,请不要修改。 + +现在我要新增动画系统,只描述新增的动画部分: +- 普通攻击:攻击方快速冲向对方100像素然后弹回来,感觉轻快有力 +- 重击:攻击方先膨胀变大(1.2倍,蓄力感),然后猛冲向对方150像素,对方水平抖动3次 +- 格挡:格挡方向后退50像素,同时闪烁两次(半透明/不透明切换,护盾感) +- 受击:被击方左右快速抖动(±10像素,3次),同时变红后恢复原色 +- 死亡:旋转360度同时缩小到0并淡出,600毫秒内完成 +- 胜利:上下弹跳3次(-30像素/次,200毫秒/次) + +请只输出新增的动画相关代码,以及在哪里插入。不要改动现有代码结构。 +``` + +**教师演示用提示词(音效合成,窗口 B):** +``` +我要用 Web Audio API 合成战斗游戏音效,全部在 HTML 里实现,不需要任何音频文件。 + +请帮我写以下音效函数(每个独立的 function),音效感觉描述如下: +1. playSound_attack():短促有力,像轻击金属,80毫秒 +2. playSound_heavy():低沉震撼,像远处爆炸,有一点回响感,150毫秒 +3. playSound_block():清脆硬邦邦,像剑挡住了另一把剑,50毫秒 +4. playSound_hit():短促的痛感,像「嗷」一声,120毫秒 +5. playSound_win():欢快的三音符上升,像「叮叮叮」,音调一个比一个高 + +每个函数调用时直接播放,不需要预加载。请输出可以直接放进 HTML 的完整代码片段。 +``` + +**学生保底提示词(动画增量需求,窗口 A):** +``` +我已有一个用 HTML/JavaScript 写的战斗游戏(代码如下)。 +战斗逻辑已验收,请不要修改已有代码。 + +在此基础上新增动画: +- 普通攻击:角色冲出去然后弹回 +- 重击:先蓄力放大再猛冲,对方抖动 +- 格挡:角色后退并闪烁 +- 受击:角色抖动并变红 +- 死亡:旋转消失 + +请只添加动画相关代码,告诉我在哪里插入。 +``` + +**学生保底提示词(音效合成,窗口 B):** +``` +请帮我用 Web Audio API 合成以下游戏音效,写成 HTML 代码片段,每个音效一个函数: +1. 普通攻击:短促有力的金属碰撞声 +2. 重击:低沉震撼的爆炸声 +3. 格挡:清脆的金属阻挡声 +4. 受击:短促的痛苦音 +5. 胜利:三音符上升的欢快音 + +函数名分别为 playSound_attack、playSound_heavy、playSound_block、playSound_hit、playSound_win。 +调用时直接播放,不需要任何音频文件。 +``` + +**进阶提示词(特技粒子效果):** +``` +我的战斗游戏有一个「燃烧」特技,触发时目标会持续受到灼烧伤害。 +请帮我用 Canvas 2D API(不用任何外部库)实现: +- 燃烧状态下,目标角色周围持续出现橙红色小粒子 +- 粒子从角色身体向上飘散,透明度随时间降低到0后消失 +- 燃烧持续3秒,期间粒子效果一直在 +请只给我新增的粒子系统代码,以及调用时机说明。 +``` + +--- + +### 6. 教师指南 + +**本课技术备注:** + +**关于 Canvas 动画实现方式(不用 Phaser 的情况下):** +本课的战斗游戏基于 HTML Canvas 2D 直接绘制(无 Phaser),动画通过 `requestAnimationFrame` 循环和时间差(deltaTime)驱动。动画「缓动感」来自 lerp(线性插值):每帧把当前位置向目标位置靠近一小步,产生「减速停下」的感觉。AI 生成的代码通常会用 `let t = 0; t += deltaTime / duration` 的方式控制进度,0到1之间变化,再套上缓动函数(如 `1 - (1-t)^3`)产生弹性效果。 + +**关于 Web Audio API 的自动播放限制:** +Chrome/Edge 要求页面必须有用户交互(点击/键盘输入)后,才允许 `AudioContext` 播放声音。如果游戏一打开就尝试播放,会被浏览器拦截(报错:`AudioContext was not allowed to start`)。解决方案:把第一个 `AudioContext` 的创建放在用户点击按钮之后,或者用 `ctx.resume()` 在点击时激活。AI 生成的代码不一定会处理这个问题,需要教师在课堂提醒。 + +**关于增量需求的上下文传递:** +让学生在「增量需求提示词」里把整个现有代码粘贴进去,Kimi 才能根据现有代码结构插入新代码。如果不提供现有代码,Kimi 会自己猜代码结构,生成的插入位置可能不对。提醒学生:「把你的战斗游戏代码全选复制,粘贴到提示词末尾」。 + +**关于特技粒子效果的性能:** +粒子效果如果每帧创建大量 DOM 元素,会导致游戏卡顿。告诉学生用 Canvas 绘制粒子(在 `requestAnimationFrame` 里画圆点),不要让 AI 创建 `
` 元素来做粒子。如果学生的游戏明显卡顿,检查是否有粒子数组无限增长的问题(每帧加粒子但不清除),引导学生告诉 AI「粒子消失后从数组里删除」。 + +**常见问题 FAQ:** + +| 问题 | 应对 | +|------|------| +| 「动画代码加进去之后,血条不显示了」 | 很可能是 Canvas `clearRect` 的调用顺序被改了,告诉 AI:「加了动画代码后血条不显示,请检查 clearRect 和绘制顺序是否被修改」 | +| 「音效能响但是每次攻击响很多次」 | `playSound_attack` 函数被错误地放在了 `requestAnimationFrame` 里,每帧都在调用;告诉 AI「音效每次行动只应该播放一次」 | +| 「死亡动画结束后角色还留在屏幕上」 | 死亡动画只改了透明度,没有在动画结束后将角色标记为「已死亡」并停止绘制;引导学生告诉 AI「动画结束后停止绘制该角色」 | +| 「特技粒子效果触发一次后就一直在了」 | 粒子系统的「存活时间」逻辑没有实现,粒子永远不消失;告诉 AI「每个粒子有3秒存活时间,时间到了就从数组里移除」 | +| 「我的重击蓄力动画太慢了游戏变拖沓」 | 这是审美判断问题,直接让学生告诉 AI:「蓄力时间改成 150ms,冲刺时间改成 80ms,感觉更爽快」 | +| 「Chrome 没有声音」 | 先确认系统音量;再确认是否先点击了游戏页面;最后检查 `AudioContext` 是否在按钮点击后创建 | + +**课堂风险预案:** +- **如果 Kimi 返回的代码加进去运行报错:** 让学生把报错信息复制给 Kimi,提示词格式:「我按你说的把代码加进去了,运行时出现了这个报错:[报错信息],原来的代码是 [原代码],请帮我找到原因并给出修正后的代码」 +- **如果学生进度差异过大(有人全部做完有人还没做动画):** 做完的学生进入拓展任务(给特技加粒子效果 + 调平衡性);做到一半的学生优先完成动画,音效用保底提示词一步到位 +- **如果整体时间不够(25分钟建构还剩两段没做完):** 合并分段二和分段三,音效只做三种基础音效(攻击/受击/胜利),特技视觉效果作为课后挑战 + +--- + +### 7. 5分钟日常AI挑战 + +**本周挑战:** 给你的一个特技,设计一个全新的视觉特效 + +**挑战说明:** +选你游戏里你最喜欢的一个特技,想象它触发时应该「看起来像什么」——可以是粒子爆炸、颜色变化、屏幕震动、时间静止特效……只要用感觉语言描述出来,告诉 AI 实现。要求:这个特效必须和课上做的不一样,完全是你自己的设计。 + +**下节课分享:** 下周课上选 2-3 位同学展示特技特效挑战成果,说明自己是怎么描述感觉的,AI 实现了几轮才满意。 + +--- + +### 8. 拓展任务 + +**拓展一(推荐):屏幕震动特效** +重击时,不只是角色抖动——整个游戏画布轻微震动一下(Canvas 偏移 ±5 像素,持续 200ms)。这种效果叫「屏幕震动(Screen Shake)」,是格斗游戏的经典手法。用感觉描述让 AI 实现:「重击时整个画面抖一下,像相机被猛地推了一把」。 + +**拓展二(挑战):行动预判音效** +在角色攻击「蓄力」阶段播放一个低频「嗡——」的充能音效,攻击命中时再播放冲击音效——两段音效组合,制造出「蓄力→爆发」的完整听觉体验。提示:需要两个 Web Audio 函数,第一个在蓄力开始时调用,第二个在命中时调用,注意时机控制。 + +--- + +### 附:本课核心教学框架速查 + +**四幕时间分配(合计 90 分钟):** + +| 幕 | 内容 | 时长 | +|----|------|------| +| 联系 Connect | 对比演示无动画 vs 有动画,引出「游戏感」 | 10 分钟 | +| 建构 · 分段一 | 感觉语言描述动画,写增量需求 | 20 分钟 | +| 建构 · 分段二 | 用代码合成音效,整合进战斗行动 | 20 分钟 | +| 建构 · 分段三 | 特技视觉标记完善 + 平衡性微调 | 15 分钟 | +| 反思 Contemplate | 成果展示 + 感觉描述回顾 + 互评 | 10 分钟 | +| 延续 Continue | 抽象总结三件事 + 预告班级对战 + 挑战发布 | 5 分钟 | + +**本课核心能力训练路径:** + +``` +审美力路径: +无动画体验(识别层) +→ 用感觉描述动画/音效需求(理解层) +→ 对比 AI 输出和自己预期,定位差距(应用层) +→ 精准迭代修改,达到满意(迁移层) + +提问力路径: +理解增量需求的必要性(识别层) +→ 只写新增部分的提示词,不重写全局(理解层) +→ 在已有代码基础上定向追加功能(应用层) +``` + +**关键词速查(下课前可口头检查学生是否能解释):** +- 游戏感(Game Feel):每次操作都有视觉/听觉反馈,让玩家感受到行动生效 +- 增量需求:在已验收代码基础上只描述新增部分,避免 AI 误改 +- Web Audio API:浏览器内置音频引擎,用代码合成声音,无需音频文件 +- 感觉语言:用描述体验和画面感的词汇提需求,而非技术参数 diff --git a/3-lessons/AICODE-06/AICODE06-11 涂鸦PK(四)— 班级锦标赛.md b/3-lessons/AICODE-06/AICODE06-11 涂鸦PK(四)— 班级锦标赛.md new file mode 100644 index 0000000..c13cb20 --- /dev/null +++ b/3-lessons/AICODE-06/AICODE06-11 涂鸦PK(四)— 班级锦标赛.md @@ -0,0 +1,599 @@ +--- +课时: 11 +主题: 涂鸦PK(四)— 班级锦标赛 +核心能力: [表达力, 共创力] +核心工具: [Trae IDE, Kimi] +时长: 90分钟 +透明化层级: 结果层 +适用路线: AICODE-06 +--- + +### 1. 课程目标 + +**知识目标:** +- 理解「数据驱动设计」的核心思想:角色数据与游戏代码分离,加新角色只需加文件,代码不用改 +- 理解角色选择界面是「数据读取 + UI 展示」的组合,而非把所有角色写死在代码里 +- 理解路演的核心是「设计决策」而非「功能列表」:说清楚「为什么这样做」比「做了什么」更有价值 + +**能力目标:** +- 能用增量需求文档描述 roles 系统,并经过窗口B审核、窗口C执行(共创力) +- 能在班级锦标赛中用语言分析胜负原因,做出有依据的复盘(表达力) +- 能按「展示角色→设计意图→精彩瞬间→设计复盘」结构完成3分钟路演(表达力) + +**情感目标:** +- 感受到「自己的角色和全班的角色一起对战」的真实社交激励 +- 建立「输了是迭代的起点」而非「输了说明设计失败」的成长心态 +- 对「数据和代码分离」产生直觉性认同——这是真实工程师的设计方式 + +--- + +### 2. 核心概念与误概念预设 + +**核心概念认知层级:** + +| 概念 | 学生类比 | 认知层级 | +|------|---------|---------| +| 数据驱动设计 | 游戏皮肤系统——你换皮肤不需要重新下载整个游戏,皮肤是「数据」,游戏逻辑是「代码」,两者分离 | 理解层 | +| 硬编码 | 把菜单直接印在餐厅墙上——想加一道菜要重新刷墙 | 识别层 | +| roles 系统 | 班级花名册——班里来了新同学,只需要在花名册上加一行,不需要改班级的所有规则 | 理解层 | +| 增量需求 | 在已有房子里加一个房间——不是推倒重建,而是在现有结构上扩展 | 应用层 | +| 路演设计决策 | 苹果发布会不说「这个手机有摄像头」,而是说「为什么这个摄像头改变了拍照方式」 | 应用层 | + +**典型误概念表:** + +| 编号 | 误概念 | 正确认知 | 激发策略 | +|------|--------|---------|---------| +| M1 | 加新角色需要改代码 | 数据驱动设计:加一个 json 文件 = 加一个角色,代码不用改 | 演示:不改一行代码,只在 roles/ 文件夹里加一个新 json,新角色就出现在选择界面 | +| M2 | 路演就是说「我做了什么功能」 | 路演要说「我为什么这样设计」——设计决策比功能列表更有价值 | 类比苹果发布会:发布会不说「手机有摄像头」,而是说「为什么这颗摄像头改变了拍照方式」 | +| M3 | 属性随便分的角色不可能赢认真分的 | 「奇怪」的属性分配有时会产生意外的克制效果;游戏平衡比绝对强度更重要 | 展示一个「全部堆 HP」的坦克型角色用消耗战赢了「全部堆 ATK」的爆发型角色 | +| M4 | 输了说明自己设计失败了 | 输了是迭代的起点;「如果重来属性怎么分」才是最有价值的问题 | 强调:世界上最厉害的游戏设计师也在持续迭代,没有「一次设计就完美」的 | + +--- + +### 3. 教学准备 + +**工具与环境:** +- 每台电脑已安装 Trae IDE,第10课的战斗游戏项目可以正常运行 +- 每台电脑有学生自己的角色图片(.png)和角色数据(.json) +- 投影可切换至任意学生屏幕,用于锦标赛投屏 +- 教师电脑预建好 `roles/` 文件夹结构(用于演示数据驱动) + +**教师备课必做(课前):** +> 1. 提前向每位学生收集角色文件(角色名.png + 角色名.json),放入教师电脑 `roles/` 文件夹 +> 2. 在教师电脑上跑一遍 roles 系统生成流程,确保角色选择界面正常读取所有角色 +> 3. 准备好「花名册投屏」:一个展示全班角色名字 + 特技的页面或截图 +> 4. 准备好锦标赛对阵表(单淘汰制,根据班级人数提前画好括号) +> 5. 备用方案:如果 roles 系统生成失败,手动在代码里加角色选择下拉菜单(15分钟内可完成) + +**教学资源:** +- 教师准备:全班 roles/ 文件夹(含所有 png + json) +- 教师准备:锦标赛对阵表(投屏用) +- 教师准备:保底提示词(见第5节) +- 学生资源:第10课的战斗游戏项目文件(index.html) + +--- + +### 4. 教学流程 + +--- + +**第一幕:联系 (Connect) — 10分钟** 🔗 + +*本幕目标:用「角色花名册」制造全班兴奋感,引出数据驱动概念,建立「今天是全班大乱斗」的期待* + +**【环节】角色花名册 + 今日导入 (10分钟)** + +**师:** 课前我收集了大家的角色文件。我现在打开,给大家看看今天的「选手花名册」。 + +【投屏展示花名册——所有角色的名字、HP/ATK/DEF/SPD 属性、特技名称】 + +**师:** 你们来数一数,今天一共有多少个角色参赛? + +**生:** (数人数)……XX 个! + +**师:** XX 个角色,今天全部都要上场对战。谁是最强的?我们今天锦标赛见真章。 + +【停顿 3 秒,让兴奋感发酵】 + +**师:** 但我现在遇到一个问题。大家的游戏现在只能用「硬编码」的两个角色。什么叫硬编码?就是角色数据直接写死在代码里,像这样—— + +【投屏展示代码片段】 + +```javascript +// 角色数据写死在代码里 +const player = { name: '章鱼怪', hp: 80, atk: 15, def: 5, spd: 8 }; +``` + +**师:** 这种写法,想换一个角色,要去代码里改数字。想加一个新角色,要再写一段代码。如果班里有 8 个角色要互相打,要改多少次代码? +【识别层:让学生感受到硬编码的局限性】 + +**生:** (预期:很多次……要改来改去) + +**师:** 对,非常麻烦。今天我们要做一件事——用「数据驱动」的方式重新设计这个系统。做完之后,加新角色只需要加一个 json 文件,代码一行都不用改。我们先做好这个系统,然后——锦标赛开始。 + +【诊断点:学生是否感受到「数据驱动」和「硬编码」的差别,还是觉得无所谓】【识别层】 + +**【分支A】若学生问「数据驱动是什么意思」:** +**师:** 你知道游戏皮肤吗?比如王者荣耀,你换一个皮肤,不需要重新下载整个游戏对吧?皮肤就是「数据」,游戏逻辑是「代码」,两个东西分开存放。我们今天就是要把角色数据从代码里分离出来,放进独立的 json 文件。 + +**【分支B】若学生觉得「改代码也没什么,反正能跑」:** +**师:** 如果你做的游戏将来要卖给别人,需要经常更新角色,每次更新都要改代码,那维护成本是很高的。数据驱动就是为了让「扩展」变得简单——这是真实游戏公司的标准做法。 + +--- + +**第二幕:建构 (Construct) — 65分钟** 🛠️ + +*本幕目标:完成 roles 系统(数据驱动角色选择);举办班级锦标赛* + +--- + +**【分段一:roles 系统——数据驱动设计实战】(20分钟)** + +**预设误概念:** +- 误概念 M1:加新角色需要改代码(核心要破除的误概念) +- 学生可能认为「从文件夹读取 json」很难实现,需要很复杂的代码 + +**讲解与演示 (Teach & Demo): (5分钟)** + +**师:** 现在我们用三个窗口来完成这个系统。还记得三窗口原则吗? + +**生:** (预期:窗口A写需求,窗口B审核,窗口C执行) + +**师:** 对。今天的需求是「增量需求」——不是从头做,而是在现有战斗游戏上加一个新模块。我先给大家看增量需求文档长什么样。 + +【投屏展示增量需求文档内容,逐条讲解】 + +**师:** 这份需求文档有四条核心要求。我来念一遍: +第一,从 roles/ 文件夹读取所有 .json 文件,每个文件包含 name、hp、atk、def、spd、skill 字段。 +第二,显示角色选择界面:左边选玩家角色,右边选 AI 角色,每个角色显示名字和属性。 +第三,有「开始战斗」按钮,点击后进入战斗,加载选中角色对应的同名 .png 作为 Spritesheet。 +第四,不需要重写整个游戏——只增加角色选择这一层,原来的战斗逻辑不动。 + +**师:** 注意最后一条——「不重写整个游戏」。这就是增量需求的核心。我们不推倒重来,我们在现有基础上扩展。 + +现在我演示一下最重要的一步——数据驱动设计的关键代码思路。 + +【投屏展示两种写法对比】 + +``` +硬编码方式(现在): +代码里直接写 { name: '角色A', hp: 80, atk: 15 ... } +→ 想加角色:改代码 + +数据驱动方式(今天要做): +读取 roles/角色A.json → 代码只负责读取,不存储数据 +→ 想加角色:在 roles/ 文件夹里加一个新 json 文件,代码不变 +``` + +**师:** 看到区别了吗?现在窗口A的需求文档大家已经看到了,我们直接去窗口B审核。 + +**学生实践 (Practice): (12分钟)** + +【教师打开窗口B(新的 Kimi 对话),投屏展示审核提示词】 + +**师:** 窗口B的提示词是—— + +``` +你是一个严格的需求审核工程师。我有一份增量需求文档,请找出其中可能的漏洞和没说清楚的地方。每个问题单独列出来,只问问题,不给解决方案。 + +需求文档: +[粘贴增量需求内容] +``` + +**师:** 大家现在把窗口B打开,把这个提示词加上你自己的增量需求,提交审核。我来演示一遍,你们同步做。 + +> 教师同步演示窗口B审核过程,投屏展示 AI 找出的问题(如:roles/ 文件夹里没有 png 文件只有 json 怎么处理?同一个角色能选两次吗?) + +**师:** AI 找到了这几个问题。大家对照一下,你的窗口B找到了什么问题? + +**生:** (预期:找到类似问题,或发现自己的需求文档有遗漏) + +**师:** 好,把 AI 问的问题答案补充进需求文档。然后开窗口C执行。窗口C的提示词见屏幕。 + +【投屏展示保底提示词,学生复制使用】 + +> 教师巡视:谁的屏幕 3 分钟没变化就主动过去。重点关注窗口C是否用了「只输出新增/修改的代码」指令,避免 AI 重写整个游戏。 + +**进度同步 (Checkpoint): (3分钟)** + +**师:** 谁的角色选择界面已经出来了?截图或者展示屏幕。 + +【让 1-2 位学生展示屏幕】 + +**师:** 你试试——现在不改一行代码,把一个新的 json 文件放进 roles/ 文件夹,刷新页面,新角色出现了吗? +【诊断点:验证学生是否真正实现了数据驱动,而不只是在选择界面里把角色名字硬编码进去】【应用层】 + +**【分支A】若角色自动出现了:** +**师:** 这就是数据驱动。你的代码现在可以无限扩展角色,不需要碰代码本身。这是真实游戏公司的标准做法。 + +**【分支B】若角色没有自动出现(角色名写死在选择界面里):** +**师:** 看一下你的选择界面代码,角色名是直接写在 HTML 里还是从文件里读的?如果是写在 HTML 里,说明还是硬编码,需要让 AI 改成读取 json 文件的方式。提示词这样说:「我的角色选择界面现在是把角色名硬编码在 HTML 里的,请改成从 roles/*.json 文件里读取,动态生成选择列表。」 + +**【分支C】若 AI 把整个游戏重写了:** +**师:** 这是常见的情况——AI 有时候会把整个代码重写一遍。发现这个情况后,告诉 AI:「请不要重写整个游戏,只输出 roles 系统的新增部分,我自己复制进去。」然后把新增部分手动粘贴到原来的代码里。 + +--- + +**【分段二:班级锦标赛——全班大乱斗】(30分钟)** + +**预设误概念:** +- 误概念 M3:属性随便分的角色不可能赢认真分的 +- 误概念 M4:输了说明自己设计失败了 + +**讲解与演示 (Teach & Demo): (3分钟)** + +**师:** roles 系统已经完成了。现在游戏可以选任意角色对战了。我们正式开始今天的班级锦标赛! + +【投屏展示锦标赛对阵表】 + +**师:** 规则说明。单淘汰赛制。每场对战:一方选自己的角色,另一方选自己的角色,战斗5回合。5回合后谁 HP 多谁赢;如果有一方 HP 归零,提前结束。每场大约 2-3 分钟。赢的人晋级,输的人直接进入路演准备。 + +**师:** 在每场开始之前,我会给大家介绍两个角色的属性和打法,然后问你们——你们觉得谁会赢? + +**师:** 有没有问题? + +> 如果学生有问题,简短回答;如果没有,直接开始第一场 + +**学生实践 (Practice): (25分钟)** + +【锦标赛主持逐字稿,每场 2-3 分钟】 + +**第一场开始前:** + +**师:** 第一场对阵:[角色A] vs [角色B]。我来介绍一下这两位选手—— + +[角色A] 是 [学生名] 设计的,[角色名],属性是 HP[数字]、ATK[数字]、DEF[数字]、SPD[数字],特技是[特技名]。从属性看,这是一个[分析:高ATK爆发型 / 高HP坦克型 / 高SPD速攻型]的角色。 + +[角色B] 是 [学生名] 设计的,[角色名],属性是 HP[数字]、ATK[数字]、DEF[数字]、SPD[数字],特技是[特技名]。这是一个[分析]的角色。 + +你们觉得谁会赢?举手投票——投 [角色A] 的举手……投 [角色B] 的举手…… + +好,开始! + +【由第一个出战的学生上台操作,或者由教师代操,全班围观投屏】 + +**战斗进行中(教师解说):** + +**师:** 第 1 回合,[角色A] 先手——攻击了 [数字] 点伤害。[角色B] 现在剩 HP [数字]。 + +**师:** [角色B] 反击……特技触发了![特技效果]。现在形势[分析]。 + +**师:** 大家注意这一回合——[角色A] 的 DEF 是 [数字],所以对方每次攻击被减了 [数字] 点。这就是 DEF 的价值。 + +**战斗结束后:** + +**师:** [赢方角色] 赢了![学生名] 晋级。 + +**师:** 分析一下——[赢方角色] 赢的原因是什么?是属性设计好,还是特技时机对,还是单纯运气? + +**生:** (预期:因为 HP 多扛住了 / 因为特技打了两次 / 因为 ATK 高秒杀了) + +**师:** 对。[具体分析赢的原因]。[输方角色] 输了——如果重来,你觉得属性怎么分会更好? + +**生(输方学生):** (预期:我应该把 DEF 加高一点 / 我应该多加 SPD 先手) + +**师:** 这个分析很好。记住这个想法,等会儿路演的时候说出来。 + +【继续下一场,同样流程】 + +**半决赛/决赛前:** + +**师:** 现在进入[半决赛/决赛]![角色A] 和 [角色B],这两位已经赢过了[X]场。来介绍一下他们的战绩—— + +**师:** [角色A] 在上一场用[什么策略]赢了[谁]。[角色B] 在上一场用[什么方式]赢了[谁]。这场对阵,你们觉得—— + +**决赛结束后:** + +**师:** 恭喜[冠军角色]![学生名] 拿到今天锦标赛冠军! + +**师:** 但我要说一件事——今天冠军不是「最聪明的人」,而是「今天这个对阵顺序下最幸运的人」。如果换一个对阵顺序,冠军可能完全不同。游戏平衡性比绝对强度更重要——这是游戏设计师最核心的命题。 + +**进度同步 (Checkpoint): (2分钟)** + +**师:** 锦标赛结束了。在进入路演之前,我问大家一个问题:你们觉得,今天的冠军角色「设计得最好」吗? + +【诊断点:学生是否理解「赢得比赛」和「设计得好」是两件事,随机因素(对阵顺序)影响结果】【理解层】 + +**【分支A】若学生说「冠军设计最好」:** +**师:** 如果把今天的对阵顺序换一下,让冠军第一场就对上另一个强角色,他还会赢吗?不一定。所以赢比赛不等于设计最好——游戏平衡设计是一门科学,不是谁 ATK 最高谁就赢。 + +**【分支B】若学生说「运气成分很大」:** +**师:** 对,你说到一个重点。同样属性的两个角色打十场,赢的次数可能各五场。所以好的游戏设计要让不同风格的角色都有赢的可能,而不是让一种打法通吃所有。这叫「策略多样性」。 + +--- + +**第三幕:反思 (Contemplate) — 15分钟** 🤔 + +*本幕目标:每人完成3分钟路演,训练「说设计决策」而非「说功能列表」* + +**【环节】班级路演 (15分钟)** + +**师:** 现在进入路演环节。每个人 3 分钟,包括展示和提问。路演有四段固定内容: + +【投屏展示路演结构】 + +``` +第1段(30秒):展示角色 + 说:「我的角色叫 XX,是一个 XX 型,属性分配是……」 + +第2段(30秒):设计意图 + 说:「我选这个打法是因为……我觉得用 XX 特技可以克制……」 + +第3段(60秒):精彩瞬间 + 说:「最让我印象深刻的是和 XX 的对战,那一场……」 + +第4段(60秒):设计复盘 + 说:「如果重来,我会把 XX 调低一点,把 XX 调高……因为我发现……」 +``` + +**师:** 注意——路演不是说「我的角色有什么功能」。路演是说「我为什么这样设计」。这两件事差很多。我来举个例子: + +错误示范:「我的角色叫章鱼怪,它有 HP 80、ATK 15、DEF 5、SPD 8,特技是连击。」 +正确示范:「我叫它章鱼怪,我把 HP 设高是因为我想让它能扛住对方的连续攻击,用消耗战的方式赢。特技选连击是因为连击在对方 HP 低的时候效果最好,可以一次清掉。」 + +看到区别了吗?第一个说了什么,第二个说了为什么。 + +**师:** 好,谁先来? + +【6-8人小班建议全员路演;学生逐一路演,教师计时,到 3 分钟给提示】 + +**路演示例(教师可以第一个先做一遍示范,30秒内):** + +**师:** 我先给大家示范一遍格式。如果我设计了一个角色,我会这样路演—— + +「我的角色叫石甲龟,是一个防御型角色。HP 设了 100,DEF 设了 20,ATK 只有 5——我知道这样攻击力很弱,但我的想法是:用超高的防御力把对方的输出全部挡掉,靠持久战赢。特技我选了「反弹」——把对方一部分伤害反还给它。最让我印象深刻的是和高 ATK 角色对战,那一场打了整整 5 回合,对方 ATK 30 打在我身上每次只剩 10 点,我靠反弹慢慢把它磨死了。如果重来,我会把 SPD 调高一点,因为我发现先手权在某些情况下比防御更重要——有几场因为后手被秒杀了。」 + +看到了吗?每一个数字背后都有理由,每一个设计决策都可以说出来。好,现在轮到大家了。谁第一个? + +【学生逐一路演,教师计时,到 3 分钟给提示】 + +**每位学生路演后,教师引导互评:** + +**师:** [学生名] 路演完了。谁来给一个「一个优点 + 一个改进建议」? + +**生:** (预期:优点是……建议是……) + +**师:** 好。[学生名],你对这个建议怎么看?如果你的下一个版本按照这个建议改,你觉得会怎样? + +**生:** (预期:可能会更好 / 但是我担心……/ 我觉得还有另一个问题是……) + +**师:** 好,这就是设计思维——不是「改了一定变好」,而是「改了会带来什么新的权衡」。 + +**学生路演引导词(当学生卡壳时使用):** + +若学生在「设计意图」卡壳: +**师:** 你当时为什么把 HP 设成这个数字?是随机的还是有理由的? + +若学生在「精彩瞬间」卡壳: +**师:** 锦标赛里你最紧张的是哪一场?或者最意外的是哪一场?就说那一场。 + +若学生在「设计复盘」卡壳: +**师:** 你输的那场,对方哪个属性让你最难受?如果把你的属性分配改一下,能不能针对性地克制它? + +若学生整体准备不足: +**师:** 好,我给你 30 秒想一下。有一个问题你一定能回答:你和谁打的那一场,最让你印象深刻?说那一场就行。 + +**路演结束后的整体反思问题:** + +**师:** 好,大家都路演完了。我有一个问题——你们今天路演,最难说的是哪个部分?是「展示角色」还是「设计意图」还是「设计复盘」? +【诊断点:学生是否认为「说为什么」比「说是什么」更难,反映其对设计思维的认知层级】【理解层】 + +**【分支A】若学生说「最难的是设计复盘」:** +**师:** 对,复盘最难。因为复盘要求你承认「我的设计有问题」,然后还要找到具体是什么问题,还要想出怎么改。这个能力叫「反事实推理」——世界上所有的工程师和设计师都在练这个能力。你们今天已经开始练了。 + +**【分支B】若学生说「最难的是设计意图,因为我当时随便分的」:** +**师:** 没关系,随便分也有设计意图——「我不知道怎么分,所以平均分」本身就是一个决策。下一次你设计角色的时候,在分属性之前先写一句话:「我要做一个什么风格的角色,要克制什么打法」,有了这句话,属性分配就有了方向。 + +--- + +**第四幕:延续 (Continue) — 5分钟** 🚀 + +**【环节】四课主线总结 (3分钟)** + +**师:** 最后一个问题——锦标赛结束后,你们觉得游戏平不平衡?有没有某种打法「必赢」? + +**生:** (预期:有一点不平衡 / 感觉高 ATK 的更容易赢 / 感觉差不多) + +**师:** 游戏平衡是永远做不到「完美」的——哪怕是王者荣耀这种级别的游戏,每个版本也要出「平衡性调整」。你们今天做的游戏也一样,会有某些打法偏强。这是正常的。重要的是你们发现了这个问题,发现了就可以迭代。 + +好,进入总结。 + +**师:** 今天是涂鸦 PK 系列的最后一课。我们来回顾一下这四课做了什么—— + +【投屏展示四课主线总结】 + +``` +第8课:需求文档 → 画图工具 + 你用工程流程做了一个工具 + +第9课:需求文档 → 战斗系统 + 测试验证 + 你用数据验证了你设计的规则 + +第10课:增量需求 → 动画 + 音效 + 你用「感觉描述」扩展了系统 + +第11课:数据驱动 → 角色系统 + 锦标赛 + 你让系统可以无限扩展 +``` + +**师:** 但这四课里,你们学到的不是游戏。 + +你们学到的是——如何把一个想法,变成可以被验证、可以被扩展、可以被迭代的系统。 + +需求文档让你在动手之前想清楚。 +测试验证让你知道自己做的对不对。 +增量需求让你在已有基础上扩展,而不是推倒重来。 +数据驱动让你的系统可以无限成长,不被代码本身限制。 + +**师:** 这四件事,就是工程师做事的方式。你们今天用这个方式,做出了一个可以全班对战的游戏。 + +**【环节】下节预告 + 5分钟挑战 (2分钟)** + +**师:** 下节课,我们开始新的项目。你们在前面学到的这些能力——需求文档、增量迭代、数据驱动——会在接下来的项目里继续用到。 + +**师:** 本周 5 分钟 AI 挑战——给你的角色设计一个「2.0 版本」:改变属性分配,写下这次你要克制哪种打法,以及你的设计理由。不需要改代码,只需要改 json 文件里的属性数值,然后写一段话说清楚「我为什么这样改」。下节课分享。 + +--- + +### 5. AI助教使用指南 + +**窗口A——增量需求文档模板(教师投屏用):** + +``` +增量需求文档 v1.0 +项目:涂鸦PK战斗游戏 +新增功能:roles 角色选择系统 + +1. 从 roles/ 文件夹读取所有 *.json 文件 + - 每个 json 包含字段:name, hp, atk, def, spd, skill + - 如果文件夹为空或读取失败,显示提示信息「暂无角色,请检查 roles/ 文件夹」 + +2. 战斗开始前显示角色选择界面 + - 左侧:玩家角色列表(从 json 文件读取,动态生成) + - 右侧:AI 对手角色列表(同上) + - 每个角色显示名字 + HP/ATK/DEF/SPD 数值 + - 两侧可选同一个角色(允许镜像对战) + +3. 选择确认 + - 点击「开始战斗」按钮进入战斗 + - 战斗时加载对应的同名 .png 文件作为角色图片 + - 如果 .png 不存在,使用默认占位图 + +4. 不修改原战斗逻辑 + - 只新增角色选择这一层 + - 原来的战斗循环、伤害计算、特技逻辑保持不动 +``` + +**窗口C——保底执行提示词(学生直接使用):** + +``` +我已有一个 Phaser.js 战斗游戏,两个角色数据现在是硬编码的。 +现在我要加角色选择系统: + +1. 从 roles/ 文件夹读取所有 *.json 文件 + (每个文件包含 name/hp/atk/def/spd/skill 字段) +2. 显示角色选择界面:左边选玩家角色(列表),右边选 AI 角色(列表) +3. 每个角色显示名字和属性数值 +4. 选好后点「开始战斗」进入游戏,加载对应的同名 .png 作为角色图片 +5. 如果 .png 不存在,显示默认占位图 + +只输出新增/修改的代码部分,不要重写整个游戏。 +在代码里加注释说明每段新增代码的作用。 +``` + +**路演辅助提示词(给路演准备不足的学生):** + +``` +我的游戏角色数据是: +名字:XX +HP=[数字], ATK=[数字], DEF=[数字], SPD=[数字] +特技:[特技描述] + +在班级锦标赛中,我赢了[X]场,输了[X]场。 + +帮我用 3 个问题引导我做「设计复盘」——只问问题,不给答案。 +``` + +**进阶提示词(给完成基础任务、想进一步扩展的学生):** + +``` +我的角色选择系统已经完成了。现在我想加一个「角色详情」功能: +点击角色卡片时,弹出一个详情面板,显示: +1. 角色大图(放大版的 .png) +2. 属性条形图(HP/ATK/DEF/SPD 各用一条进度条表示,满分100) +3. 特技说明(从 json 里读取 skill 字段,格式化显示) +4. 「选择此角色」按钮 + +只输出新增代码,不改变现有的选择界面逻辑。 +``` + +--- + +### 6. 教师指南 + +**本课技术备注:** + +**关于浏览器无法直接读取本地文件夹的问题:** + +浏览器出于安全原因,无法用 `fetch('roles/角色.json')` 直接读取本地文件夹(会报 CORS 错误)。解决方案: +- 方案A(推荐):用 Trae IDE 的本地服务器功能启动项目(Trae 内置 Live Server,自动解决 CORS 问题) +- 方案B:让 AI 生成一个简单的 Node.js 本地服务器(`node server.js`),在本地 8080 端口提供文件服务 +- 方案C(备用):改为手动列出所有角色文件名,用 `Promise.all` 批量 fetch(避免了「自动扫描文件夹」的需求,但需要每次加新角色时在列表里加一个文件名) + +**备课时务必先在 Trae 里跑通,确认本地服务器正常。** + +**关于 Phaser.js 动态加载 Spritesheet:** + +Phaser 的 `this.load.spritesheet()` 需要在 `preload()` 阶段调用,不能在游戏运行时动态加载。如果 AI 生成的代码在 `create()` 里加载图片,会报错。解决方案:提示词加上「角色图片需要在 preload 阶段加载,请用 scene.restart() 重新启动场景来实现动态切换角色」。 + +**锦标赛组织 FAQ:** + +| 问题 | 应对 | +|------|------| +| roles 系统没做好,无法进行锦标赛 | 退回到手动改代码换角色,每场由教师提前改好对应角色的数据,坚持锦标赛进行 | +| 某位学生的角色文件损坏/无法加载 | 临时用教师提前准备的备用角色文件替换 | +| 6人以下小班(如只有4人)| 改为双败赛制(输两场才淘汰),增加对战场次 | +| 学生对结果强烈不满(认为Bug导致输了)| 认可情绪,说「你可以在5分钟挑战里设计2.0版本,下次来复仇」 | +| 路演时学生只说功能不说设计意图 | 用引导词打断:「等等,你刚才说了做了什么。现在告诉我,你为什么这样做?」 | + +**路演控时技巧:** +- 用手机计时,3分钟倒计时给学生看 +- 到2分30秒时轻声提醒:「还有30秒」 +- 如果学生还没到「设计复盘」环节,可以跳过「精彩瞬间」直接问:「如果重来你会怎么改?」 +- 互评限时 30 秒:「一个优点,一个建议,简短说」 +- 路演顺序建议:冠军最后一个路演,制造节奏感;输了第一场的同学第一个路演,减少等待焦虑 + +**关于「数据驱动设计」的深度追问(给理解快的学生):** + +如果有学生问「为什么要把数据和代码分开,直接写在代码里不是更方便吗?」,这是一个很好的问题,可以这样回答: + +「当你只有 2 个角色的时候,写死在代码里确实更方便。但当你有 100 个角色的时候呢?当别人也要给你的游戏加角色的时候呢——你要让他改你的代码吗?数据和代码分离,是为了让扩展和维护变得容易。这个原则不只在游戏里,几乎所有的软件系统都在用——数据库、配置文件、皮肤系统,都是同一个思路。」 + +**锦标赛后的班级文化建立:** + +锦标赛不是为了分出高下,是为了制造「真实战斗测试」的场景。建议在锦标赛结束后强调: +- 不设「最强角色」称号,只设「冠军」(今日锦标赛冠军,不代表绝对最强) +- 鼓励「最有创意设计」:给属性分配最特别、最有设计理由的角色点名表扬 +- 鼓励「最佳复盘」:在路演中,给复盘最到位、最有具体改进方案的同学点名表扬 + +**课堂风险预案:** +- 如果 Trae 本地服务器启动失败:切换到 Kimi 直接生成 HTML,不依赖本地服务器 +- 如果锦标赛时间不够(roles 系统做得慢):缩减锦标赛场次,只打半决赛 + 决赛(两场) +- 如果进度差异过大(有学生roles系统5分钟做完,有学生20分钟还没做好):先完成的学生做进阶任务(角色详情弹窗),帮进度慢的学生看报错 + +--- + +### 7. 5分钟日常AI挑战 + +**本周挑战:** 给你的角色设计「2.0 版本」 + +**挑战说明:** +打开你角色的 json 文件,修改属性数值,设计一个新版本。要求写一段话(3-5句)说清楚三件事: +1. 你改了哪些属性,改成了什么数字 +2. 这次你想克制哪种打法(比如:克制高 ATK 爆发型 / 克制高 SPD 速攻型) +3. 你觉得这样改会带来什么新的弱点 + +不需要跑代码验证,只需要写出「设计意图」。 + +**下节课分享:** 下周课上选 2-3 位同学分享「我的 2.0 设计方案」,其他同学判断:这个改动真的能克制目标打法吗? + +--- + +### 8. 拓展任务 + +**拓展一(推荐):角色详情卡** + +在角色选择界面里,给每个角色加一个「详情」功能:点击角色名字时,弹出一个小面板,用条形图显示 HP/ATK/DEF/SPD 的比例关系(满分100的进度条),让玩家在选角色前能直观对比属性强弱。 + +提示:条形图可以用 HTML 的 `` 标签,或者用 CSS 的 `width` 百分比实现。 + +**拓展二(挑战):战斗回放摘要** + +每场战斗结束后,自动生成一段「战斗日志」:记录关键回合(如特技触发、HP 归零)的文字摘要。格式参考: + +``` +第3回合:章鱼怪特技「连击」触发,对火焰鸟造成双倍伤害 28 点 +第5回合:火焰鸟 HP 归零,章鱼怪以 HP 34 获胜 +``` + +这个功能需要在战斗循环里加「事件记录」逻辑,是真正的功能扩展挑战。 diff --git a/3-lessons/AICODE-06/demo-pk/demo-1-draw-tool.html b/3-lessons/AICODE-06/demo-pk/demo-1-draw-tool.html new file mode 100644 index 0000000..06e76fa --- /dev/null +++ b/3-lessons/AICODE-06/demo-pk/demo-1-draw-tool.html @@ -0,0 +1,422 @@ + + + + +涂鸦角色画图工具 + + + + +

🎨 涂鸦角色画图工具

+ +
+
+
+
帧1 · 待机
+
帧2 · 攻击
+
+ +
+ + + + +
+
+
画布 64×64 像素 · 8倍放大显示
+
+ +
+
+

动画预览

+ + +
+ +
+

操作

+ + +
+ +
+

导出

+ + +
+ +
+

使用说明

+
+ 1. 在帧1画待机姿势
+ 2. 点「复制帧1→帧2」
+ 3. 切到帧2修改成攻击姿势
+ 4. 点▶预览动画效果
+ 5. 导出 Spritesheet 用于游戏 +
+
+
+
+ + + + diff --git a/3-lessons/AICODE-06/demo-pk/demo-2-pk-battle.html b/3-lessons/AICODE-06/demo-pk/demo-2-pk-battle.html new file mode 100644 index 0000000..2de9ede --- /dev/null +++ b/3-lessons/AICODE-06/demo-pk/demo-2-pk-battle.html @@ -0,0 +1,583 @@ + + + + +涂鸦PK · 对战演示 + + + + +
+ + + + +
+
+ + + + diff --git a/3-lessons/AICODE-06/demo-pk/demo-3-animation.html b/3-lessons/AICODE-06/demo-pk/demo-3-animation.html new file mode 100644 index 0000000..42ce5a4 --- /dev/null +++ b/3-lessons/AICODE-06/demo-pk/demo-3-animation.html @@ -0,0 +1,474 @@ + + + + +角色动画展示 + + + + +

🎬 角色动画展示

+ +
+ + + + +
+ + + +
+ + + + + + + + +
+ +
+ 点击按钮查看不同的动画效果。
+ 所有动画都用 Phaser Tween 实现,只需要一张图片,不需要多帧素材。
+ 可以导入你在画图工具里画的角色 PNG,看看它配上动画是什么效果。 +
+ + + +