# [特殊字符] 睡觉模拟器 — 鸿蒙ArkTS完整技术解析
应用定位生活方式模拟类小应用技术栈HarmonyOS NEXT ArkTS Stage模型源码行数138行核心亮点有限状态机、阶段化Progress、警惕/深度/梦乡三级睡眠模型一、引言睡觉模拟器是20个模拟器系列中第一个采用**有限状态机FSM**设计模式的应用。它模拟了从清醒→犯困→浅睡→深睡→美梦的完整睡眠周期每个阶段都有不同的UI表现和数值变化规则。为什么睡觉模拟器比前面的应用更复杂对比项吃饭/喝水模拟器跑步模拟器睡觉模拟器状态模式简单数值增减持续递减定时器多阶段状态机状态数2-3个2个(跑/停)5个阶段阶段切换自动手动手动自动(基于时间)副作用无卡路里计算精力恢复二、需求分析2.1 功能需求需求ID功能描述F1睡眠计时记录已睡小时数F2精力系统睡眠中精力逐渐恢复F3多阶段睡眠清醒→犯困→浅睡→深睡→美梦F4阶段图标每个阶段显示不同的emojiF5闹钟功能设置闹钟在特定时间叫醒F6咖啡提神喝咖啡跳过睡眠阶段直接清醒F7自然醒睡够8小时自动唤醒F8起床操作手动起床2.2 有限状态机设计-------- | 清醒 | --------- -------- | | | 犯困中 | | | v | -------- | ----| 犯困 | | | -------- | | | | | v | | -------- -------- | | 浅睡 | | 咖啡提神 | | -------- -------- | | | | v | | -------- | | | 深睡 | | | -------- | | | | | v | | -------- | | | 美梦 | | | -------- | | | | --------- | v -------- | 清醒 | --------三、状态机实现3.1 状态定义private stages: string[] [ 清醒, 犯困, 浅睡, 深睡, 美梦]; State sleepStage: number 0; // 0:清醒 1:犯困 2:浅睡 3:深睡 4:美梦状态用number表示从0到4共5个阶段。使用数组索引而不是枚举值简化了状态转换逻辑。3.2 状态转换逻辑this.sleepStage Math.min(4, this.sleepStage (Math.random() 0.6 ? 1 : 0));这行代码包含了状态机的核心转换逻辑递进式转换每次只增加一个阶段从浅睡→深睡不能从浅睡直接到美梦概率性转换Math.random() 0.6意味着每次只有40%的概率进入下一阶段上限保护Math.min(4, ...)防止超过美梦阶段概率性转换的设计目的是模拟真实睡眠——不是到了某个时间点就立刻进入深睡而是一个渐进的、不固定的过程。3.3 阶段转换的时间分布假设每2秒interval时间触发一次阶段检查从清醒(0)到美梦(4)需要约 4/0.4 10 次检查 ≈ 20秒但实际上中间可能卡在某个阶段很久运气不好一直随机数 0.6这种设计让每次睡觉的体验都有所不同增加了模拟的真实感。四、精力系统的设计4.1 精力恢复模型this.energy Math.min(100, this.energy 8);每2秒恢复8点精力。从初始值50恢复到100需要(100-50)/8 × 2秒 12.5秒。加上从清醒到入睡的转换时间大约需要30秒才能完全恢复——这是一个合理的等待时间。4.2 精力与睡眠阶段的对比时间线00s 10s 20s 30s 40s 阶段 清醒 → 犯困 → 浅睡 → 深睡 → 美梦 精力 50 70 82 94 100精力恢复和睡眠阶段是并行但不同步的——阶段取决于随机概率精力取决于固定增量。这使两个状态既有联系又相互独立增加了模拟的复杂度。4.3 8小时自然醒if (this.sleepTime 8 !this.alarmSet) { this.message 自然醒睡得真好☀️; this.wakeUp(); }模拟了8小时健康睡眠的概念。当sleepTime 8且没有设置闹钟时自动唤醒。五、闹钟系统if (!this.alarmSet) { Button( 定闹钟) .onClick(() { this.alarmSet true; this.message 闹钟已设定会叫醒你的⏰; }) .backgroundColor(#F44336) }闹钟系统实际上是一个标记位flag——alarmSet: boolean。在当前的简化实现中它只是一个显示状态。完整的闹钟系统应该允许用户选择唤醒时间在指定时间触发通知使用鸿蒙的AlarmManager能力六、咖啡提神机制Button(☕ 喝咖啡提神) .onClick(() { if (this.energy 100) { this.message 已经精神满满啦☀️; return; } this.energy Math.min(100, this.energy 20); this.sleepStage 0; this.message 喝了咖啡精神多了☕; }) .backgroundColor(#795548)咖啡的作用恢复精力energy 20重置睡眠阶段sleepStage 0回到清醒这是一个反向状态转换——通常睡觉是 stage 从0→4而咖啡是从当前阶段→0。它打破了状态机的单向流动提供了一个跳出循环的选项。七、UI布局详解7.1 阶段指示Text(状态: this.stages[this.sleepStage]) .fontSize(16) .fontColor(#5C6BC0) .margin({ bottom: 5 })将数值状态sleepStage映射为人类可读的文字描述这是一种状态→展示的解耦模式。7.2 睡眠中/非睡眠中的UI切换if (!this.isSleeping) { // 显示上床睡觉和喝咖啡按钮 } else { // 显示起床和定闹钟按钮 }这与跑步模拟器的开始/暂停按钮切换类似但这里切换的是两组不同的按钮而非单个按钮的文案切换。八、完整的生命周期管理8.1 页面显示时的自动恢复.onPageShow(() { // 页面显示时如果有未完成的睡眠应该继续 })尽管当前版本没有显式使用这个生命周期钩子但onPageShow是ArkTS页面开发中非常重要的API——它会在页面每次显示时触发不仅仅是首次创建适用于恢复定时器如果页面被隐藏过刷新数据从后台返回时检查状态一致性8.2 定时器清理stopSleep() { this.isSleeping false; if (this.intervalId ! -1) { clearInterval(this.intervalId); this.intervalId -1; } }与跑步模拟器相同的清理模式——先清定时器后重置ID。九、状态机设计的通用模式本应用的状态机模式可以抽象为一个通用模板// 1. 定义阶段名称 private stages: string[] [S0, S1, S2, ...]; // 2. 定义当前阶段的索引 State currentStage: number 0; // 3. 更新阶段递进式 advanceStage() { this.currentStage Math.min( this.stages.length - 1, this.currentStage (condition ? 1 : 0) ); } // 4. 重置阶段 resetStage() { this.currentStage 0; } // 5. 强制跳转 jumpToStage(target: number) { this.currentStage target; }这个模板适用于任何需要阶段递进的场景游戏关卡、烹饪流程、安装向导、阅读进度等。十、边界条件与异常处理场景守卫条件处理方式已满精力喝咖啡energy 100提示已精神满满睡眠中喝咖啡未加守卫可直接在睡眠中喝咖啡醒过来未睡够就起床无守卫允许但精力恢复较少重置时正在睡眠未加守卫直接停止睡眠并清空状态多次点击上床isSleeping条件渲染按钮不显示无法重复点击十一、扩展思路11.1 睡眠质量评分根据深睡时间占比、总睡眠时间计算睡眠质量getQuality(): string { let deepRatio this.deepSleepTime / this.sleepTime; if (deepRatio 0.4) return 优质睡眠; if (deepRatio 0.25) return 良好睡眠; return 需要改善; }11.2 梦境记录在美梦阶段随机展示不同的梦境描述private dreams: string[] [ 在彩虹上奔跑, 在花丛中飞舞, 飞向太空, ️ 在海岛上度假 ];11.3 使用鸿蒙后台任务真正的睡眠计时应该支持后台运行——即使用户关闭了应用也要计时。这需要使用鸿蒙的BackgroundTaskManagerimport { backgroundTaskManager } from kit.BackgroundTaskKit;11.4 睡眠周期闹钟在用户处于浅睡阶段时唤醒避免在深睡阶段被叫醒导致起床困难smartWakeUp() { if (this.sleepStage 2) { // 浅睡阶段 this.wakeUp(); } }十二、总结睡觉模拟器是系列中第一个采用**有限状态机FSM**的应用也是第一个拥有5个可递进阶段的复杂状态模型。它教会了我们状态机的ArkTS实现用数字索引和数组映射管理多阶段状态概率性状态转换通过随机数控制转换频率增加模拟真实感并行状态更新睡眠阶段和精力恢复并行推进相互独立反向状态转换咖啡提神机制打破单向流动生命周期集成定时器与页面生命周期的绑定睡觉模拟器为后续更复杂的模拟器如养花模拟器、养猫模拟器的多维度状态管理打下了基础。