refactor(英雄): 分离间隔效果的应用与视图更新逻辑
将间隔效果的处理逻辑从 HeroAttrsComp 中分离,改为由 HeroBuffSystem 统一收集并应用效果,同时触发 HeroViewComp 中的视觉反馈。这提高了关注点分离,使属性计算与视图更新解耦,便于维护和扩展新的间隔效果类型。
This commit is contained in:
@@ -6,6 +6,7 @@ import { BuffConf, BuffRunType, SkillDisVal, SkillRange } from "../common/config
|
|||||||
import { HeroInfo, HType } from "../common/config/heroSet";
|
import { HeroInfo, HType } from "../common/config/heroSet";
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
|
import { HeroViewComp } from "./HeroViewComp";
|
||||||
import { _decorator } from "cc";
|
import { _decorator } from "cc";
|
||||||
|
|
||||||
const { property } = _decorator;
|
const { property } = _decorator;
|
||||||
@@ -333,31 +334,33 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
this.updateStatusFlags();
|
this.updateStatusFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateIntervalEffectsBySystem(dt: number) {
|
collectIntervalEffectsBySystem(dt: number): IntervalBuffState[] {
|
||||||
|
const triggered: IntervalBuffState[] = [];
|
||||||
for (let i = this.INTERVAL_EFFECTS.length - 1; i >= 0; i--) {
|
for (let i = this.INTERVAL_EFFECTS.length - 1; i >= 0; i--) {
|
||||||
const state = this.INTERVAL_EFFECTS[i];
|
const state = this.INTERVAL_EFFECTS[i];
|
||||||
state.remain -= dt;
|
state.remain -= dt;
|
||||||
state.tick -= dt;
|
state.tick -= dt;
|
||||||
while (state.tick <= 0 && state.remain > 0) {
|
while (state.tick <= 0 && state.remain > 0) {
|
||||||
this.applyIntervalEffect(state);
|
triggered.push({
|
||||||
|
id: state.id,
|
||||||
|
attr: state.attr,
|
||||||
|
sourceUuid: state.sourceUuid,
|
||||||
|
value: state.value,
|
||||||
|
BType: state.BType,
|
||||||
|
interval: state.interval,
|
||||||
|
remain: state.remain,
|
||||||
|
tick: state.tick
|
||||||
|
});
|
||||||
state.tick += state.interval;
|
state.tick += state.interval;
|
||||||
}
|
}
|
||||||
if (state.remain <= 0) {
|
if (state.remain <= 0) {
|
||||||
this.INTERVAL_EFFECTS.splice(i, 1);
|
this.INTERVAL_EFFECTS.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return triggered;
|
||||||
}
|
}
|
||||||
|
applyStoredEffect(attr: Attrs, value: number, type: BType) {
|
||||||
private applyIntervalEffect(state: IntervalBuffState) {
|
this.applyAttrChange(attr, value, type);
|
||||||
if (state.attr === Attrs.hp) {
|
|
||||||
this.add_hp(state.value, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (state.attr === Attrs.shield) {
|
|
||||||
this.add_shield(state.value, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.applyAttrChange(state.attr, state.value, state.BType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateList(list: Record<number, ActiveBuffState[]>, dt: number) {
|
private updateList(list: Record<number, ActiveBuffState[]>, dt: number) {
|
||||||
@@ -535,7 +538,37 @@ export class HeroBuffSystem extends ecs.ComblockSystem implements ecs.ISystemUpd
|
|||||||
const attrs = e.get(HeroAttrsComp);
|
const attrs = e.get(HeroAttrsComp);
|
||||||
if (!attrs || attrs.is_dead) return;
|
if (!attrs || attrs.is_dead) return;
|
||||||
attrs.updateBuffsDebuffs(this.dt);
|
attrs.updateBuffsDebuffs(this.dt);
|
||||||
attrs.updateIntervalEffectsBySystem(this.dt);
|
const triggered = attrs.collectIntervalEffectsBySystem(this.dt);
|
||||||
|
if (triggered.length === 0) return;
|
||||||
|
const view = e.get(HeroViewComp);
|
||||||
|
for (const effect of triggered) {
|
||||||
|
this.applyIntervalEffect(attrs, view, effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private applyIntervalEffect(attrs: HeroAttrsComp, view: HeroViewComp | null, effect: IntervalBuffState) {
|
||||||
|
if (effect.attr === Attrs.hp) {
|
||||||
|
const oldHp = attrs.hp;
|
||||||
|
attrs.add_hp(effect.value, true);
|
||||||
|
const delta = attrs.hp - oldHp;
|
||||||
|
if (view && delta !== 0) {
|
||||||
|
view.playIntervalEffect(effect.attr, delta, effect.sourceUuid);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (effect.attr === Attrs.shield) {
|
||||||
|
const oldShield = attrs.shield;
|
||||||
|
attrs.add_shield(effect.value, true);
|
||||||
|
const delta = attrs.shield - oldShield;
|
||||||
|
if (view && delta !== 0) {
|
||||||
|
view.playIntervalEffect(effect.attr, delta, effect.sourceUuid);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
attrs.applyStoredEffect(effect.attr, effect.value, effect.BType);
|
||||||
|
if (view) {
|
||||||
|
view.playIntervalEffect(effect.attr, effect.value, effect.sourceUuid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { Tooltip } from "../skill/Tooltip";
|
|||||||
import { timedCom } from "../skill/timedCom";
|
import { timedCom } from "../skill/timedCom";
|
||||||
import { HeroInfo, HType } from "../common/config/heroSet";
|
import { HeroInfo, HType } from "../common/config/heroSet";
|
||||||
import { Timer } from "db://oops-framework/core/common/timer/Timer";
|
import { Timer } from "db://oops-framework/core/common/timer/Timer";
|
||||||
|
import { Attrs } from "../common/config/HeroAttrs";
|
||||||
|
|
||||||
|
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
@@ -344,6 +345,36 @@ export class HeroViewComp extends CCComp {
|
|||||||
this.lastBarUpdateTime = Date.now() / 1000;
|
this.lastBarUpdateTime = Date.now() / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playIntervalEffect(attr: Attrs, value: number, s_uuid: number) {
|
||||||
|
if (!this.node || !this.node.isValid) return;
|
||||||
|
this.top_node.active = true;
|
||||||
|
this.lastBarUpdateTime = Date.now() / 1000;
|
||||||
|
if (attr === Attrs.hp) {
|
||||||
|
if (value > 0) {
|
||||||
|
this.heathed();
|
||||||
|
this.hp_tip(TooltipTypes.health, value.toFixed(0), s_uuid);
|
||||||
|
} else if (value < 0) {
|
||||||
|
this.in_atked("atked", this.model?.fac == FacSet.HERO ? 1 : -1);
|
||||||
|
this.hp_tip(TooltipTypes.life, Math.abs(value).toFixed(0), s_uuid);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (attr === Attrs.shield) {
|
||||||
|
if (this.model && this.model.shield > 0) {
|
||||||
|
this.show_shield(this.model.shield, this.model.shield_max);
|
||||||
|
}
|
||||||
|
this.hp_tip(TooltipTypes.health, Math.abs(value).toFixed(0), s_uuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (attr === Attrs.IN_FROST && value > 0) {
|
||||||
|
this.in_iced(0.3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (attr === Attrs.IN_STUN && value > 0) {
|
||||||
|
this.in_yun(0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
alive(){
|
alive(){
|
||||||
// 重置复活标记 - 必须最先重置,否则status_change会被拦截
|
// 重置复活标记 - 必须最先重置,否则status_change会被拦截
|
||||||
this.model.is_reviving = false;
|
this.model.is_reviving = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user