HarmonyOS应用开发实战:猫猫大作战-指数得分公式的设计

HarmonyOS应用开发实战:猫猫大作战-指数得分公式的设计

前言

在「猫猫大作战」中,得分公式是整个游戏激励机制的核心。玩家合成的猫咪等级越高,获得的分数越有"爆发感"。如果采用线性增长,高级猫咪的合成动力不足;如果增长太快,低级猫咪就失去意义。最终我们选择了指数增长方案——3^(level-1) × 10,再叠加连击倍率,让每一组合成都充满期待。

本文以GameEngine.tryMergeAt()中的得分计算为锚点,讲解指数得分公式的设计思路、数学原理、连击倍率的叠加机制、以及这套公式在游戏平衡性上的考量。

提示:本系列不讲 ArkTS 基础语法与环境搭建,假设你已跟完第 1–128 篇。本篇是阶段四第 129 篇。

一、核心得分公式

1.1 公式定义

// 来源:entry/src/main/ets/components/GameEngine.etsprivatecalculateMergeScore(catLevel:number,comboMultiplier:number):number{constbaseScore=CatConfig[catLevel].score;returnbaseScore*comboMultiplier;}

CatConfig中预定义的各等级基础分:

exportconstCatConfig:Record<CatLevel,CatConfigItem>={[CatLevel.SMALL]:{name:'小猫',score:10,size:40,color:'#FF9800'},[CatLevel.MEDIUM]:{name:'中猫',score:30,size:50,color:'#F57C00'},[CatLevel.LARGE]:{name:'大猫',score:90,size:60,color:'#E65100'},[CatLevel.XLARGE]:{name:'特大猫',score:270,size:70,color:'#D84315'},[CatLevel.SUPER]:{name:'超级猫',score:810,size:80,color:'#BF360C'},[CatLevel.LEGENDARY]:{name:'传奇猫',score:2430,size:90,color:'#8E24AA'},};

1.2 背后的指数公式

// 基础分 = 3^(level-1) × 10// 其中 level 从 1 开始(SMALL = 1)constbaseScore=Math.pow(3,level-1)*10;
等级level公式基础分倍率×2倍率×5倍率×8
SMALL(1)13^0 × 1010205080
MEDIUM(2)23^1 × 103060150240
LARGE(3)33^2 × 1090180450720
XLARGE(4)43^3 × 1027054013502160
SUPER(5)53^4 × 10810162040506480
LEGENDARY(6)63^5 × 10243048601215019440

提示:Math.pow(3, level - 1)的底数 3 对应「三只同级合成一只高级」的合并规则。每次合成投入 3 只猫咪,产出 1 只高级猫,得分恰好成指数增长,形成「投入产出比」的正反馈。

二、为什么选择指数增长

2.1 线性 vs 指数对比

// 线性增长方案(已弃用)constlinearScore=40*level-30;// level 1 → 10, level 2 → 50, level 3 → 90, level 4 → 130...// 指数增长方案(当前使用)constexpScore=Math.pow(3,level-1)*10;// level 1 → 10, level 2 → 30, level 3 → 90, level 4 → 270...
level线性 (40n-30)指数 (3^(n-1)×10)差距
110101x
250300.6x
390901x
41302702.1x
51708104.8x
6210243011.6x

关键观察

  1. 低等级阶段(1-3)两者差异不大,给新手平滑的学习曲线
  2. 中等级阶段(4-5)指数开始拉开差距,给中级玩家成就感
  3. 高等级阶段(6)指数爆发,给核心玩家终极目标

2.2 底数 3 的选择理由

// 底数 2(增长太慢)Math.pow(2,level-1)*10;// 1→10, 2→20, 3→40, 4→80, 5→160... 传奇猫仅 160 分,缺乏吸引力// 底数 3(当前选择)Math.pow(3,level-1)*10;// 1→10, 2→30, 3→90, 4→270, 5→810, 6→2430... 每 3 级 27 倍,正反馈强// 底数 4(增长太快)Math.pow(4,level-1)*10;// 1→10, 2→40, 3→160, 4→640, 5→2560... 中猫合成奖励太高,失衡

底数 3 的三重意义

  1. 三合一的规则匹配:3 只同级合 1 只→底数为 3→奖励与投入成正比
  2. 10 倍阈值:玩家从合成传奇猫获得 2430 分 ≈ 243 次小猫合并,成就感强
  3. 分段增速:低等级平缓,高等级爆发,形成「前期攒资源、后期冲高分」的策略节奏

三、连击倍率系统

3.1 连击机制

