Files
pixelheros/assets/script/game/hero/HeroAttrsSystem.ts
panw dc746e28da refactor(英雄系统): 将调试模式变量移至Monster类
将HeroAttrSystem中的debugMode改为public,并在Monster类中添加私有debugMode字段,为后续调试功能做准备。
2026-02-03 16:33:21 +08:00

130 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Timer } from "db://oops-framework/core/common/timer/Timer";
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { smc } from "../common/SingletonModuleComp";
import { Attrs } from "../common/config/HeroAttrs";
import { HeroUpSet } from "../common/config/heroSet";
import { HeroSkillsComp } from "./HeroSkills";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { mLogger } from "../common/Logger";
/**
* ==================== 英雄属性更新系统 ====================
*
* 按照 ECS 设计理念:
* - ComponentHeroAttrsComp存储数据
* - SystemHeroAttrSystem处理业务逻辑
*
* 系统职责:
* 1. 每帧更新临时 Buff时间递减过期移除
* 2. 每帧更新 HP/MP 自然回复
* 3. 限制属性值在合理范围内
*
/**
* 使用方式:
* 在 RootSystem 中注册此系统,它会自动每帧更新所有拥有 HeroAttrsComp 的实体
*/
@ecs.register('HeroAttrSystem')
export class HeroAttrSystem extends ecs.ComblockSystem
implements ecs.ISystemUpdate, ecs.IEntityEnterSystem, ecs.ISystemFirstUpdate {
// ==================== 调试统计(可选)====================
private entityCount: number = 0; // 本帧处理的实体数
private frameCount: number = 0; // 总帧数
public debugMode: boolean = false; // 是否启用调试模式
private timer:Timer=new Timer(1)
/**
* 过滤器:只处理拥有 HeroAttrsComp 的实体
*/
filter(): ecs.IMatcher {
return ecs.allOf(HeroAttrsComp);
}
/**
* 实体首次进入系统时调用(每个实体只调用一次)
*/
entityEnter(e: ecs.Entity): void {
const model = e.get(HeroAttrsComp);
if (!model) return;
mLogger.log(this.debugMode, 'HeroAttrSystem', `[HeroAttrSystem] 英雄进入系统: ${model.hero_name} (uuid: ${model.hero_uuid})`);
}
/**
* 系统首次更新前调用(整个系统只调用一次)
*/
firstUpdate(): void {
mLogger.log(this.debugMode, 'HeroAttrSystem', "[HeroAttrSystem] 系统首次更新");
}
/**
* 每帧更新(为每个英雄调用一次)
*
* ⭐ 关键理解:
* - 如果有 3 个英雄,这个方法每帧会被调用 3 次
* - 每次调用处理不同的实体 e
* - 这是正确的设计,不是 bug
*/
update(e: ecs.Entity): void {
if(!smc.mission.play ) return;
if(smc.mission.pause) return
const model = e.get(HeroAttrsComp);
if (!model || model.is_dead || model.is_reviving) return;
// 统计:记录本帧处理的实体数
this.entityCount++;
// 调试日志(可选,调试时启用)
if (this.debugMode) {
mLogger.log(this.debugMode, 'HeroAttrSystem', ` [${this.entityCount}] 更新英雄: ${model.hero_name}, HP: ${model.hp.toFixed(2)}`);
}
// 1. 更新临时 Buff/Debuff时间递减过期自动移除
model.updateTemporaryBuffsDebuffs(this.dt);
// 记录MP变化前的值
const oldMp = model.mp;
if(this.timer.update(this.dt)){
// 2. HP/MP 自然回复(业务规则)
model.mp += HeroUpSet.MP
model.hp += HeroUpSet.HP
}
// 3. 限制属性值在合理范围内
if (model.mp > model.Attrs[Attrs.MP_MAX]) {
model.mp = model.Attrs[Attrs.MP_MAX];
}
if (model.hp > model.Attrs[Attrs.HP_MAX]) {
model.hp = model.Attrs[Attrs.HP_MAX];
}
// 4. 如果MP发生变化更新最大技能距离缓存最小距离不受MP影响
if (model.mp !== oldMp) {
const skillsComp = e.get(HeroSkillsComp);
if (skillsComp) {
model.updateSkillDistanceCache(skillsComp);
}
}
// 每 60 帧输出一次统计
this.frameCount++;
if (this.frameCount % 60 === 0 && this.entityCount === 1) {
mLogger.log(this.debugMode, 'HeroAttrSystem', `[HeroAttrSystem] 第 ${this.frameCount} 帧,处理 ${this.entityCount} 个英雄`);
}
// 注意:显示更新由 HeroViewComp 负责,这里只处理数据
}
/**
* 启用调试模式(调试时使用)
*/
enableDebug() {
this.debugMode = true;
}
/**
* 禁用调试模式(正式运行)
*/
disableDebug() {
this.debugMode = false;
}
}