perf(英雄属性): 使用脏标签模式优化属性UI更新性能
在 HeroAttrsComp 中添加脏标签标记,仅在属性变化时更新UI 移除 HeroViewComp 中每帧不必要的UI更新调用 添加文档说明优化方案
This commit is contained in:
@@ -14,39 +14,27 @@ import { HeroAttrEvent } from "./HeroAttrEvent";
|
||||
*
|
||||
* 系统职责:
|
||||
* 1. 处理当角色收到attr变更事件时,更新角色属性,并处理动画展示
|
||||
|
||||
*
|
||||
/**
|
||||
* 使用方式:
|
||||
* 在 RootSystem 中注册此系统,它会自动每帧更新所有拥有 HeroAttrsComp 的实体
|
||||
*/
|
||||
@ecs.register('HeroAttrEventSystem')
|
||||
export class HeroAttrEventSystem extends ecs.ComblockSystem
|
||||
implements ecs.IEntityEnterSystem {
|
||||
|
||||
/**
|
||||
* 过滤器:只处理拥有 HeroAttrsComp 的实体
|
||||
*/
|
||||
implements ecs.ISystemUpdate, ecs.IEntityEnterSystem {
|
||||
|
||||
filter(): ecs.IMatcher {
|
||||
return ecs.allOf(HeroAttrsComp,HeroAttrEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 实体首次进入系统时调用(每个实体只调用一次)
|
||||
*/
|
||||
entityEnter(e: ecs.Entity): void {
|
||||
if(!smc.mission.play || smc.mission.pause) return;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统首次更新前调用(整个系统只调用一次)
|
||||
*/
|
||||
firstUpdate(): void {
|
||||
console.log("[HeroAttrEventSystem] 系统首次更新");
|
||||
update(e: ecs.Entity): void {
|
||||
if(!smc.mission.play || smc.mission.pause) return;
|
||||
const model = e.get(HeroAttrsComp);
|
||||
if (!model || model.is_dead) return;
|
||||
const event = e.get(HeroAttrEvent);
|
||||
if (!event) return;
|
||||
// 移除事件组件(事件处理完成)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 启用调试模式(调试时使用)
|
||||
*/
|
||||
|
||||
@@ -38,7 +38,12 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
Talents: Record<number, talTrigger> = {};
|
||||
//数值型天赋buff
|
||||
BUFFS_TAL: Record<number, {count:number,BType:BType,attrIndex:number,value: number}> = {};
|
||||
|
||||
|
||||
// ==================== 脏标签标记 ====================
|
||||
dirty_hp: boolean = false; // 血量变更标记
|
||||
dirty_mp: boolean = false; // 魔法值变更标记
|
||||
dirty_shield: boolean = false; // 护盾变更标记
|
||||
|
||||
// ==================== 技能距离缓存 ====================
|
||||
maxSkillDistance: number = 0; // 最远技能攻击距离(缓存,受MP影响)
|
||||
minSkillDistance: number = 0; // 最近技能攻击距离(缓存,不受MP影响,用于停止位置判断)
|
||||
@@ -128,6 +133,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
}
|
||||
this.hp += addValue;
|
||||
this.hp = Math.max(0, Math.min(this.hp, this.Attrs[Attrs.HP_MAX]));
|
||||
this.dirty_hp = true; // 标记血量需要更新
|
||||
}
|
||||
add_mp(value:number,isValue:boolean){
|
||||
let addValue = value;
|
||||
@@ -140,6 +146,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
}
|
||||
this.mp += addValue;
|
||||
this.mp = Math.max(0, Math.min(this.mp, this.Attrs[Attrs.MP_MAX]));
|
||||
this.dirty_mp = true; // 标记魔法值需要更新
|
||||
}
|
||||
add_shield(value:number,isValue:boolean){
|
||||
let addValue = value;
|
||||
@@ -148,6 +155,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
}
|
||||
this.shield += addValue;
|
||||
this.shield = Math.max(0, Math.min(this.shield, this.Attrs[Attrs.HP_MAX]));
|
||||
this.dirty_shield = true; // 标记护盾需要更新
|
||||
}
|
||||
// ==================== BUFF 管理 ====================
|
||||
/**
|
||||
@@ -561,6 +569,10 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
this.atk_count = 0;
|
||||
this.atked_count = 0;
|
||||
this.killed_count =0;
|
||||
// 重置脏标签
|
||||
this.dirty_hp = false;
|
||||
this.dirty_mp = false;
|
||||
this.dirty_shield = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -148,12 +148,22 @@ export class HeroViewComp extends CCComp {
|
||||
|
||||
// ✅ View 层职责:处理表现相关的逻辑
|
||||
this.processDamageQueue(); // 伤害数字显示队列
|
||||
|
||||
// ✅ 更新 UI 显示(数据由 HeroAttrSystem 更新)
|
||||
// 移除了每帧调用的 hp_show,改为仅在需要时调用
|
||||
this.hp_show();
|
||||
this.mp_show();
|
||||
this.show_shield(this.model.shield, this.model.Attrs[Attrs.SHIELD_MAX]);
|
||||
|
||||
// ✅ 按需更新 UI(脏标签模式)- 只在属性变化时更新
|
||||
if (this.model.dirty_hp) {
|
||||
this.hp_show();
|
||||
this.model.dirty_hp = false;
|
||||
}
|
||||
|
||||
if (this.model.dirty_mp) {
|
||||
this.mp_show();
|
||||
this.model.dirty_mp = false;
|
||||
}
|
||||
|
||||
if (this.model.dirty_shield) {
|
||||
this.show_shield(this.model.shield, this.model.Attrs[Attrs.SHIELD_MAX]);
|
||||
this.model.dirty_shield = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user