/** * @file ComboComp.ts * @description 连杀 Combo 计数组件(逻辑层,事件驱动) * * 职责: * 1. 监听 MonDead 事件,2s 滑动窗口内累计连杀数。 * 2. 达阈值(5/10/20)时派发 ComboReach 事件,由 BattleBannerComp 消费分级表现。 * 3. 窗口超时或整局结束(MissionEnd)清零。 * * 使用 oops-framework 模块:oops.message(事件解耦)。 * 本组件无 UI 绑定,挂 mission.prefab 任意节点即可。 */ import { _decorator } from "cc"; import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops"; import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; import { GameEvent } from "../common/config/GameEvent"; import { smc } from "../common/SingletonModuleComp"; const { ccclass } = _decorator; /** 连杀窗口(秒):窗口内每次击杀续期 */ const COMBO_WINDOW = 2; /** 连杀阈值档位:x5 / x10 / x20 */ const COMBO_TIERS = [5, 10, 20]; @ccclass('ComboComp') export class ComboComp extends CCComp { /** 当前连杀数 */ private comboCount: number = 0; /** 滑动窗口剩余时间(秒) */ private windowTimer: number = 0; onLoad() { // oops.message 全局事件总线:怪物死亡 / 整局结束 oops.message.on(GameEvent.MonDead, this.onMonDead, this); oops.message.on(GameEvent.MissionEnd, this.resetCombo, this); } onDestroy() { oops.message.off(GameEvent.MonDead, this.onMonDead, this); oops.message.off(GameEvent.MissionEnd, this.resetCombo, this); } private onMonDead() { this.comboCount++; this.windowTimer = COMBO_WINDOW; const tier = COMBO_TIERS.indexOf(this.comboCount); if (tier >= 0) { // oops.message 全局事件总线:连杀达阈值(横幅/震屏/金币爆发由 BattleBannerComp 消费) oops.message.dispatchEvent(GameEvent.ComboReach, { count: this.comboCount, tier, }); } } private resetCombo() { this.comboCount = 0; this.windowTimer = 0; } protected update(dt: number) { if (!smc.mission.play || smc.mission.pause) return; if (this.windowTimer > 0) { this.windowTimer -= dt; if (this.windowTimer <= 0) { this.comboCount = 0; } } } }