Files
pixelheros/assets/script/game/hero/HeroAttrsSystem.ts
walkpan 1cce4ce361 feat(英雄系统): 添加英雄复活机制并控制怪物行为
实现英雄复活功能,当英雄死亡且有复活次数时延迟复活
新增is_reviving状态标记复活中状态
英雄死亡或复活时通过stop_mon_action控制怪物停止刷新和移动
2026-01-03 11:17:04 +08:00

129 lines
4.4 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";
/**
* ==================== 英雄属性更新系统 ====================
*
* 按照 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; // 总帧数
private debugMode: boolean = false; // 是否启用调试模式
private timer:Timer=new Timer(1)
/**
* 过滤器:只处理拥有 HeroAttrsComp 的实体
*/
filter(): ecs.IMatcher {
return ecs.allOf(HeroAttrsComp);
}
/**
* 实体首次进入系统时调用(每个实体只调用一次)
*/
entityEnter(e: ecs.Entity): void {
if(!smc.mission.play || smc.mission.pause) return;
const model = e.get(HeroAttrsComp);
if (!model) return;
console.log(`[HeroAttrSystem] 英雄进入系统: ${model.hero_name} (uuid: ${model.hero_uuid})`);
}
/**
* 系统首次更新前调用(整个系统只调用一次)
*/
firstUpdate(): void {
console.log("[HeroAttrSystem] 系统首次更新");
}
/**
* 每帧更新(为每个英雄调用一次)
*
* ⭐ 关键理解:
* - 如果有 3 个英雄,这个方法每帧会被调用 3 次
* - 每次调用处理不同的实体 e
* - 这是正确的设计,不是 bug
*/
update(e: ecs.Entity): void {
if(!smc.mission.play || smc.mission.pause) return;
const model = e.get(HeroAttrsComp);
if (!model || model.is_dead || model.is_reviving) return;
// 统计:记录本帧处理的实体数
this.entityCount++;
// 调试日志(可选,调试时启用)
if (this.debugMode) {
console.log(` [${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) {
console.log(`[HeroAttrSystem] 第 ${this.frameCount} 帧,处理 ${this.entityCount} 个英雄`);
}
// 注意:显示更新由 HeroViewComp 负责,这里只处理数据
}
/**
* 启用调试模式(调试时使用)
*/
enableDebug() {
this.debugMode = true;
}
/**
* 禁用调试模式(正式运行)
*/
disableDebug() {
this.debugMode = false;
}
}