泡泡龙 Bubble Shooter:瞄准即落点,连锁才得分
拆解这只泡泡龙的确定性设计:角度如何被折叠成列选择、八向连通如何提高消除密度、每 10 发压顶如何把倒计时改成可计算的步数压力,以及悬空 20 分为什么是技巧上限。文末附可试玩 demo。
玩法拆解
- 14 行 × 8 列网格,开局随机填 5 行,蓝/绿/红三色泡泡
- 瞄准角 ±80° 直接映射到目标列:泡泡挂在该列最低泡泡之下,空列则顶到天花板
- 八向连通同色 ≥3 即消除,每颗 10 分;失去顶部锚点的泡泡整片下落,每颗 20 分
- 每发射 10 次天花板整体下压一行;触底或列满判负,清空网格直接结算
- 读盘:看网格缺口 + 当前/下一颗颜色,决定这一发去哪一列
- 按住拖动出瞄准线,松手发射(pointerDown 瞄准 / pointerUp 发射)
- 命中 → 消除计分 → 悬空连锁下落 → 发射计数 +1
- 计数满 10 发压顶一行,网格逼近底线形成倒计时感;结束进 result,可 Restart 或回菜单
- core/bubble-shooter 承载全部规则数据:bubbleGrid / currentBubble / nextBubble / score / comboCount
- 渲染与交互走 core/scene-renderer 的 grid-shooter 模板(PIXI),__OV.Games.BubbleShooter.Game 只做薄封装注册 drawer
- 消除用八向 flood fill,悬空检测用从顶行出发的 BFS 锚定标记
- 状态机 boot → menu → gameplay → result 由 v2-kernel LogicGraph 驱动,按钮事件与迁移事件严格同名
关键代码
Demo
点击 Play 开局;在网格区域按住拖动瞄准、松手发射,凑 3 颗同色消除,打掉支撑点可整片连锁下落;每 10 发天花板下压一行,别让泡泡触底。
文章
泡泡龙 Bubble Shooter:瞄准即落点,连锁才得分
一句话本质
表面上是"瞄准射击",实质是一个确定性三消:瞄准角被折叠成列选择,每一发都可以提前算清后果。连锁下落(悬空 20 分/颗)是技巧上限,每 10 发压顶一行是节奏时钟——玩家永远知道自己输在哪一发。
泡泡龙是全民认知。这只样本值得拆的地方在于:它把原版"连续弹道 + 墙面反弹"换成离散落点,用极低的实现成本保住了"这发该打哪"的解谜感。
行为循环
- 读盘:扫网格缺口与颜色分布,再看当前泡泡和下一颗预览——两个信息一起决定目标列。
- 瞄准:在网格区域按住拖动,出现瞄准虚线;角度限制在 ±80°。
- 发射:松手即射。泡泡不做连续物理飞行,按角度映射到目标列,挂在该列最低泡泡之下;空列则顶到天花板。
- 结算消除:新泡泡与邻居做八向连通检查,同色 ≥3 整片消除,每颗 10 分。
- 连锁下落:消除后做顶部锚定扫描,失去连接的泡泡整片掉落,每颗 20 分——得分放大器。
- 压顶:发射计数满 10,天花板整体下压一行并补一行随机泡泡。触底、列满判负;清空网格则通关。
- 结算页:展示最终分数,Restart 重开,Menu 回菜单。
原语标注
Aim(angle)– 按住拖动调整瞄准角,实时更新瞄准线Shoot(angle)– 松手发射当前泡泡Attach(row, col, color)– 泡泡按列挂载进网格Match(min=3)– 八向 flood fill 找同色连通块Eliminate(cells)– 消除并计分(10 分/颗)Cascade()– 顶行 BFS 锚定,未锚定泡泡整片下落(20 分/颗)Advance(every=10)– 每 10 发天花板下压一行CheckEnd()– 触底 / 列满 / 清空三向终局判定
参数速查表
| 参数 | 说明 | 默认值 | 单位 | |------|------|--------|------| | gridRows | 网格总行数 | 14 | 行 | | gridCols | 网格列数 | 8 | 列 | | initialRows | 开局填充行数 | 5 | 行 | | colorCount | 泡泡颜色数(蓝/绿/红) | 3 | 种 | | matchMin | 最小消除连通数 | 3 | 颗 | | popScore | 每颗消除得分 | 10 | 分 | | cascadeScore | 每颗悬空下落得分 | 20 | 分 | | advanceEvery | 压顶间隔(发射数) | 10 | 发 | | aimRange | 瞄准角度范围 | ±80 | 度 | | canvasRect | 发射交互区(设计坐标) | 75,180 / 600×540 | px |
设计取舍
- 角度折叠成列:连续弹道和反弹对触屏单手并不友好,落点预判也容易变成玄学。把 ±80° 直接映射到 8 列后,玩家下发前就能确定落点,解谜属性(spatial)才成立。代价是牺牲反弹炫技,换来每发都可复盘。
- 八向连通而非四向:斜对角也算连通,显著提高匹配概率。对入门难度这是对的——新手前几发就能打出消除;换四向,盘面会明显变"硬"。
- 压顶用步数而非秒表:每 10 发压一行,把倒计时翻译成可计算的步数压力。玩家能精确说出"我还有几发可以浪费",失败原因可解释,比秒表更适合解谜向玩家。
- 悬空 20 分 > 消除 10 分:双倍分差是最直白的行为引导——打支撑点比打散兵值钱。玩家会主动学习"找连接最细的那一格",技巧深度全藏在这个系数里。
- 三色而非四色:颜色越少,单发匹配期望越高,节奏越快;"清空网格"的胜利结局在 14×8 盘面上真实可达成,高手有"胜"的出口,而不只是比谁死得慢。
实现要点
- 规则全部下沉到模块:
core/bubble-shooter管网格、挂载、匹配、连锁、压顶与终局判定,只暴露reset / setAim / shoot三个动作;蓝图 LogicGraph 里只有 onEnter reset、onEvent(aim/shoot) 调动作,没有散落的分支逻辑。 - 渲染是模板而非定制:画面由
core/scene-renderer的 grid-shooter 模板绘制(交错行布局、瞄准线、消除淡出、危险线),__OV.Games.BubbleShooter.Game只是注册 drawer 的薄封装,换皮不用动渲染层。 - 悬空检测的正确姿势:消除后从顶行 BFS 打锚定标记,没被标记的就是悬空,一次性整片清除。逐颗递归判断"是否还挂着"在级联场景下又慢又容易漏。
- 压顶先判溢出再移动:下压前先查底行是否已有泡泡,有则直接
game.over,避免把泡泡推出网格。 - 事件名即契约:皮肤按钮的
game.start / game.restart / game.menu与状态机迁移事件严格同名,点击无需胶水代码;bubble.aim / bubble.shoot由指针事件发出,payload 只带一个 angle。 - 音频按事件挂:发射、挂载、消除、连锁、结束各挂一条 SFX,音效时机与规则事件天然对齐,表现层无需状态轮询。
"离散落点 + 八向匹配 + 步数压顶"是把街机泡泡龙改造成移动端解谜三消的最小配方。文中参数与判定都可以在文末 demo 里直接验证——它正是本文分析的那一份构建产物。
你可能也喜欢
拆解这只 8 球台球的确定性设计:拖拽距离如何折叠成 18 档力度、全停统一结算如何保证规则可信、犯规与自由球如何维持回合公平,以及 AI 误差如何制造对局张力。文末附可试玩 demo。

文章深度拆解多结局触发条件编写与玩家路径引导机制。通过量化核心要素明确通关门槛,构建从强提示到无引导的分级提示体系,并设计动态反馈以平衡探索自由度,帮助开发者高效构建多结局叙事结构。
120 秒、3 条命、323 颗豆:在方块城市迷宫里边吃边躲,能量豆的 8 秒攻守反转是全局唯一的节奏开关。