Phaser Boss 战阶段设计:招式表、转阶段和压迫感控制不能只靠血量

围绕 Phaser 动作游戏中的 Boss 战,拆解阶段状态机、招式调度、预警、碰撞窗口、难度调节和调试工具。

好 Boss 不是血厚的小怪

很多 Phaser 动作游戏的 Boss 初版只是一个血量更多、碰撞更大的敌人。它会追玩家、发子弹、血量低了发得更快。这样的 Boss 很快会暴露问题:招式没有预警,玩家不知道为什么受伤;阶段切换突然打断动画,看起来像 bug;弹幕密度随着血量线性增加,低端手机开始掉帧;玩家死了以后只觉得被数值压死,而不是想再挑战一次。Boss 战要有记忆点,核心是阶段、招式和反馈,而不是血条长度。

在 Phaser 中,Boss 战应该是一个独立战斗导演系统。Boss Sprite 本身只负责表现,真正决定行为的是阶段状态机和招式调度器。阶段定义当前可用招式、移动模式、弱点窗口和转阶段条件;招式定义预警、执行、恢复和可打断规则;导演根据玩家位置、距离、历史招式和难度选择下一招。这样 Boss 看起来有意图,而不是随机抽风。

阶段不是只有血量阈值

血量阈值是最常见的转阶段条件,但不应该是唯一条件。阶段可以由血量、时间、玩家行为、场景机关共同决定。比如 Boss 第一阶段测试玩家跳跃,第二阶段引入地刺,第三阶段才组合弹幕和冲刺。血量低于 50% 时不必立刻转阶段,可以等当前招式结束,播放咆哮和场景变化,再切换。这个等待很重要,它让玩家理解战斗进入新段落,也避免状态机被硬切。

每个阶段要有明确目标:教学、施压、变奏、高潮、收束。不要所有阶段都只是“更快更多”。可以让第二阶段反而降低频率但增加读招要求,第三阶段加入短暂输出窗口。节奏变化比单纯堆密度更有戏剧性。

stateDiagram-v2
  [*] --> Intro
  Intro --> PhaseOne: 入场动画结束
  PhaseOne --> TransitionA: HP <= 70% 且当前招式可结束
  TransitionA --> PhaseTwo: 场景机关激活
  PhaseTwo --> TransitionB: HP <= 35% 或战斗超过 120 秒
  TransitionB --> FinalPhase: 弱点暴露
  FinalPhase --> Defeated: HP <= 0
  PhaseOne --> Staggered: 破韧
  PhaseTwo --> Staggered: 破韧
  FinalPhase --> Staggered: 破韧
  Staggered --> PhaseOne: 恢复到来源阶段
  Staggered --> PhaseTwo: 恢复到来源阶段
  Staggered --> FinalPhase: 恢复到来源阶段

招式表要描述完整生命周期

一个招式至少有四段:准备、预警、执行、恢复。准备阶段决定目标和参数,比如冲刺目标点;预警阶段告诉玩家危险即将出现,比如地面红线或 Boss 抬手;执行阶段产生伤害判定;恢复阶段给玩家反击或调整位置的机会。新手常犯的错是只有执行阶段,于是 Boss 伤害像突然出现。玩家可以接受难,但不能接受没有信息。

招式配置可以包含冷却、权重、距离条件、阶段限制、最近使用惩罚、是否可打断。调度器选招时不能只随机。连续三次冲刺会显得机械,远距离还使用近战砸地会显得愚蠢。一个简单策略是先过滤可用招式,再按权重和上下文打分。上下文包括玩家距离、Boss 与墙的位置、最近招式、当前屏幕危险物数量。

伤害窗口必须和动画对齐

