refactor(VictoryComp): 重构MVP英雄渲染逻辑
使用CardComp统一渲染MVP英雄,移除冗余的手动UI设置代码,修复了UI被覆盖的问题,同时禁用卡牌交互防止误操作
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
*
|
||||
|
||||
*/
|
||||
import { _decorator, instantiate, Label ,Prefab,Node, Sprite, Animation, AnimationClip, resources, UITransform, Widget, ProgressBar } from "cc";
|
||||
import { _decorator, instantiate, Label ,Prefab,Node, Sprite, Animation, AnimationClip, resources, UITransform, Widget, ProgressBar, Tween, NodeEventType } from "cc";
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||
@@ -13,7 +13,8 @@ import { GameEvent } from "../common/config/GameEvent";
|
||||
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||
import { FacSet } from "../common/config/GameSet";
|
||||
import { HeroInfo } from "../common/config/heroSet";
|
||||
import { CKind } from "../common/config/CardSet";
|
||||
import { CKind, CardType, CardLV, CardConfig } from "../common/config/CardSet";
|
||||
import { CardComp } from "./CardComp";
|
||||
import { HighlightSet, HighlightType, HighlightLevel } from "../common/config/HighlightSet";
|
||||
import { LangPrefix, lang, langf } from "../common/LangUtil";
|
||||
import { mLogger } from "../common/Logger";
|
||||
@@ -137,7 +138,7 @@ export class VictoryComp extends CCComp {
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 MVP 英雄,逻辑参考 CardComp 长按放大的 UI 显示
|
||||
* 渲染 MVP 英雄,使用绑定的 CardComp
|
||||
*/
|
||||
private renderMVPHero(mvp: HeroAttrsComp | null) {
|
||||
if (!this.mvp_node) return;
|
||||
@@ -153,185 +154,53 @@ export class VictoryComp extends CCComp {
|
||||
const hero = HeroInfo[uuid];
|
||||
if (!hero) return;
|
||||
|
||||
const kindName = CKind[CKind.Hero];
|
||||
|
||||
// 节点查找
|
||||
const BG_node = this.mvp_node.getChildByName("BG");
|
||||
const HF_node = this.mvp_node.getChildByName("HF");
|
||||
const NF_node = this.mvp_node.getChildByName("NF");
|
||||
const lv_node = this.mvp_node.getChildByName("lv");
|
||||
const name_node = this.mvp_node.getChildByName("name");
|
||||
const ap_node = this.mvp_node.getChildByName("ap");
|
||||
const hp_node = this.mvp_node.getChildByName("hp");
|
||||
const oinfo_node = this.mvp_node.getChildByName("oinfo");
|
||||
const icon_node = this.mvp_node.getChildByName("icon");
|
||||
const hbNode = this.mvp_node.getChildByName("HB");
|
||||
const cost_node = this.mvp_node.getChildByName("cost");
|
||||
// 延迟到下一帧执行,因为如果 mvp_node 刚被激活,Cocos 会在当前帧稍后/下一帧触发 CardComp 的 onLoad
|
||||
// 而 CardComp 的 onLoad 中调用了 applyEmptyUI() 会把卡面清空,导致我们的设置被覆盖。
|
||||
this.scheduleOnce(() => {
|
||||
if (!this.isValid || !this.mvp_node) return;
|
||||
|
||||
// ---- 背景与边框 ----
|
||||
if (BG_node) {
|
||||
BG_node.children.forEach(child => {
|
||||
child.active = (child.name === kindName);
|
||||
});
|
||||
}
|
||||
|
||||
if (HF_node) {
|
||||
HF_node.active = true;
|
||||
// HF_node.children.forEach(child => {
|
||||
// child.active = (child.name === kindName);
|
||||
// });
|
||||
}
|
||||
|
||||
if (NF_node) {
|
||||
NF_node.active = false;
|
||||
}
|
||||
|
||||
if (hbNode) hbNode.active = false;
|
||||
|
||||
// ---- 卡牌等级标识 ----
|
||||
const cardLvStr = `lv${mvp.base_pool_lv || mvp.pool_lv || 1}`;
|
||||
if (lv_node) {
|
||||
lv_node.children.forEach(child => {
|
||||
if (child.name === "light") {
|
||||
child.active = false;
|
||||
} else if (child.name === "bg") {
|
||||
child.active = true;
|
||||
} else {
|
||||
child.active = (child.name === cardLvStr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ---- 调整尺寸 (模拟放大状态) ----
|
||||
const isEnlarged = true; // 结算界面的卡牌默认处于放大显示状态
|
||||
const uiTrans = this.mvp_node.getComponent(UITransform);
|
||||
if (uiTrans) {
|
||||
uiTrans.setContentSize(isEnlarged ? 230 : 170, isEnlarged ? 340 : 230);
|
||||
const widget = this.mvp_node.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
|
||||
if (BG_node) {
|
||||
const bgTrans = BG_node.getComponent(UITransform);
|
||||
if (bgTrans) {
|
||||
bgTrans.setContentSize(isEnlarged ? 230 : 170, isEnlarged ? 340 : 230);
|
||||
const widget = BG_node.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
// 获取 CardComp 组件
|
||||
let cardComp = this.mvp_node.getComponent(CardComp);
|
||||
if (!cardComp) {
|
||||
cardComp = this.mvp_node.addComponent(CardComp);
|
||||
}
|
||||
BG_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) {
|
||||
childTrans.setContentSize(isEnlarged ? 230 : 170, isEnlarged ? 340 : 230);
|
||||
const widget = child.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (HF_node) {
|
||||
const hfTrans = HF_node.getComponent(UITransform);
|
||||
if (hfTrans) {
|
||||
hfTrans.setContentSize(isEnlarged ? 230 : 170, isEnlarged ? 340 : 230);
|
||||
const widget = HF_node.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
// 构造虚拟的 CardConfig 数据供渲染
|
||||
const cardConfig: CardConfig = {
|
||||
uuid: uuid,
|
||||
type: CardType.Hero,
|
||||
cost: 0,
|
||||
weight: 0,
|
||||
kind: CKind.Hero,
|
||||
pool_lv: mvp.pool_lv || CardLV.LV1,
|
||||
hero_lv: mvp.lv || 1,
|
||||
base_pool_lv: mvp.base_pool_lv || mvp.pool_lv || 1,
|
||||
};
|
||||
|
||||
const originalPos = this.mvp_node.position.clone();
|
||||
|
||||
// 禁用交互事件,防止结算界面的卡牌被拖拽或点击
|
||||
this.mvp_node.off(NodeEventType.TOUCH_START);
|
||||
this.mvp_node.off(NodeEventType.TOUCH_MOVE);
|
||||
this.mvp_node.off(NodeEventType.TOUCH_END);
|
||||
this.mvp_node.off(NodeEventType.TOUCH_CANCEL);
|
||||
if (cardComp.Lock) cardComp.Lock.off(NodeEventType.TOUCH_END);
|
||||
if (cardComp.unLock) cardComp.unLock.off(NodeEventType.TOUCH_END);
|
||||
|
||||
// 应用数据并刷新UI
|
||||
cardComp.applyDrawCard(cardConfig);
|
||||
|
||||
// 隐藏不必要的信息(比如费用)
|
||||
if (cardComp.cost_node) {
|
||||
cardComp.cost_node.active = false;
|
||||
}
|
||||
HF_node.children.forEach(child => {
|
||||
const childTrans = child.getComponent(UITransform);
|
||||
if (childTrans) {
|
||||
childTrans.setContentSize(isEnlarged ? 230 : 170, isEnlarged ? 340 : 230);
|
||||
const widget = child.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.mvp_node.children.forEach(child => {
|
||||
const widget = child.getComponent(Widget);
|
||||
if (widget) widget.updateAlignment();
|
||||
child.children.forEach(subChild => {
|
||||
const subWidget = subChild.getComponent(Widget);
|
||||
if (subWidget) subWidget.updateAlignment();
|
||||
});
|
||||
});
|
||||
|
||||
// ---- 文本信息 ----
|
||||
const heroLv = mvp.lv || 1;
|
||||
const suffix = heroLv >= 2 ? "★".repeat(heroLv - 1) : "";
|
||||
if (name_node) {
|
||||
const label = name_node.getComponent(Label);
|
||||
if (label) label.string = `${suffix}${hero.name || ""}${suffix}`;
|
||||
const currentPos = name_node.position;
|
||||
name_node.setPosition(currentPos.x, isEnlarged ? 8 : -70, currentPos.z);
|
||||
}
|
||||
|
||||
if (ap_node) {
|
||||
ap_node.active = true;
|
||||
const valNode = ap_node.getChildByName("val");
|
||||
if (valNode) {
|
||||
const label = valNode.getComponent(Label);
|
||||
if (label) label.string = `${Math.floor(mvp.ap)}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (hp_node) {
|
||||
hp_node.active = true;
|
||||
const valNode = hp_node.getChildByName("val");
|
||||
if (valNode) {
|
||||
const label = valNode.getComponent(Label);
|
||||
if (label) label.string = `${Math.floor(mvp.hp_max)}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (oinfo_node) {
|
||||
oinfo_node.active = isEnlarged;
|
||||
const infoLabel = oinfo_node.getChildByName("info")?.getComponent(Label);
|
||||
if (infoLabel) infoLabel.string = `${hero.info || ""}`;
|
||||
}
|
||||
|
||||
if (cost_node) {
|
||||
cost_node.active = false; // 结算时不显示金币费用
|
||||
}
|
||||
|
||||
// ---- 图标动画 ----
|
||||
if (icon_node) {
|
||||
this.updateHeroAnimation(icon_node, uuid);
|
||||
}
|
||||
}
|
||||
|
||||
private updateHeroAnimation(node: Node, uuid: number) {
|
||||
const sprite = node.getComponent(Sprite) || node.getComponentInChildren(Sprite);
|
||||
if (sprite) sprite.spriteFrame = null;
|
||||
|
||||
const hero = HeroInfo[uuid];
|
||||
if (!hero) return;
|
||||
|
||||
const anim = node.getComponent(Animation) || node.addComponent(Animation);
|
||||
|
||||
// clear animation clips
|
||||
const clips = anim.clips;
|
||||
for (let i = clips.length - 1; i >= 0; i--) {
|
||||
const clip = clips[i];
|
||||
if (clip) anim.removeClip(clip);
|
||||
}
|
||||
|
||||
const path = `game/heros/hero/${hero.path}/idle`;
|
||||
resources.load(path, AnimationClip, (err, clip) => {
|
||||
if (err || !clip) {
|
||||
mLogger.log(this.debugMode, "VictoryComp", `load hero animation failed ${uuid}`, err);
|
||||
return;
|
||||
}
|
||||
// avoid state conflict
|
||||
if (!this.node.isValid || !this.mvp_node || !this.mvp_node.active) return;
|
||||
|
||||
const currentClips = anim.clips;
|
||||
for (let i = currentClips.length - 1; i >= 0; i--) {
|
||||
const c = currentClips[i];
|
||||
if (c) anim.removeClip(c);
|
||||
}
|
||||
|
||||
anim.addClip(clip);
|
||||
anim.play("idle");
|
||||
});
|
||||
// 覆盖 CardComp 内部动画的 scale,停止其上的 tween,并直接放大
|
||||
// 结算界面的卡牌需要放大显示,170 * 1.35 ≈ 230
|
||||
Tween.stopAllByTarget(this.mvp_node);
|
||||
this.mvp_node.setPosition(originalPos);
|
||||
this.mvp_node.setScale(1.35, 1.35, 1);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user