feat(ui): 添加战场英雄信息面板并增强主角召唤事件
扩展主角召唤事件,传递更多实体信息供UI系统使用。新增HInfoComp组件作为英雄信息面板基础,并在MissionCardComp中动态生成和管理英雄信息面板,实时显示英雄属性。同时调整相关预制体引用和布局配置。
This commit is contained in:
@@ -35,10 +35,13 @@
|
|||||||
"_components": [
|
"_components": [
|
||||||
{
|
{
|
||||||
"__id__": 74
|
"__id__": 74
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__id__": 76
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_prefab": {
|
"_prefab": {
|
||||||
"__id__": 76
|
"__id__": 78
|
||||||
},
|
},
|
||||||
"_lpos": {
|
"_lpos": {
|
||||||
"__type__": "cc.Vec3",
|
"__type__": "cc.Vec3",
|
||||||
@@ -1733,6 +1736,24 @@
|
|||||||
"__type__": "cc.CompPrefabInfo",
|
"__type__": "cc.CompPrefabInfo",
|
||||||
"fileId": "9c8CWaboJEQ4tagNhw+LQr"
|
"fileId": "9c8CWaboJEQ4tagNhw+LQr"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"__type__": "a832fh9yR9LJK1kR+tZ1lin",
|
||||||
|
"_name": "",
|
||||||
|
"_objFlags": 0,
|
||||||
|
"__editorExtras__": {},
|
||||||
|
"node": {
|
||||||
|
"__id__": 1
|
||||||
|
},
|
||||||
|
"_enabled": true,
|
||||||
|
"__prefab": {
|
||||||
|
"__id__": 77
|
||||||
|
},
|
||||||
|
"_id": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"__type__": "cc.CompPrefabInfo",
|
||||||
|
"fileId": "11S1XoDG5Ndo+S7MbRH4us"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInfo",
|
"__type__": "cc.PrefabInfo",
|
||||||
"root": {
|
"root": {
|
||||||
|
|||||||
@@ -778,7 +778,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInstance",
|
"__type__": "cc.PrefabInstance",
|
||||||
"fileId": "8el1xtaIhFn4eJMCp78t65",
|
"fileId": "b1fQvsJE5Axp3W57Iu81HO",
|
||||||
"prefabRootNode": {
|
"prefabRootNode": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
@@ -890,7 +890,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInstance",
|
"__type__": "cc.PrefabInstance",
|
||||||
"fileId": "f2Vo21jDdPfbsPEDATg/6w",
|
"fileId": "24ho6yMw5OyKqGnnlb1lZe",
|
||||||
"prefabRootNode": {
|
"prefabRootNode": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
@@ -920,7 +920,7 @@
|
|||||||
"propertyPath": [
|
"propertyPath": [
|
||||||
"_name"
|
"_name"
|
||||||
],
|
],
|
||||||
"value": "hnode-001"
|
"value": "hnode"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.TargetInfo",
|
"__type__": "cc.TargetInfo",
|
||||||
@@ -1002,7 +1002,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInstance",
|
"__type__": "cc.PrefabInstance",
|
||||||
"fileId": "95i/033cdI1ar3RE/LeAFh",
|
"fileId": "bf9CO3VXpEapXp0MM4jeGj",
|
||||||
"prefabRootNode": {
|
"prefabRootNode": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
@@ -1032,7 +1032,7 @@
|
|||||||
"propertyPath": [
|
"propertyPath": [
|
||||||
"_name"
|
"_name"
|
||||||
],
|
],
|
||||||
"value": "hnode-002"
|
"value": "hnode"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.TargetInfo",
|
"__type__": "cc.TargetInfo",
|
||||||
@@ -1114,7 +1114,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInstance",
|
"__type__": "cc.PrefabInstance",
|
||||||
"fileId": "96aOqwbNZC2554Tb3MVHAi",
|
"fileId": "cbhqcW/7BHOIfs5h+tuWvE",
|
||||||
"prefabRootNode": {
|
"prefabRootNode": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
@@ -1144,7 +1144,7 @@
|
|||||||
"propertyPath": [
|
"propertyPath": [
|
||||||
"_name"
|
"_name"
|
||||||
],
|
],
|
||||||
"value": "hnode-003"
|
"value": "hnode"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.TargetInfo",
|
"__type__": "cc.TargetInfo",
|
||||||
@@ -1226,7 +1226,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInstance",
|
"__type__": "cc.PrefabInstance",
|
||||||
"fileId": "82lTFZokVJ1YXiKvnc7dBe",
|
"fileId": "f9xptjk/hA+IJ5/9k6XxMX",
|
||||||
"prefabRootNode": {
|
"prefabRootNode": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
@@ -1256,7 +1256,7 @@
|
|||||||
"propertyPath": [
|
"propertyPath": [
|
||||||
"_name"
|
"_name"
|
||||||
],
|
],
|
||||||
"value": "hnode-004"
|
"value": "hnode"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.TargetInfo",
|
"__type__": "cc.TargetInfo",
|
||||||
@@ -1338,7 +1338,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.PrefabInstance",
|
"__type__": "cc.PrefabInstance",
|
||||||
"fileId": "27cEJ94ONNHKT7mJlaxtlG",
|
"fileId": "b9NtsF98ZKrpqsdLUl8ouf",
|
||||||
"prefabRootNode": {
|
"prefabRootNode": {
|
||||||
"__id__": 1
|
"__id__": 1
|
||||||
},
|
},
|
||||||
@@ -1368,7 +1368,7 @@
|
|||||||
"propertyPath": [
|
"propertyPath": [
|
||||||
"_name"
|
"_name"
|
||||||
],
|
],
|
||||||
"value": "hnode-005"
|
"value": "hnode"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"__type__": "cc.TargetInfo",
|
"__type__": "cc.TargetInfo",
|
||||||
@@ -1517,7 +1517,7 @@
|
|||||||
"_constraint": 0,
|
"_constraint": 0,
|
||||||
"_constraintNum": 2,
|
"_constraintNum": 2,
|
||||||
"_affectedByScale": false,
|
"_affectedByScale": false,
|
||||||
"_isAlign": false,
|
"_isAlign": true,
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -11461,7 +11461,10 @@
|
|||||||
"hero_info_node": {
|
"hero_info_node": {
|
||||||
"__id__": 24
|
"__id__": 24
|
||||||
},
|
},
|
||||||
"hero_info_prefab": null,
|
"hero_info_prefab": {
|
||||||
|
"__uuid__": "46f1e2cb-6fa7-4e9e-b419-e424ba47fe68",
|
||||||
|
"__expectedType__": "cc.Prefab"
|
||||||
|
},
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -11833,7 +11836,7 @@
|
|||||||
"node": {
|
"node": {
|
||||||
"__id__": 560
|
"__id__": 560
|
||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": false,
|
||||||
"__prefab": {
|
"__prefab": {
|
||||||
"__id__": 572
|
"__id__": 572
|
||||||
},
|
},
|
||||||
@@ -11847,10 +11850,7 @@
|
|||||||
"b": 255,
|
"b": 255,
|
||||||
"a": 255
|
"a": 255
|
||||||
},
|
},
|
||||||
"_spriteFrame": {
|
"_spriteFrame": null,
|
||||||
"__uuid__": "deedea09-8f2b-400f-9803-4cfd38e45d1a@58cb7",
|
|
||||||
"__expectedType__": "cc.SpriteFrame"
|
|
||||||
},
|
|
||||||
"_type": 1,
|
"_type": 1,
|
||||||
"_fillType": 0,
|
"_fillType": 0,
|
||||||
"_sizeMode": 0,
|
"_sizeMode": 0,
|
||||||
@@ -11863,10 +11863,7 @@
|
|||||||
"_fillRange": 0,
|
"_fillRange": 0,
|
||||||
"_isTrimmedMode": true,
|
"_isTrimmedMode": true,
|
||||||
"_useGrayscale": false,
|
"_useGrayscale": false,
|
||||||
"_atlas": {
|
"_atlas": null,
|
||||||
"__uuid__": "deedea09-8f2b-400f-9803-4cfd38e45d1a",
|
|
||||||
"__expectedType__": "cc.SpriteAtlas"
|
|
||||||
},
|
|
||||||
"_id": ""
|
"_id": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -113,7 +113,12 @@ export class Hero extends ecs.Entity {
|
|||||||
this.add(hv);
|
this.add(hv);
|
||||||
hv.init();
|
hv.init();
|
||||||
// 广播主角召唤事件,触发外部系统监听逻辑
|
// 广播主角召唤事件,触发外部系统监听逻辑
|
||||||
oops.message.dispatchEvent(GameEvent.MasterCalled,{uuid:uuid})
|
oops.message.dispatchEvent(GameEvent.MasterCalled, {
|
||||||
|
eid: this.eid,
|
||||||
|
uuid,
|
||||||
|
hero_lv,
|
||||||
|
model
|
||||||
|
})
|
||||||
|
|
||||||
// 初始化移动组件:方向、目标 X、站位基准 Y
|
// 初始化移动组件:方向、目标 X、站位基准 Y
|
||||||
const move = this.get(MoveComp);
|
const move = this.get(MoveComp);
|
||||||
|
|||||||
20
assets/script/game/map/HInfoComp.ts
Normal file
20
assets/script/game/map/HInfoComp.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { mLogger } from "../common/Logger";
|
||||||
|
import { _decorator, Animation, AnimationClip, EventTouch, Label, Node, NodeEventType, Sprite, SpriteAtlas, Tween, tween, UIOpacity, Vec3, resources } from "cc";
|
||||||
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
|
|
||||||
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
|
/** 视图层对象 */
|
||||||
|
@ccclass('HInfoComp')
|
||||||
|
@ecs.register('HInfoComp', false)
|
||||||
|
export class HInfoComp extends CCComp {
|
||||||
|
private debugMode: boolean = true;
|
||||||
|
/** 锁定态图标节点(显示时表示本槽位锁定) */
|
||||||
|
|
||||||
|
|
||||||
|
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
||||||
|
reset() {
|
||||||
|
this.node.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
9
assets/script/game/map/HInfoComp.ts.meta
Normal file
9
assets/script/game/map/HInfoComp.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "a832f87d-c91f-4b24-ad64-47eb59d658a7",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { _decorator, Label, Node, NodeEventType, Prefab, SpriteAtlas, Tween, tween, Vec3 } from "cc";
|
import { _decorator, instantiate, Label, Node, NodeEventType, Prefab, SpriteAtlas, Tween, tween, Vec3 } from "cc";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
@@ -7,6 +7,7 @@ import { CARD_POOL_INIT_LEVEL, CARD_POOL_MAX_LEVEL, CardConfig, CardInitCoins, C
|
|||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
import { CardComp } from "./CardComp";
|
import { CardComp } from "./CardComp";
|
||||||
import { oops } from "db://oops-framework/core/Oops";
|
import { oops } from "db://oops-framework/core/Oops";
|
||||||
|
import { HeroAttrsComp } from "../hero/HeroAttrsComp";
|
||||||
|
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
@@ -38,9 +39,9 @@ export class MissionCardComp extends CCComp {
|
|||||||
@property(Node)
|
@property(Node)
|
||||||
pool_lv_node:Node = null!
|
pool_lv_node:Node = null!
|
||||||
@property(Node)
|
@property(Node)
|
||||||
hero_info_node:Node = null!
|
hero_info_node:Node = null! //场上英雄信息面板所在节点
|
||||||
@property(Prefab)
|
@property(Prefab)
|
||||||
hero_info_prefab:Prefab=null!
|
hero_info_prefab:Prefab=null! //场上英雄信息面板Prefab
|
||||||
/** 预留图集缓存(后续接入按钮/卡面图标时复用) */
|
/** 预留图集缓存(后续接入按钮/卡面图标时复用) */
|
||||||
private uiconsAtlas: SpriteAtlas | null = null;
|
private uiconsAtlas: SpriteAtlas | null = null;
|
||||||
/** 四个槽位对应的单卡控制器缓存 */
|
/** 四个槽位对应的单卡控制器缓存 */
|
||||||
@@ -48,6 +49,14 @@ export class MissionCardComp extends CCComp {
|
|||||||
/** 当前卡池等级(仅影响抽卡来源,不直接改卡槽现有内容) */
|
/** 当前卡池等级(仅影响抽卡来源,不直接改卡槽现有内容) */
|
||||||
private poolLv: number = CARD_POOL_INIT_LEVEL;
|
private poolLv: number = CARD_POOL_INIT_LEVEL;
|
||||||
private coin: number = CardInitCoins;
|
private coin: number = CardInitCoins;
|
||||||
|
private readonly heroInfoItemGap: number = 86;
|
||||||
|
private heroInfoSyncTimer: number = 0;
|
||||||
|
private heroInfoItems: Map<number, {
|
||||||
|
node: Node,
|
||||||
|
model: HeroAttrsComp,
|
||||||
|
apLabel: Label | null,
|
||||||
|
hpLabel: Label | null
|
||||||
|
}> = new Map();
|
||||||
onLoad() {
|
onLoad() {
|
||||||
/** 绑定事件 -> 缓存子控制器 -> 初始化UI状态 */
|
/** 绑定事件 -> 缓存子控制器 -> 初始化UI状态 */
|
||||||
this.bindEvents();
|
this.bindEvents();
|
||||||
@@ -62,6 +71,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
|
|
||||||
onDestroy() {
|
onDestroy() {
|
||||||
this.unbindEvents();
|
this.unbindEvents();
|
||||||
|
this.clearHeroInfoPanels();
|
||||||
}
|
}
|
||||||
init(){
|
init(){
|
||||||
this.onMissionStart();
|
this.onMissionStart();
|
||||||
@@ -71,6 +81,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
onMissionStart() {
|
onMissionStart() {
|
||||||
this.poolLv = CARD_POOL_INIT_LEVEL;
|
this.poolLv = CARD_POOL_INIT_LEVEL;
|
||||||
this.coin = CardInitCoins
|
this.coin = CardInitCoins
|
||||||
|
this.clearHeroInfoPanels();
|
||||||
this.layoutCardSlots();
|
this.layoutCardSlots();
|
||||||
this.clearAllCards();
|
this.clearAllCards();
|
||||||
if (this.cards_up) {
|
if (this.cards_up) {
|
||||||
@@ -91,12 +102,18 @@ export class MissionCardComp extends CCComp {
|
|||||||
/** 任务结束时:清空4槽并隐藏面板 */
|
/** 任务结束时:清空4槽并隐藏面板 */
|
||||||
onMissionEnd() {
|
onMissionEnd() {
|
||||||
this.clearAllCards();
|
this.clearAllCards();
|
||||||
|
this.clearHeroInfoPanels();
|
||||||
this.node.active = false;
|
this.node.active = false;
|
||||||
}
|
}
|
||||||
start() {
|
start() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(dt: number) {
|
||||||
|
this.heroInfoSyncTimer += dt;
|
||||||
|
if (this.heroInfoSyncTimer < 0.15) return;
|
||||||
|
this.heroInfoSyncTimer = 0;
|
||||||
|
this.refreshHeroInfoPanels();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -111,6 +128,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
this.on(GameEvent.MissionStart, this.onMissionStart, this);
|
this.on(GameEvent.MissionStart, this.onMissionStart, this);
|
||||||
this.on(GameEvent.MissionEnd, this.onMissionEnd, this);
|
this.on(GameEvent.MissionEnd, this.onMissionEnd, this);
|
||||||
this.on(GameEvent.CoinAdd, this.onCoinAdd, this);
|
this.on(GameEvent.CoinAdd, this.onCoinAdd, this);
|
||||||
|
oops.message.on(GameEvent.MasterCalled, this.onMasterCalled, this);
|
||||||
|
|
||||||
/** 按钮事件:抽卡与卡池升级 */
|
/** 按钮事件:抽卡与卡池升级 */
|
||||||
this.cards_chou?.on(NodeEventType.TOUCH_START, this.onDrawTouchStart, this);
|
this.cards_chou?.on(NodeEventType.TOUCH_START, this.onDrawTouchStart, this);
|
||||||
@@ -129,6 +147,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
|
|
||||||
/** 解除按钮监听,避免节点销毁后回调泄漏 */
|
/** 解除按钮监听,避免节点销毁后回调泄漏 */
|
||||||
private unbindEvents() {
|
private unbindEvents() {
|
||||||
|
oops.message.off(GameEvent.MasterCalled, this.onMasterCalled, this);
|
||||||
this.cards_chou?.off(NodeEventType.TOUCH_START, this.onDrawTouchStart, this);
|
this.cards_chou?.off(NodeEventType.TOUCH_START, this.onDrawTouchStart, this);
|
||||||
this.cards_chou?.off(NodeEventType.TOUCH_END, this.onDrawTouchEnd, this);
|
this.cards_chou?.off(NodeEventType.TOUCH_END, this.onDrawTouchEnd, this);
|
||||||
this.cards_chou?.off(NodeEventType.TOUCH_CANCEL, this.onDrawTouchCancel, this);
|
this.cards_chou?.off(NodeEventType.TOUCH_CANCEL, this.onDrawTouchCancel, this);
|
||||||
@@ -137,6 +156,14 @@ export class MissionCardComp extends CCComp {
|
|||||||
this.cards_up?.off(NodeEventType.TOUCH_CANCEL, this.onUpgradeTouchCancel, this);
|
this.cards_up?.off(NodeEventType.TOUCH_CANCEL, this.onUpgradeTouchCancel, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onMasterCalled(event: string, args: any) {
|
||||||
|
const payload = args ?? event;
|
||||||
|
const eid = Number(payload?.eid ?? 0);
|
||||||
|
const model = payload?.model as HeroAttrsComp | undefined;
|
||||||
|
if (!eid || !model) return;
|
||||||
|
this.ensureHeroInfoPanel(eid, model);
|
||||||
|
}
|
||||||
|
|
||||||
private onDrawTouchStart() {
|
private onDrawTouchStart() {
|
||||||
this.playButtonPressAnim(this.cards_chou);
|
this.playButtonPressAnim(this.cards_chou);
|
||||||
}
|
}
|
||||||
@@ -339,8 +366,110 @@ export class MissionCardComp extends CCComp {
|
|||||||
return CardsUpSet[lv] ?? 0;
|
return CardsUpSet[lv] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ensureHeroInfoPanel(eid: number, model: HeroAttrsComp) {
|
||||||
|
if (!this.hero_info_node || !this.hero_info_prefab) return;
|
||||||
|
this.hero_info_node.active = true;
|
||||||
|
const current = this.heroInfoItems.get(eid);
|
||||||
|
if (current) {
|
||||||
|
current.model = model;
|
||||||
|
this.updateHeroInfoPanel(current);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const node = instantiate(this.hero_info_prefab);
|
||||||
|
node.parent = this.hero_info_node;
|
||||||
|
node.active = true;
|
||||||
|
const item = {
|
||||||
|
node,
|
||||||
|
model,
|
||||||
|
apLabel: this.resolvePanelLabel(node, [["ap", "val"]]),
|
||||||
|
hpLabel: this.resolvePanelLabel(node, [["hp", "val"]])
|
||||||
|
};
|
||||||
|
this.heroInfoItems.set(eid, item);
|
||||||
|
this.relayoutHeroInfoPanels();
|
||||||
|
this.updateHeroInfoPanel(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private refreshHeroInfoPanels() {
|
||||||
|
const removeKeys: number[] = [];
|
||||||
|
this.heroInfoItems.forEach((item, eid) => {
|
||||||
|
if (!item.node || !item.node.isValid) {
|
||||||
|
removeKeys.push(eid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ent = (item.model as any)?.ent;
|
||||||
|
if (!ent) {
|
||||||
|
if (item.node.isValid) item.node.destroy();
|
||||||
|
removeKeys.push(eid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.updateHeroInfoPanel(item);
|
||||||
|
});
|
||||||
|
for (let i = 0; i < removeKeys.length; i++) {
|
||||||
|
this.heroInfoItems.delete(removeKeys[i]);
|
||||||
|
}
|
||||||
|
if (removeKeys.length > 0) {
|
||||||
|
this.relayoutHeroInfoPanels();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateHeroInfoPanel(item: {
|
||||||
|
node: Node,
|
||||||
|
model: HeroAttrsComp,
|
||||||
|
apLabel: Label | null,
|
||||||
|
hpLabel: Label | null
|
||||||
|
}) {
|
||||||
|
if (item.apLabel) item.apLabel.string = `${Math.max(0, Math.floor(item.model.ap ?? 0))}`;
|
||||||
|
if (item.hpLabel) item.hpLabel.string = `${Math.max(0, Math.floor(item.model.hp_max ?? 0))}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private relayoutHeroInfoPanels() {
|
||||||
|
let index = 0;
|
||||||
|
this.heroInfoItems.forEach(item => {
|
||||||
|
if (!item.node || !item.node.isValid) return;
|
||||||
|
const pos = item.node.position;
|
||||||
|
item.node.setPosition(pos.x, -index * this.heroInfoItemGap, pos.z);
|
||||||
|
index += 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private clearHeroInfoPanels() {
|
||||||
|
this.heroInfoItems.forEach(item => {
|
||||||
|
if (item.node && item.node.isValid) {
|
||||||
|
item.node.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.heroInfoItems.clear();
|
||||||
|
if (this.hero_info_node && this.hero_info_node.isValid) {
|
||||||
|
for (let i = this.hero_info_node.children.length - 1; i >= 0; i--) {
|
||||||
|
const child = this.hero_info_node.children[i];
|
||||||
|
if (child && child.isValid) child.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.heroInfoSyncTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private resolvePanelLabel(root: Node, paths: string[][]): Label | null {
|
||||||
|
for (let i = 0; i < paths.length; i++) {
|
||||||
|
const node = this.findNodeByPath(root, paths[i]);
|
||||||
|
if (!node) continue;
|
||||||
|
const label = node.getComponent(Label) || node.getComponentInChildren(Label);
|
||||||
|
if (label) return label;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private findNodeByPath(root: Node, path: string[]): Node | null {
|
||||||
|
let current: Node | null = root;
|
||||||
|
for (let i = 0; i < path.length; i++) {
|
||||||
|
current = current?.getChildByName(path[i]) ?? null;
|
||||||
|
if (!current) return null;
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
||||||
reset() {
|
reset() {
|
||||||
|
this.clearHeroInfoPanels();
|
||||||
this.resetButtonScale(this.cards_chou);
|
this.resetButtonScale(this.cards_chou);
|
||||||
this.resetButtonScale(this.cards_up);
|
this.resetButtonScale(this.cards_up);
|
||||||
this.node.destroy();
|
this.node.destroy();
|
||||||
|
|||||||
Reference in New Issue
Block a user