Boss 攻击动画通常很夸张,但真正伤害窗口应该是其中一小段。不要让整个挥刀动画都有伤害,也不要让特效消失后仍然有碰撞。Phaser 里可以在动画关键帧事件或时间轴中打开/关闭 hitbox。开发模式要能显示 hitbox,并用颜色区分预警、伤害、恢复。很多玩家觉得“判定不公平”,往往是因为视觉和碰撞窗口不一致。

如果使用 Arcade Physics,Boss 大型攻击可以用临时 Zone 或 Rectangle Body;如果使用 Matter,注意传感器和碰撞分类。无论哪种方式,hitbox 都应该由招式系统创建和销毁,而不是长期挂在 Boss 身上。这样每个招式的危险区域清楚,也便于调试。

一个招式调度器骨架

下面的示例展示如何按上下文选择招式。真实项目中,执行招式可以用 timeline、协程式状态机或 Phaser Time events 实现。

interface BossMove {
  id: string;
  phases: string[];
  cooldownMs: number;
  minDistance: number;
  maxDistance: number;
  baseWeight: number;
}

interface BossContext {
  phase: string;
  distanceToPlayer: number;
  nowMs: number;
  recentMoveIds: string[];
  cooldownUntil: Record<string, number>;
}

export function pickMove(moves: BossMove[], ctx: BossContext) {
  const scored = moves.flatMap((move) => {
    if (!move.phases.includes(ctx.phase)) return [];
    if (ctx.nowMs < (ctx.cooldownUntil[move.id] ?? 0)) return [];
    if (ctx.distanceToPlayer < move.minDistance || ctx.distanceToPlayer > move.maxDistance) return [];
    const repeatPenalty = ctx.recentMoveIds.includes(move.id) ? 0.25 : 1;
    return [{ move, score: move.baseWeight * repeatPenalty }];
  });

  const total = scored.reduce((sum, item) => sum + item.score, 0);
  let roll = Math.random() * total;
  for (const item of scored) {
    roll -= item.score;
    if (roll <= 0) return item.move;
  }
  return scored[0]?.move;
}

这个选择器只是基础,但它避免了最糟糕的完全随机。后续可以加入“屏幕已有危险物过多则不选弹幕”“玩家贴脸太久则选后跳”“Boss 靠墙则不选冲刺”等规则。重点是把规则集中在调度器,不要散在每个招式实现里。

转阶段要清理旧危险物

Boss 转阶段时,经常会留下旧阶段的子弹、地刺或延迟爆炸。除非设计明确要求混合,否则转阶段应该有清理策略:可销毁的危险物淡出,场景机关重置,Boss 进入无敌或减伤,玩家输入保留但伤害暂停。这样能避免玩家在看转阶段演出时被旧弹幕击杀。若希望保持压力,也要用明显规则告诉玩家,比如转阶段咆哮会震碎所有旧弹幕但生成新地形。

转阶段动画不要太长,尤其是移动端。第一次很震撼,重复挑战时就会烦。可以允许长按跳过已看过的转阶段演出,但跳过不能跳过状态清理。演出层可以快进,战斗模型必须完整执行。

难度调节要谨慎

Boss 战可以做轻微动态难度,但不要明显放水。比如玩家连续死亡三次后,第一阶段多给一个血瓶,或降低最后阶段弹幕持续时间。不要在玩家即将胜利时偷偷降低 Boss 血量,这会破坏成就感。动态调节应该优先影响恢复窗口、资源补给和教学提示,而不是改变核心判定。

也可以提供可选辅助:显示更明显预警、降低屏幕震动、开启练习模式。尤其在 Phaser Web 游戏里,设备差异很大,低端手机掉帧会让 Boss 战变难。提供辅助选项比假装所有设备体验一致更诚实。

调试工具决定迭代速度

Boss 战需要专门调试面板:当前阶段、当前招式、招式剩余时间、冷却表、hitbox 显示、最近伤害事件、玩家死亡原因。还要支持跳到指定阶段、锁血、强制执行某个招式。没有这些工具,设计师每次调第三阶段都要打两分钟前置流程,效率极低。Phaser 开发环境里可以用键盘快捷键或隐藏 DOM 面板实现。