// 来源:GameEngine.ets — combo 状态管理interfaceComboInfo{count:number;// 连击次数multiplier:number;// 当前倍率lastMergeTime:number;// 上次合并时间戳(ms)}privateonMerge(x:number,y:number):void{constnow=Date.now();constcomboWindow=2000;// 2 秒内连续合并算连击if(now-this.combo.lastMergeTime<comboWindow){// 连击递增this.combo.count++;this.combo.multiplier=Math.min(this.combo.count,5);// 最大 5 倍}else{// 超时重置this.combo.count=1;this.combo.multiplier=1;}this.combo.lastMergeTime=now;// 计算本次合并得分constmergeScore=this.calculateMergeScore(cat.level,this.combo.multiplier);this.score+=mergeScore;}

3.2 倍率与得分累积

// 连续合并示例// 时间轴:t=0ms → t=500ms → t=1000ms → t=1500ms → t=3000ms(超时)// 倍率: 1x → 2x → 3x → 4x → 1x(重置)// 合并等级不同组合示例:// 场景:连续 3 次合成小猫(每次间隔 < 2s)// 第 1 次:基础 10 分 × 1x = 10 分// 第 2 次:基础 10 分 × 2x = 20 分// 第 3 次:基础 10 分 × 3x = 30 分// 总计:60 分 | 无连击:30 分 → 提升 2 倍// 场景:连续 3 次合成大猫(间隔 < 2s)// 第 1 次:基础 90 分 × 1x = 90 分// 第 2 次:基础 90 分 × 2x = 180 分// 第 3 次:基础 90 分 × 3x = 270 分// 总计:540 分 | 无连击:270 分 → 提升 2 倍
操作连击次数倍率小猫合并大猫合并传奇合并
第 1 次合并11x10902430
第 2 次连击22x201804860
第 3 次连击33x302707290
第 4 次连击44x403609720
第 5+ 次连击55x(最高)5045012150

提示:连击倍率上限为 5 倍。这是经过测试后确定的平衡值——倍率太高会导致玩家"只堆连击不看等级",太低则连击系统缺乏吸引力。5 倍上限下,一次 5 连击传奇合并可获得 12150 分,占单局总分相当比例。

四、递归合并中的得分累积

4.1 链式合并得分

当一次合并触发递归合并链时,每次合并都单独计算得分:

// 来源:GameEngine.ets — 递归合并链privatetryMergeAt(x:number,y:number):boolean{constcat=this.board[y][x];if(!cat||cat.falling)returnfalse;// 查找相邻同级猫咪constneighbors=this.findSameLevelNeighbors(x,y,cat.level);if(neighbors.length<2)returnfalse;// 移除 3 只、创建高级猫this.removeCats([{x,y},...neighbors.slice(0,2)]);constnewLevel=cat.level+1;constnewCat=this.createCatAt(x,y,newLevel);// 得分计算(本轮的连击倍率)this.score+=this.calculateMergeScore(cat.level,this.combo.multiplier);// 递归检测:新创建的猫是否能继续合并if(this.tryMergeAt(x,y)){// 递归链继续...}returntrue;}

4.2 链式合并得分示例

初始棋盘: (2,3): 小猫(Lv.1) (2,4): 小猫(Lv.1) (2,5): 小猫(Lv.1) (2,6): 中猫(Lv.2) (2,7): 中猫(Lv.2) 步骤 1:投放在 (2,3) 处掉落一个小猫(Lv.1) → (2,3) (2,4) (2,5) 三只小猫相邻 → 合并为中猫(Lv.2) → 得分: 10 × 1x = 10 步骤 2:新中猫(Lv.2) 与 (2,6) (2,7) 的中猫相邻 → 递归合并 → 3 只中猫合并为大猫(Lv.3) → 得分: 30 × 1x = 30 总得分: 10 + 30 = 40 分 (如果步骤 1→2 在 2 秒内完成,则步骤 2 享受 2x 倍率 = 60 分,总分 70)

五、得分系统的 UI 展示

5.1 实时得分显示

// 来源:entry/src/main/ets/pages/Index.etsbuild(){Column(){if(this.gameState===GameState.PLAYING){GameHUD({score:this.score,combo:this.combo,highScore:this.highScore})GameBoard({cats:this.cats,onColumnClick:(col)=>this.onColumnClick(col)})}}}

5.2 合并动画时的浮动得分

// 合并时弹出 "+XX" 浮动文字@BuilderScorePopup(score:number,multiplier:number){Text(`+${score}`).fontSize(score>100?24:18).fontWeight(FontWeight.Bold).fontColor(score>500?'#F39C12':'#E74C3C').transition({type:TransitionType.Insert,opacity:0})}// 连击提示@BuilderComboBadge(count:number){if(count>=3){Text(`${count}x 连击!`).fontSize(16).fontWeight(FontWeight.Bold).fontColor('#E74C3C').shadow({radius:4,color:'#FF6B6B',offsetY:2})}}

