feat: 完成肉鸽回合制游戏核心玩法迭代

新增连杀系统、金币飞行特效、波次HUD、屏幕震动等表现功能,重构怪物刷出逻辑与难度动态调节,调整回合回血比例,优化游戏节奏与体验。

主要变更:
1.  调整回合回血比例从0.5到0.4,优化前期节奏
2.  新增连杀计数与奖励系统,支持5/10/20连杀触发对应表现
3.  实现怪物死亡掉落金币的抛物线飞行特效
4.  增加波次进度HUD,显示剩余怪物与全局回合进度
5.  新增屏幕震动工具与战斗横幅统一展示系统
6.  重构怪物刷出逻辑,支持按回合类型调整刷怪间隔,加入清场加速机制
7.  优化动态难度调节算法,增加滞回与指数平滑,避免难度突变
8.  新增Boss预警、登场事件与回合清屏事件,完善事件总线
9.  调整怪物数量阈值与回合倒计时档位,适配新的节奏设计
This commit is contained in:
pan
2026-08-11 19:00:23 +08:00
parent d57f4c14e0
commit 409113e269
12 changed files with 904 additions and 80 deletions

View File

@@ -0,0 +1,72 @@
/**
* @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;
}
}
}
}