# 第 1 关开发文档:1-1 左手基准键 ASDF 对应规划:`分关难度规划.md` → 第 1 章 · 基准键入门 → **1-1**。 本文只覆盖第 1 关的实现范围,作为后续关卡的模板。第 1 关同时要搭好练习页的通用骨架,后关复用,不重做。 --- ## 1. 目标 让完全新手在不看键盘的情况下,用正确指法打出左手四个基准键: | 键 | 手指 | |----|------| | `A` | 左手小指 | | `S` | 左手无名指 | | `D` | 左手中指 | | `F` | 左手食指 | 本关**不考速度**,只考正确率和指法习惯。 通关条件:**正确率 ≥ 90%**(无速度门槛)。 --- ## 2. 范围 ### 2.1 本关要做 - 关卡选择页中,1-1 默认解锁,可进入 - 练习页:待打文本、实时对错着色、键盘指法图、实时数据条 - 约 40 个目标键,字符集仅 `a s d f`(小写) - 击键判定、正确率、键/分、进度 - 结束结算:通过 / 未通过,可重打 - 通过后解锁 **1-2** - 记录本关历史最好正确率(本地存储) ### 2.2 本关不做 - 右手键 `j k l ;`、空格、大写、数字、符号 - 速度门槛、限时模式 - 中文拼音、单词、文章 - 热力图统计(可先预留数据结构,本关不展示) - 账号 / 云同步 --- ## 3. 页面与信息架构 建议单页 HTML,用视图切换,不必多文件路由。 ``` 启动 └─ 关卡选择(第 1 章四关列表) └─ 练习中(1-1) └─ 结算弹层 ├─ 再打一次 → 回到练习中(重新抽题) └─ 返回选关 → 关卡选择 ``` ### 3.1 关卡选择页(本关相关) | 元素 | 说明 | |------|------| | 章标题 | 第 1 章 · 基准键入门 | | 关卡卡片 1-1 | 标题「左手基准键 ASDF」;状态:已解锁 / 已通关 | | 关卡卡片 1-2~1-4 | 未通关 1-1 前置灰,不可点 | | 最佳成绩 | 若打过 1-1,显示历史最高正确率 | ### 3.2 练习页布局(自上而下) 1. **顶栏**:关卡名「1-1 左手基准键」、返回选关 2. **数据条**:进度 `已打/总数`、正确率、速度(键/分)、用时 3. **文本区**:一行待打字符,当前目标键放大/下划线,已打正确为绿、错误为红 4. **键盘区**:QWERTY 示意图,强制显示;当前目标键高亮;四指提示 5. **提示文案**:「食指放在 F,小指放在 A,不要看键盘」 结算用遮罩弹层盖在练习页上,不跳新页。 --- ## 4. 关卡配置 实现时用一份配置驱动,后关只改配置、少改逻辑。 ```js { id: "1-1", chapter: 1, title: "左手基准键 ASDF", charset: ["a", "s", "d", "f"], length: 40, allowSpace: false, caseSensitive: false, // 本关只产生小写;Shift+A 视为错误 passAccuracy: 0.90, passKpm: null, // 本关不卡速度 unlockNext: "1-2", showKeyboard: true, // 强制显示,不可关 generate: "random-from-charset" } ``` ### 4.1 题目生成规则 - 从 `charset` 均匀随机抽取 `length` 个字符,连成一串,例如:`asdfafsdasfd...` - **不要**出现空格、换行 - 建议约束:同一字符连续不超过 3 次(避免 `aaaa` 失去指法切换训练) - 每次进入或「再打一次」都重新生成,不固定题库 ### 4.2 允许输入 | 按键 | 行为 | |------|------| | `a` `s` `d` `f` | 有效击键,进入对错判定 | | 其他字母 / 数字 / 符号 | 记为一次错误击键,不前进光标(卡住当前目标,直到打对) | | `Shift` / `CapsLock` 产生的 `A` 等 | 视为错误(本关只认小写) | | `Backspace` | **忽略**,本关不允许改错(对标金山打字通初级指法:打错就记错,必须打对当前键才继续) | | `Enter` `Tab` `Esc` | 忽略,不计入对错 | | `Alt` `Meta` `Ctrl` 组合 | 忽略 | 采用「必须打对才前进」:错了标红提示,光标停在当前目标,直到按下正确键。 正确率分母按「总击键次数(含错键)」计算,而不是按「已完成字符数」。见第 6 节。 --- ## 5. 指法与键盘 UI ### 5.1 手指映射(本关只用左手) | 键 | 手指 | 建议高亮色 | |----|------|------------| | A | 小指 | 橙 | | S | 无名指 | 黄 | | D | 中指 | 绿 | | F | 食指 | 蓝 | 其余键绘制出来但呈禁用态(降低透明度),避免误导用户去打。 ### 5.2 键盘交互 - 当前目标键:描边 + 放大/脉冲 - 按下正确键:该键闪绿后熄灭,切到下一目标 - 按下错误键:目标键闪红,可加轻微震动(CSS) - 键盘图下方固定文案: 「左手:小指 A · 无名指 S · 中指 D · 食指 F」 ### 5.3 文本区表现 假设目标串为 `asdf`,用户先打对 `a` `s`,第三个该打 `d` 却打了 `f`: ``` [a] [s] [d] [f] 绿 绿 当前(红闪) 灰 ``` - 已正确:绿色 - 当前目标:深色底 + 下划线;若刚打错则红框 - 未打到:灰色 - 不把错误字符插入文本(文本始终是标准答案,只改颜色/状态) --- ## 6. 判定与统计 从**第一次有效击键**开始计时(`a/s/d/f` 或其他会记错的可见字符)。纯功能键不开始计时。 ### 6.1 字段 | 字段 | 定义 | |------|------| | `targetLength` | 40 | | `cursor` | 当前待打下标,0~40;到 40 结束 | | `correctHits` | 打对次数(每前进一格 +1,最大 40) | | `wrongHits` | 打错次数(每次错误按键 +1,可大于 40) | | `totalHits` | `correctHits + wrongHits` | | `elapsedMs` | 从首次有效击键到结束(或当前)的毫秒 | ### 6.2 公式 ``` 正确率 accuracy = correctHits / totalHits 进度 percent = cursor / targetLength 速度 kpm = correctHits / (elapsedMs / 60000) 用时 time = elapsedMs ``` 展示: - 正确率:百分数,保留 1 位小数,如 `92.5%` - 速度:整数「键/分」,未开始时显示 `--` - 进度:`12 / 40` + 进度条 - 用时:`mm:ss` ### 6.3 通关判定(结束时一次性算) ``` passed = accuracy >= 0.90 ``` 本关 `passKpm` 为空,不判断速度。 `totalHits` 为 0 时(理论上不会结束)正确率按 0。 ### 6.4 结束时机 `cursor === targetLength` 立即结束,弹出结算。不再接收击键。 --- ## 7. 结算 ### 7.1 展示 | 项 | 说明 | |----|------| | 结果标题 | 「通关」或「未通关」 | | 正确率 | 实际值,并标明门槛「≥ 90%」 | | 速度 | 键/分(仅展示,不影响通关) | | 用时 | mm:ss | | 击键 | 正确 / 错误 / 总计 | | 操作 | 「再打一次」「返回选关」 | 通关时额外一行:「已解锁 1-2 右手基准键」。 ### 7.2 进度写入 使用 `localStorage`,键名建议:`typing-progress-v1`。 ```js { unlocked: ["1-1", "1-2"], // 通关 1-1 后写入 1-2 records: { "1-1": { bestAccuracy: 0.95, bestKpm: 62, passed: true, lastPlayedAt: "2026-08-13T15:30:00+08:00" } } } ``` 规则: - 初始 `unlocked` 含 `1-1` - 通关才把 `unlockNext` 加入 `unlocked` - `bestAccuracy` / `bestKpm` 只升不降 - 未通关也写入 `lastPlayedAt` 和当前成绩,但不把 `passed` 从 true 改回 false - 重打失败不锁回 1-2 --- ## 8. 状态机 ``` idle 进入练习页,题目已生成,等待第一击 playing 已开始计时,接收击键 finished 40 键打完,弹出结算,忽略击键 ``` 转移: - `idle` → `playing`:第一次有效/错误可见击键 - `playing` → `finished`:`cursor` 达到 40 - `finished` → `idle`:点「再打一次」(新题、清零统计) - 任意 → 选关:点返回(练习中途返回不保存通关,可选择是否写入 lastPlayedAt;本关规定:**中途退出不记成绩**) --- ## 9. 技术约定 | 项 | 约定 | |----|------| | 形态 | 单文件或「HTML + CSS + JS」,先保证双击即可打开 | | 输入 | `window` 上 `keydown`;用 `event.key` 判定字符 | | 防干扰 | 练习中 `preventDefault` 掉会滚动/选中的键;不要用隐藏 `` 抢焦点(避免 IME) | | 本关 IME | 不需要中文输入;若系统处于中文输入法,提示「请切换到英文」 | | 样式 | 深色背景、大字号文本区,适合全屏练习 | | 兼容 | 现代桌面 Chrome / Edge / Safari;本关按物理键盘设计,不做触屏键盘 | ### 9.1 建议模块划分(同一文件内亦可) 1. `config`:关卡配置 2. `progress`:读写 localStorage 3. `generator`:按 charset 生成题目 4. `engine`:状态机、击键、统计 5. `keyboardView`:键盘高亮 6. `textView`:文本着色 7. `hud`:数据条 8. `resultModal`:结算 9. `stageSelect`:选关 第 1 关实现时就把 1~8 做成可复用,选关先只列第 1 章四关。 --- ## 10. 文案 | 位置 | 文案 | |------|------| | 选关卡片标题 | 1-1 左手基准键 | | 选关卡片副标 | 只打 A S D F,正确率 90% 即可通关 | | 练习顶栏 | 第 1 关 · 左手基准键 ASDF | | 指法提示 | 食指放 F,小指放 A。请看着屏幕,不要看键盘。 | | 通关 | 通关!基准键已经记住了。 | | 未通关 | 再练一次。先求正确,再求速度。 | | 输入法提示 | 请切换到英文输入法后再开始。 | --- ## 11. 验收标准 - [ ] 打开页面即可进入 1-1,无需登录 - [ ] 题目长度为 40,仅含 `a s d f`,无空格 - [ ] 同一字符连续不超过 3 次 - [ ] 打对前进一格,打错不前进并记一次错误 - [ ] Backspace 不影响进度与统计 - [ ] 正确率按 `正确 / (正确+错误)` 计算,≥ 90% 判定通关 - [ ] 无速度门槛;结算仍显示键/分 - [ ] 键盘图始终显示,当前键高亮,非 ASDF 键呈禁用态 - [ ] 通关后 1-2 可点;未通关 1-2 仍锁 - [ ] 刷新页面后解锁状态仍在 - [ ] 中途返回选关不记本局成绩 - [ ] 「再打一次」重新抽题并清零 --- ## 12. 测试用例 | 编号 | 操作 | 期望 | |------|------|------| | T1 | 40 次全对 | 正确率 100%,通关,解锁 1-2 | | T2 | 打对 36、打错 4(错键后补对) | 总击键 44,正确率 ≈ 81.8%,未通关 | | T3 | 打对 36、打错 4 之外再算:正确 36 / 总击键 40 | 注意:因打错不前进,40 个正确键必须打满;未通关局 `correctHits` 仍为 40,`wrongHits` > 0。例如错 5 次则正确率 = 40/45 ≈ 88.9%,未通关 | | T4 | 正确率刚好 90%(40 对 + 约 4.44 错不可整除) | 用 40 对 + 5 错 = 88.9% 未过;40 对 + 4 错 = 90.9% 通过。门槛按 `>= 0.90` | | T5 | 练习中按 Backspace、方向键 | 无效果 | | T6 | 打 `g` 或其他非 charset 键 | 错误 +1,光标不动 | | T7 | 通关后刷新 | 1-2 仍解锁 | | T8 | 通关后再打失败 | 1-2 保持解锁 | | T9 | 第一键前等待 | 速度显示 `--`,用时 00:00 | | T10 | 中途点返回 | 无结算、不改 best、不解锁 | **正确率要点(务必实现一致):** 本关结束时 `correctHits` 恒为 40。通关只取决于错了多少次: ``` accuracy = 40 / (40 + wrongHits) 90% 通关 ⇒ 40 / (40 + wrongHits) >= 0.90 ⇒ wrongHits <= 4 ``` 即:全程最多允许打错 4 次。 --- ## 13. 后续关卡复用说明 第 1 关落地后,1-2 只需改配置: | 项 | 1-1 | 1-2(预告,不在本文实现) | |----|-----|---------------------------| | charset | a s d f | j k l ; | | 手指 | 左手四指 | 右手四指 | | 通关 | 正确率 ≥ 90% | 同 1-1 | | 键盘禁用态 | 非 ASDF | 非 JKL; | 不要为 1-2 另写一套引擎。