六、得分公式验证

6.1 单元测试

// 得分计算验证functiontestScoreFormula(){// 小猫基础分assert.strictEqual(calculateMergeScore(CatLevel.SMALL,1),10);// 传奇猫基础分assert.strictEqual(calculateMergeScore(CatLevel.LEGENDARY,1),2430);// 5 倍连击assert.strictEqual(calculateMergeScore(CatLevel.SUPER,5),4050);}

6.2 边界情况

场景预期行为验证方法
倍率为 0得分为 0实际倍率最小为 1
倍率超过上限截断到 5xMath.min(count, 5)
合并等级 0数组越界CatConfig 从 level 1 开始
连击超时重置为 1xnow - last < 2000判定
递归合并每次合并独立算分链式回调累积

七、游戏平衡性分析

7.1 得分分布模型

单局典型得分分布(假设 3 分钟游戏时长): 合并次数:约 30-50 次 小猫合并占比:60% → 约 300 分 中猫合并占比:20% → 约 180 分 大猫合并占比:12% → 约 324 分 特大猫合并占比:5% → 约 405 分 超级猫合并占比:2% → 约 486 分 传奇猫合并占比:1% → 约 729 分 ────────────────────────── 预计单局平均总分:约 2424 分

7.2 刺激玩家策略

  1. 不要贪快,要贪连击:等连续合并机会比快速投放收益大
  2. 优先合成高等级:一个传奇猫 (2430) > 243 个小猫 (2430),但节省了大量操作
  3. 控制节奏:连击窗口 2 秒,规划好再投放

八、其他游戏得分方案参考

方案公式特点典型游戏
线性a × level + b可预测、缺惊喜传统消除
指数(本游戏)3^(n-1) × 10越高级越爽猫猫大作战
斐波那契F(n) × k自然增长曲线合成类游戏
对数log(n) × k等级越高增长越缓放置类游戏

提示:指数方案最适合「合并进化」类游戏——合成本身就是指数行为(3 只变 1 只),用指数得分匹配指数合成,玩家直观感受「越合越赚」。

九、性能考量

// Math.pow 的性能在游戏循环中可接受// 但更好的做法是预计算级别分(已经在 CatConfig 中预定义)constprecomputedScores=[0,10,30,90,270,810,2430];// 运行时直接查表,避免每次调用 Math.powfunctiongetBaseScore(level:number):number{returnprecomputedScores[level]??0;}

十、完整代码示例

// GameEngine.ets 中的完整得分逻辑exportclassGameEngine{privatescore:number=0;privatecombo:ComboInfo={count:0,multiplier:1,lastMergeTime:0};privatereadonlyCOMBO_WINDOW=2000;// 2s 连击窗口privatereadonlyMAX_MULTIPLIER=5;// 最高 5 倍privatecalculateMergeScore(catLevel:number,comboMultiplier:number):number{returnCatConfig[catLevel].score*comboMultiplier;}privateupdateCombo():void{constnow=Date.now();if(now-this.combo.lastMergeTime<this.COMBO_WINDOW){this.combo.count++;this.combo.multiplier=Math.min(this.combo.count,this.MAX_MULTIPLIER);}else{this.combo.count=1;this.combo.multiplier=1;}this.combo.lastMergeTime=now;}tryMergeAt(x:number,y:number):boolean{// ... 合并逻辑 ...this.updateCombo();this.score+=this.calculateMergeScore(cat.level,this.combo.multiplier);// ... 递归合并 ...}getScore():number{returnthis.score;}getCombo():ComboInfo{return{...this.combo};}resetScore():void{this.score=0;this.combo={count:0,multiplier:1,lastMergeTime:0};}}

总结

「猫猫大作战」的得分公式3^(level-1) × 10采用指数增长 + 连击倍率双重机制。指数增长与三合一规则匹配,让高级合成收益远超低级;连击倍率(上限 5 倍)激励玩家连续操作,形成紧张的策略节奏。核心要点:Math.pow(3, level-1)底数 3 对应三合一规则、 连击 2 秒窗口 + 倍率上限 5 防失衡、 递归链每次合并独立算分累积、 预计算查表优于运行时 Math.pow

下一篇将深入循环合并链——while merged 连锁反应实现级联消除。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

  • GameEngine.ets 完整源码
  • Math.pow() MDN 文档
  • 游戏平衡性设计 — 知乎
  • 指数增长与游戏设计
  • ArkTS setInterval 定时器
  • 开源鸿蒙跨平台社区
  • HarmonyOS 开发者官方文档
  • 第 128 篇:连击倍率实现
  • 第 130 篇:循环合并链
  • 系列文章索引