【OpenHarmony/HarmonyOs 】化学学习软件成就系统设计实践:让学习 App 更有持续使用动力 【OpenHarmony/HarmonyOs 】成就系统设计实践让学习 App 更有持续使用动力学习类 App 很容易遇到一个问题用户第一次打开觉得内容很多但过几天就忘了继续用。为了解决这个问题我在「化学视界」中加入了成就系统用访问天数、学习行为、收藏、答题等数据给用户持续反馈。一、为什么学习 App 需要成就系统成就系统不是游戏专属。对于学习工具来说它可以发挥三个作用给用户正反馈让学习过程更有成就感。记录长期行为比如连续学习天数。引导用户探索更多功能比如查看元素、阅读知识、完成挑战。在我的项目中成就不是为了制造焦虑而是让用户看到自己一点点进步。二、成就系统的整体结构项目中成就相关文件主要有AchievementData.ts成就配置数据。Achievement.ts成就模型。AchievementManager.ts成就管理器。Achievement.ets成就展示页面。Statistics.ets学习统计页面。我开发时把“成就配置”和“成就进度”分开配置成就名称、描述、图标、目标值。进度当前完成度、是否解锁、解锁时间。这样以后新增成就时只需要补充配置管理逻辑可以复用。三、用户统计数据设计成就系统依赖学习行为统计function getDefaultStatistics():UserStatistics{return{totalEquationsViewed:0,totalElementsViewed:0,totalKnowledgeRead:0,dailyQuizCorrect:0,dailyQuizStreak:0,totalFavorites:0,totalSearches:0,visitDates:[],currentStreak:0,unlockedAchievements:[]};}这些数据覆盖了 App 的主要学习行为看过多少方程式。看过多少元素。读过多少知识点。答对多少题。收藏多少内容。连续学习多少天。我没有把统计写在页面里而是统一放到管理器中避免每个页面各算各的。四、成就管理器单例统一管理成就管理器使用单例static getInstance(): AchievementManager {if(AchievementManager.instancenull) {AchievementManager.instance newAchievementManager(); } returnAchievementManager.instance; }这样整个 App 中都能使用同一个成就状态。比如主入口记录访问。元素详情记录查看。知识详情记录阅读。挑战页记录答题。收藏动作记录收藏数量。统一管理的好处是数据不会分散成就判断也不会重复写。五、记录访问和连续学习用户每次打开 App 时会记录当天访问recordVisit(): void {constnow new Date();consttoday this.formatDate(now);constyesterday this.formatDate(new Date(now.getTime() -86400000));if(this.statistics.lastVisitDate today) {return; }if(!this.statistics.visitDates.includes(today)) {this.statistics.visitDates.push(today); }if(this.statistics.lastVisitDate yesterday) {this.statistics.currentStreak 1; }else{this.statistics.currentStreak 1; }this.statistics.lastVisitDate today;this.scheduleSave(); }这段逻辑是成就系统里最基础的一环。连续学习天数可以鼓励用户保持习惯但同一天重复打开不应该重复计数。六、行为记录把学习动作转成成就进度例如查看方程式recordEquationViewed(type?: string): void {this.checkAndUnlock(first_equation,1);this.statistics.totalEquationsViewed 1;this.checkAndUnlock(equation_5,this.statistics.totalEquationsViewed);this.checkAndUnlock(equation_15,this.statistics.totalEquationsViewed);this.checkAndUnlock(equation_30,this.statistics.totalEquationsViewed);this.scheduleSave(); }这里的思路是页面只告诉管理器“用户看了一个方程式”至于是否解锁成就由管理器判断。这样页面层非常干净不需要知道具体成就规则。七、成就解锁后的弹窗反馈成就页面订阅解锁事件privateonUnlockBound:(achievement: Achievement) void(achievement: Achievement) {this.showUnlockAnimation(achievement);this.refreshAchievements();this.unlockedCountthis.manager.getUnlockedCount(); };解锁时展示弹窗动效showUnlockAnimation(achievement: Achievement) {this.popupAchievement achievement;this.showUnlockPopup true;this.popupScale 0.3;this.popupOpacity 0; animateTo({ duration:400, curve: Curve.EaseOut }, () {this.popupScale 1;this.popupOpacity 1; }); }这个弹窗是成就系统的情绪反馈。用户完成某个动作后看到成就解锁会更愿意继续探索。八、成就页面展示设计成就页包含当前称号。已解锁数量。总进度条。全部/已解锁/未解锁切换。成就卡片列表。解锁弹窗。顶部进度区域代码片段Text(${this.unlockedCount}).fontSize(20).fontWeight(FontWeight.Bold).fontColor($r(app.color.secondary_color))Text(/${TOTAL_ACHIEVEMENTS}).fontSize(13).fontColor($r(app.color.text_tertiary))我希望用户进入页面后第一眼就能知道我现在处于什么阶段还差多少成就。九、称号系统让成就有长期目标项目中根据已解锁成就数量计算用户称号getTitle(): {level: number;name: string } { const t getUserTitle(this.statistics.unlockedAchievements.length);return { level: t.level, name: t.name}; }称号比单纯数字更有情绪价值。比如“化学学徒”“化学达人”这种命名会让学习过程更像成长路线。十、开发成就系统的思考我做成就系统时遵循了几个原则成就来自真实学习行为不做无意义打卡。页面只记录行为不判断复杂规则。解锁反馈要及时但不能打扰学习。成就数据本地保存保证离线可用。称号系统提供长期目标。十一、总结成就系统的价值不在于“炫”而在于让用户看见自己的学习轨迹。在「化学视界」里成就系统把元素查看、方程式阅读、知识学习、答题挑战、收藏行为串了起来 学得越多成就越丰富。 坚持越久连续天数越高。⭐ 收藏越多复习路径越清晰。 解锁越多用户称号越高。如果你也在开发学习类 App可以考虑把成就系统作为“长期留存”的一部分而不是最后随便加一个展示页。