前言
在「猫猫大作战」中,得分公式是整个游戏激励机制的核心。玩家合成的猫咪等级越高,获得的分数越有"爆发感"。如果采用线性增长,高级猫咪的合成动力不足;如果增长太快,低级猫咪就失去意义。最终我们选择了指数增长方案——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) | 1 | 3^0 × 10 | 10 | 20 | 50 | 80 |
| MEDIUM(2) | 2 | 3^1 × 10 | 30 | 60 | 150 | 240 |
| LARGE(3) | 3 | 3^2 × 10 | 90 | 180 | 450 | 720 |
| XLARGE(4) | 4 | 3^3 × 10 | 270 | 540 | 1350 | 2160 |
| SUPER(5) | 5 | 3^4 × 10 | 810 | 1620 | 4050 | 6480 |
| LEGENDARY(6) | 6 | 3^5 × 10 | 2430 | 4860 | 12150 | 19440 |
提示:
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) | 差距 |
|---|---|---|---|
| 1 | 10 | 10 | 1x |
| 2 | 50 | 30 | 0.6x |
| 3 | 90 | 90 | 1x |
| 4 | 130 | 270 | 2.1x |
| 5 | 170 | 810 | 4.8x |
| 6 | 210 | 2430 | 11.6x |
关键观察:
- 低等级阶段(1-3)两者差异不大,给新手平滑的学习曲线
- 中等级阶段(4-5)指数开始拉开差距,给中级玩家成就感
- 高等级阶段(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 的三重意义:
- 三合一的规则匹配:3 只同级合 1 只→底数为 3→奖励与投入成正比
- 10 倍阈值:玩家从合成传奇猫获得 2430 分 ≈ 243 次小猫合并,成就感强
- 分段增速:低等级平缓,高等级爆发,形成「前期攒资源、后期冲高分」的策略节奏
三、连击倍率系统
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 次合并 | 1 | 1x | 10 | 90 | 2430 |
| 第 2 次连击 | 2 | 2x | 20 | 180 | 4860 |
| 第 3 次连击 | 3 | 3x | 30 | 270 | 7290 |
| 第 4 次连击 | 4 | 4x | 40 | 360 | 9720 |
| 第 5+ 次连击 | 5 | 5x(最高) | 50 | 450 | 12150 |
提示:连击倍率上限为 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 |
| 倍率超过上限 | 截断到 5x | Math.min(count, 5) |
| 合并等级 0 | 数组越界 | CatConfig 从 level 1 开始 |
| 连击超时 | 重置为 1x | now - last < 2000判定 |
| 递归合并 | 每次合并独立算分 | 链式回调累积 |
七、游戏平衡性分析
7.1 得分分布模型
单局典型得分分布(假设 3 分钟游戏时长): 合并次数:约 30-50 次 小猫合并占比:60% → 约 300 分 中猫合并占比:20% → 约 180 分 大猫合并占比:12% → 约 324 分 特大猫合并占比:5% → 约 405 分 超级猫合并占比:2% → 约 486 分 传奇猫合并占比:1% → 约 729 分 ────────────────────────── 预计单局平均总分:约 2424 分7.2 刺激玩家策略
- 不要贪快,要贪连击:等连续合并机会比快速投放收益大
- 优先合成高等级:一个传奇猫 (2430) > 243 个小猫 (2430),但节省了大量操作
- 控制节奏:连击窗口 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 篇:循环合并链
- 系列文章索引