# [特殊字符] 学习模拟器 — 鸿蒙ArkTS完整技术解析
应用定位:教育养成模拟类小应用
技术栈:HarmonyOS NEXT + ArkTS + Stage模型
源码行数:130行
核心亮点:知识积累系统、专注力机制、随机科目切换、考试评分体系
一、引言
学习模拟器是20个模拟器系列中第一个引入消耗型资源与产出型资源双轨系统的应用。它将学习抽象为两个核心资源:知识(产出)和专注力(消耗),以及一个考试(检验)机制。
从设计模式看,学习模拟器引入了几个重要概念:
- 双资源系统:知识(正向增长)和专注力(逆向消耗)
- 随机事件:每次学习随机切换科目
- 考试评价体系:基于积累知识计算考试成绩
- 暂停恢复:学习过程中的专注力恢复
- 多级评价:从不及格到满分的五级评价
二、需求分析
2.1 功能需求
| 需求ID | 功能 | 描述 |
|---|---|---|
| F1 | 知识积累 | 每次学习增加知识值 |
| F2 | 专注力消耗 | 学习中专注力递减 |
| F3 | 科目随机 | 6门科目随机切换 |
| F4 | 考试系统 | 基于知识值计算得分 |
| F5 | 五级评价 | 不及格→及格→良好→优秀→满分 |
| F6 | 专注力恢复 | 暂停时恢复专注力 |
| F7 | 学习统计 | 学习次数统计 |
2.2 状态模型
┌──────────────────────────────────────┐
│ 学习模拟器状态树 │
├──────────────────────────────────────┤
│ knowledge: number // 知识值 0+ │
│ focus: number // 专注力 0-100│
│ studyCount: number // 学习次数 │
│ isStudying: boolean // 学习中 │
│ message: string // 提示消息 │
│ subjectIndex: number // 当前科目 │
│ intervalId: number // 定时器ID │
│ examScore: number // 考试得分 │
└──────────────────────────────────────┘
三、双资源系统设计
3.1 资源模型对比
| 资源类型 | 变量名 | 初始值 | 上限 | 增长方式 | 消耗方式 |
|---|---|---|---|---|---|
| 产出型 | knowledge | 0 | 无上限 | 学习+1 | 无 |
| 消耗型 | focus | 100 | 100 | 休息+30 | 学习-5 |
知识是无限增长型资源——学得越多,知识越高,永远不会减少。
专注力是有限消耗型资源——从100开始,持续消耗,需要通过休息恢复。
3.2 双资源交互逻辑
// 学习中的状态更新
this.knowledge++;
this.focus = Math.max(0, this.focus - 5);
// 专注力耗尽时
if (this.focus <= 0) {
this.stopStudy();
this.message = '专注力耗尽了,休息一下吧😵';
}
// 休息恢复
this.focus = Math.min(100, this.focus + 30);
这种设计形成了一个循环:学习→消耗专注力→休息→恢复专注力→继续学习。这是游戏设计中经典的"行动-消耗-恢复"模式。
四、随机科目切换
private subjects: string[] = ['📐 数学', '📖 语文', '🔬 科学', '🌍 地理', '🎵 音乐', '🎨 美术'];
4.1 随机切换实现
this.subjectIndex = Math.floor(Math.random() * this.subjects.length);
每次学习后随机切换科目,让模拟更有趣。6门科目包括文科、理科、艺术,覆盖了主要学习领域。
4.2 科目频率统计
虽然没有显式统计,但可以添加每个科目的学习次数统计:
@State subjectStats: Map<string, number> = new Map();
// 每次学习后记录
let subject = this.subjects[this.subjectIndex];
this.subjectStats.set(subject, (this.subjectStats.get(subject) || 0) + 1);
五、考试评分系统
5.1 评分计算公式
let score = Math.min(100, Math.floor(this.knowledge * 1.2 + Math.random() * 10));
公式解析:
- 基础分:
knowledge × 1.2— 依赖积累的知识量 - 随机加分:
Math.random() * 10— 加入运气成分(0-10分的浮动) - 上限保护:
Math.min(100, ...)— 满分100
5.2 五级评价体系
private grades: string[] = ['❌ 不及格', '⚠️ 及格', '👍 良好', '🌟 优秀', '🏆 满分'];
let gradeIdx = score >= 95 ? 4 : score >= 80 ? 3 : score >= 60 ? 2 : score >= 40 ? 1 : 0;
| 分数范围 | 评价 | 含义 |
|---|---|---|
| 0-39 | ❌ 不及格 | 知识太少 |
| 40-59 | ⚠️ 及格 | 勉强通过 |
| 60-79 | 👍 良好 | 掌握一般 |
| 80-94 | 🌟 优秀 | 学得不错 |
| 95-100 | 🏆 满分 | 学霸级 |
5.3 考试条件
if (this.knowledge < 10) {
this.message = '知识太少,没法考试!先学习吧📖';
return;
}
这是学习模拟器的一个关键设计——考试需要前置条件。与吃饭/喝水模拟器中"随时可以做任何操作"不同,学习模拟器引入了一个"门槛"概念:知识不够时不能考试。
六、UI交互设计
6.1 科目展示
Text(this.subjects[this.subjectIndex])
.fontSize(32)
.margin(10)
科目展示在界面中央,大号字体显示,使用户一目了然地看到当前学习科目。
6.2 统计数据展示
Row() {
Text('📊 知识: ' + this.knowledge)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.margin({ right: 20 })
Text('🔋 专注: ' + this.focus + '%')
.fontSize(16)
.fontWeight(FontWeight.Bold)
}
使用 Row 并排显示两个核心数据,加粗强调。margin({ right: 20 }) 在两者之间产生间距。
6.3 考试成绩历史
if (this.examScore > 0) {
Text('最近考试: ' + this.examScore + ' 分')
.fontSize(14)
.fontColor('#3F51B5')
.margin({ top: 15 })
}
条件渲染——只在有考试成绩时才显示。这与吃饭模拟器的统计信息如出一辙。
七、ArkTS中的MathAPI
本应用密集使用了 Math 对象的一系列方法:
| 方法 | 用途 | 示例 |
|---|---|---|
Math.random() |
生成0-1随机数 | Math.random() * 10 → 0-10 |
Math.floor() |
向下取整 | Math.floor(3.7) → 3 |
Math.min() |
取最小值 | Math.min(100, score) |
Math.max() |
取最大值 | Math.max(0, focus) |
7.1 Math.floor 和 Math.random 的组合
Math.floor(Math.random() * N) 是一种经典的模式,用于生成 [0, N-1] 范围内的随机整数。
// 随机选择一个科目
this.subjectIndex = Math.floor(Math.random() * 6); // 0-5
// 随机加分
Math.floor(Math.random() * 10); // 0-9
7.2 使用场景总结
| 表达式 | 范围 | 用途 |
|---|---|---|
Math.random() |
[0, 1) | 基础概率 |
Math.floor(Math.random() * N) |
[0, N-1] | 随机索引 |
Math.random() * M |
[0, M) | 随机数值 |
min + Math.random() * (max - min) |
[min, max) | 区间随机 |
八、ArkTS条件渲染最佳实践
本应用的三个条件渲染场景展示了不同用法:
8.1 基于前置条件的渲染
if (this.examScore > 0) {
// 显示考试结果
}
用途:只在有有效数据时显示。
8.2 基于状态切换的互斥渲染
if (!this.isStudying) {
// 显示"开始学习"
} else {
// 显示"休息一下"
}
用途:两个不同状态的UI切换。
8.3 基于数值阈值的渲染
学习模拟器虽然没有使用,但可以扩展:
if (this.knowledge >= 50) {
Text('🎓 学霸徽章已解锁!')
}
用途:达到特定条件时触发特殊显示。
九、学习与考试的平衡设计
9.1 学习-考试循环
学习(消耗专注力→增长知识)→ 专注力不足 → 休息(恢复专注力)
↓
考试(基于知识计算得分) ←──────────────── 知识积累到10+
这是一个典型的"积累-检验"循环。知识是销量(quantity),考试是质量(quality)——数量积累到一定程度后才能接受质量检验。
9.2 最优策略分析
假设用户每次都按最优策略操作:
-
阶段1(知识0-9):只能学习,不能考试
- 每学习1次消耗5专注力,增加1知识
- 从0到9需要学习10次,消耗50专注力
- 至少需要休息2次(恢复60专注力)
-
阶段2(知识10+):可以选择考试
- 最佳考试时机:知识接近满分前
- 如果知识=70,考试分 ≈ 70×1.2 + 5(平均随机) = 89分(优秀)
十、扩展思路
10.1 多科目专精
可以为每个科目单独记录知识值,实现分科学习:
@State subjectKnowledge: number[] = [0, 0, 0, 0, 0, 0];
考试时可以选择科目,考对应科目的知识。
10.2 技能树
引入技能树概念——每门科目达到一定知识后解锁新的学习内容:
if (this.subjectKnowledge[0] >= 10) {
// 解锁高等数学
}
10.3 学习时长统计
使用 AppStorage 持久化每日学习时长:
import { AppStorage } from '@kit.ArkUI';
// 保存
AppStorage.set('total_study_time', totalMinutes);
// 读取
let saved = AppStorage.get<number>('total_study_time');
10.4 专注力恢复的多种方式
除了休息,可以增加不同效率的恢复方式:
| 方式 | 恢复量 | 备注 |
|---|---|---|
| 小休息 | +20 | 快速但恢复少 |
| 午睡 | +50 | 需要更多时间 |
| 运动 | +30 | 额外增加知识 |
| 听音乐 | +15 | 简单快捷 |
十一、总结
学习模拟器展示了ArkTS在"双资源系统"场景下的开发模式:
- 双轨状态管理:产出型资源(knowledge)和消耗型资源(focus)的并行管理
- 门槛机制:考试需要知识≥10的前置条件
- 多元评价:五级考试评分体系
- 随机化交互:每次学习切换不同科目
- Math API密集使用:random、floor、min、max的组合应用
这种"学→考→评"的机制在设计教育类、测评类应用时非常有用。
更多推荐




所有评论(0)