战斗录像也很有价值。记录随机种子、招式选择、玩家输入和伤害事件,可以复现“某招式连发导致无解”的问题。Boss 战的平衡不是靠感觉一次次试玩,而是靠数据和可复现案例。

上线前检查清单

确认每个阶段有设计目标,而不只是血量阈值;确认转阶段等待当前招式安全结束;确认每个招式有预警、执行、恢复;确认 hitbox 和动画关键帧对齐;确认调度器避免连续重复和不合距离的招式;确认转阶段会清理或明确保留旧危险物;确认低帧率下伤害窗口仍然按时间而不是帧数计算;确认开发模式能跳阶段、强制招式和显示碰撞;确认失败日志记录死于哪个招式和哪个 hitbox。

一个好 Boss 会让玩家觉得“我知道下一次该怎么打”。Phaser 能让 Boss 动起来,但真正让战斗成立的是阶段节奏和信息公平。把招式当成有生命周期的系统,而不是一段动画,你的 Boss 才会像一个对手,而不是一个大号血条。

场景空间也是 Boss 的一部分

Boss 战不要只盯着 Boss 本体。场地大小、平台高度、障碍物、边界、可破坏掩体都会改变招式强度。同一个冲刺招式,在宽阔场地是位移压力,在狭窄场地可能变成必杀。设计招式表时,要同时记录推荐场地条件:需要多少横向空间,是否允许高低差,是否会把玩家推到屏幕外,是否需要安全角落。Phaser 中可以给 Boss Arena 配置危险区域和安全区域,调度器选招时参考玩家和 Boss 所在区域。

场景机关也要进入阶段系统。比如第一阶段只是躲避冲刺,第二阶段地面出现周期火焰,最终阶段天花板落石。机关如果自己独立运行,可能和 Boss 招式叠出无解组合。更好的方式是让 BossDirector 统一管理“当前屏幕压力预算”。一个重弹幕招式执行时,场景机关降低频率;Boss 进入恢复窗口时,机关可以提供轻微走位挑战。压力预算不是数学上绝对精确的值,但能防止多个系统同时把玩家压死。

失败后的学习链路

Boss 战失败反馈可以比普通战斗更具体。死亡界面不必只显示“挑战失败”,可以显示“被裂地斩击中 3 次”“最后一次受伤发生在预警后 0.42 秒”“推荐保持中距离观察抬手”。这些信息可以来自招式 id 和 hitbox id。玩家不一定每次都读,但当他卡关时,这些提示能把挫败感转成学习目标。

如果游戏面向休闲玩家,可以在多次失败后逐步增加提示强度:第一次只显示招式名,第三次显示闪避方向,第五次开放练习模式。这样比直接降低 Boss 血量更尊重玩家。Phaser 实现上,提示 UI 可以作为战斗 HUD 的一层,不影响 Boss 模型。提示是否出现由失败统计决定,而不是由 Boss 招式内部决定。

美术和程序要共享关键帧表

Boss 动画的关键帧最好形成表格:第几毫秒开始预警,第几毫秒打开伤害,第几毫秒关闭伤害,第几毫秒允许转向,第几毫秒进入恢复。美术调动画时,程序可以同步调整 hitbox 时间。不要让程序看着动画手动猜“差不多第 12 帧出伤害”。如果使用 Spine 或纹理序列,也可以通过动画事件导出关键帧。发布前用调试模式把关键帧标在时间轴上,能快速发现视觉和判定不一致。

音效也属于读招信息。低沉蓄力、短促破风、护盾碎裂这些声音能帮助玩家在注意力不在 Boss 身上时仍然感知危险。移动端玩家可能关闭声音,所以音效不能替代视觉预警,但它能强化节奏。每个关键招式最好都有可识别的声音轮廓。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页