Compare commits
3 Commits
b578e17186
...
8f65282af7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f65282af7 | ||
|
|
254b7f3e9e | ||
|
|
626d27e676 |
File diff suppressed because it is too large
Load Diff
@@ -150,6 +150,8 @@ export class MissionCardComp extends CCComp {
|
|||||||
model: HeroAttrsComp,
|
model: HeroAttrsComp,
|
||||||
comp: HInfoComp
|
comp: HInfoComp
|
||||||
}> = new Map();
|
}> = new Map();
|
||||||
|
/** 缓存预先放置的 6 个 HInfoComp */
|
||||||
|
private cachedHInfoComps: Map<number, HInfoComp> = new Map();
|
||||||
// ======================== 生命周期 ========================
|
// ======================== 生命周期 ========================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -161,6 +163,7 @@ export class MissionCardComp extends CCComp {
|
|||||||
* 5. 触发首次任务开始流程。
|
* 5. 触发首次任务开始流程。
|
||||||
*/
|
*/
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
this.cacheHInfoComps();
|
||||||
this.bindEvents();
|
this.bindEvents();
|
||||||
this.cacheCardComps();
|
this.cacheCardComps();
|
||||||
this.layoutCardSlots();
|
this.layoutCardSlots();
|
||||||
@@ -171,6 +174,19 @@ export class MissionCardComp extends CCComp {
|
|||||||
poolLv: this.poolLv
|
poolLv: this.poolLv
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private cacheHInfoComps() {
|
||||||
|
this.cachedHInfoComps.clear();
|
||||||
|
if (!this.hero_info_node) return;
|
||||||
|
for (let i = 0; i < this.hero_info_node.children.length; i++) {
|
||||||
|
const child = this.hero_info_node.children[i];
|
||||||
|
const comp = (child.getComponent(HInfoComp) || child.getComponent("HInfoComp")) as HInfoComp;
|
||||||
|
if (comp && comp.node_index > 0) {
|
||||||
|
this.cachedHInfoComps.set(comp.node_index, comp);
|
||||||
|
child.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 组件销毁时解绑所有事件并清理英雄信息面板 */
|
/** 组件销毁时解绑所有事件并清理英雄信息面板 */
|
||||||
onDestroy() {
|
onDestroy() {
|
||||||
@@ -880,48 +896,61 @@ export class MissionCardComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ensureHeroInfoPanel(eid: number, model: HeroAttrsComp) {
|
private ensureHeroInfoPanel(eid: number, model: HeroAttrsComp) {
|
||||||
if (!this.hero_info_node || !this.hero_info_prefab) {
|
if (!this.hero_info_node) {
|
||||||
mLogger.error(this.debugMode, "MissionCardComp", "ensureHeroInfoPanel: missing hero_info_node or hero_info_prefab");
|
mLogger.error(this.debugMode, "MissionCardComp", "ensureHeroInfoPanel: missing hero_info_node");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.hero_info_node.active = true;
|
|
||||||
|
// MoveComp.ts 里的 assignment:
|
||||||
|
// lanePriority = [1, 0, 2]; // slotIndex 0->中路(1), 1->上路(0), 2->下路(2)
|
||||||
|
// laneIdx = lanePriority[slotIndex % 3];
|
||||||
|
// col = Math.floor(slotIndex / 3);
|
||||||
|
// model.lane = laneIdx;
|
||||||
|
// model.lane_index = col;
|
||||||
|
//
|
||||||
|
// 节点顺序预期:
|
||||||
|
// node_index=1 对应 1排上路 (lane=0, lane_index=0)
|
||||||
|
// node_index=2 对应 1排中路 (lane=1, lane_index=0)
|
||||||
|
// node_index=3 对应 1排下路 (lane=2, lane_index=0)
|
||||||
|
// node_index=4 对应 2排上路 (lane=0, lane_index=1)
|
||||||
|
// node_index=5 对应 2排中路 (lane=1, lane_index=1)
|
||||||
|
// node_index=6 对应 2排下路 (lane=2, lane_index=1)
|
||||||
|
// 因为 1排中路 在视觉上是最前面的,实际按路排(上/中/下):
|
||||||
|
const laneOrder = model.lane === 0 ? 0 : (model.lane === 1 ? 1 : 2);
|
||||||
|
const expectedNodeIndex = model.lane_index * 3 + laneOrder + 1;
|
||||||
|
|
||||||
|
mLogger.log(this.debugMode, "MissionCardComp", `ensureHeroInfoPanel calculation: lane=${model.lane}, lane_index=${model.lane_index} -> expectedNodeIndex=${expectedNodeIndex}`);
|
||||||
|
|
||||||
|
const comp = this.cachedHInfoComps.get(expectedNodeIndex);
|
||||||
|
|
||||||
|
if (!comp) {
|
||||||
|
mLogger.error(this.debugMode, "MissionCardComp", `ensureHeroInfoPanel: missing pre-placed HInfoComp for index ${expectedNodeIndex}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const current = this.heroInfoItems.get(eid);
|
const current = this.heroInfoItems.get(eid);
|
||||||
if (current) {
|
if (current) {
|
||||||
current.model = model;
|
current.model = model;
|
||||||
current.comp.bindData(eid, model);
|
current.comp = comp;
|
||||||
|
current.node = comp.node;
|
||||||
|
comp.node.active = true;
|
||||||
|
comp.bindData(eid, model);
|
||||||
this.updateHeroInfoPanel(current);
|
this.updateHeroInfoPanel(current);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLogger.log(this.debugMode, "MissionCardComp", "ensureHeroInfoPanel: creating new panel for eid", eid);
|
comp.node.active = true;
|
||||||
const node = instantiate(this.hero_info_prefab);
|
|
||||||
node.parent = this.hero_info_node;
|
|
||||||
node.active = true;
|
|
||||||
|
|
||||||
// 尝试两种方式获取组件,并输出日志
|
|
||||||
let comp = node.getComponent(HInfoComp) as any;
|
|
||||||
if (!comp) {
|
|
||||||
comp = node.getComponent("HInfoComp") as any;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!comp) {
|
|
||||||
mLogger.error(this.debugMode, "MissionCardComp", "ensureHeroInfoPanel: Failed to get HInfoComp from prefab!");
|
|
||||||
node.destroy();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const item = {
|
const item = {
|
||||||
node,
|
node: comp.node,
|
||||||
model,
|
model,
|
||||||
comp
|
comp
|
||||||
};
|
};
|
||||||
comp.bindData(eid, model);
|
comp.bindData(eid, model);
|
||||||
comp.setBattlePhase(this.isBattlePhase);
|
comp.setBattlePhase(this.isBattlePhase);
|
||||||
this.heroInfoItems.set(eid, item);
|
this.heroInfoItems.set(eid, item);
|
||||||
this.relayoutHeroInfoPanels();
|
|
||||||
this.updateHeroInfoPanel(item);
|
this.updateHeroInfoPanel(item);
|
||||||
|
|
||||||
mLogger.log(this.debugMode, "MissionCardComp", `ensureHeroInfoPanel: new panel created for eid ${eid}, final position:`, item.node.position);
|
mLogger.log(this.debugMode, "MissionCardComp", `ensureHeroInfoPanel: updated panel for eid ${eid} at node_index ${expectedNodeIndex}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
private refreshHeroInfoPanels() {
|
private refreshHeroInfoPanels() {
|
||||||
@@ -932,16 +961,36 @@ export class MissionCardComp extends CCComp {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!item.comp.isModelAlive()) {
|
if (!item.comp.isModelAlive()) {
|
||||||
if (item.node.isValid) item.node.destroy();
|
if (item.node.isValid) item.node.active = false;
|
||||||
removeKeys.push(eid);
|
removeKeys.push(eid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查英雄是否改变了位置 (lane 或 lane_index 发生了变化)
|
||||||
|
const laneOrder = item.model.lane === 0 ? 0 : (item.model.lane === 1 ? 1 : 2);
|
||||||
|
const expectedNodeIndex = item.model.lane_index * 3 + laneOrder + 1;
|
||||||
|
|
||||||
|
if (item.comp.node_index !== expectedNodeIndex) {
|
||||||
|
// 如果位置变了,需要转移到新的节点上
|
||||||
|
const newComp = this.cachedHInfoComps.get(expectedNodeIndex);
|
||||||
|
if (newComp) {
|
||||||
|
// 隐藏旧节点
|
||||||
|
item.node.active = false;
|
||||||
|
|
||||||
|
// 转移到新节点
|
||||||
|
item.comp = newComp;
|
||||||
|
item.node = newComp.node;
|
||||||
|
item.node.active = true;
|
||||||
|
item.comp.bindData(eid, item.model);
|
||||||
|
item.comp.setBattlePhase(this.isBattlePhase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.updateHeroInfoPanel(item);
|
this.updateHeroInfoPanel(item);
|
||||||
});
|
});
|
||||||
for (let i = 0; i < removeKeys.length; i++) {
|
for (let i = 0; i < removeKeys.length; i++) {
|
||||||
this.heroInfoItems.delete(removeKeys[i]);
|
this.heroInfoItems.delete(removeKeys[i]);
|
||||||
}
|
}
|
||||||
this.relayoutHeroInfoPanels();
|
|
||||||
this.updateHeroNumUI(false, false);
|
this.updateHeroNumUI(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -954,54 +1003,24 @@ export class MissionCardComp extends CCComp {
|
|||||||
item.comp.setBattlePhase(this.isBattlePhase);
|
item.comp.setBattlePhase(this.isBattlePhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private relayoutHeroInfoPanels() {
|
|
||||||
const sortedItems = [...this.heroInfoItems.values()].sort((a, b) => {
|
|
||||||
const aEnt = (a.model as any)?.ent as ecs.Entity | undefined;
|
|
||||||
const bEnt = (b.model as any)?.ent as ecs.Entity | undefined;
|
|
||||||
const aView = aEnt?.get(HeroViewComp);
|
|
||||||
const bView = bEnt?.get(HeroViewComp);
|
|
||||||
const aMove = aEnt?.get(MoveComp);
|
|
||||||
const bMove = bEnt?.get(MoveComp);
|
|
||||||
// 排序逻辑反转:适应 cc.Layout 的节点渲染顺序(先渲染/index小的在左边)
|
|
||||||
// 1. x 坐标越小(越靠后排)的,index 应该越小
|
|
||||||
const aFrontScore = aView?.node?.position?.x ?? -999999;
|
|
||||||
const bFrontScore = bView?.node?.position?.x ?? -999999;
|
|
||||||
if (aFrontScore !== bFrontScore) return aFrontScore - bFrontScore;
|
|
||||||
|
|
||||||
const aSpawnOrder = aMove?.spawnOrder ?? 0;
|
|
||||||
const bSpawnOrder = bMove?.spawnOrder ?? 0;
|
|
||||||
if (aSpawnOrder !== bSpawnOrder) return aSpawnOrder - bSpawnOrder;
|
|
||||||
|
|
||||||
const aEid = aEnt?.eid ?? 0;
|
|
||||||
const bEid = bEnt?.eid ?? 0;
|
|
||||||
return aEid - bEid;
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let index = 0; index < sortedItems.length; index++) {
|
|
||||||
const item = sortedItems[index];
|
|
||||||
if (!item.node || !item.node.isValid) continue;
|
|
||||||
|
|
||||||
// 既然使用了 cc.Layout 进行自动排版,我们只需设置渲染顺序
|
|
||||||
// Layout 会自动根据 siblingIndex 对所有子节点重新排位
|
|
||||||
item.node.setSiblingIndex(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private clearHeroInfoPanels() {
|
private clearHeroInfoPanels() {
|
||||||
if (this.heroInfoItems) {
|
if (this.heroInfoItems) {
|
||||||
this.heroInfoItems.forEach(item => {
|
|
||||||
if (item && item.node && item.node.isValid) {
|
|
||||||
item.node.destroy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.heroInfoItems.clear();
|
this.heroInfoItems.clear();
|
||||||
}
|
}
|
||||||
if (this.hero_info_node && this.hero_info_node.isValid) {
|
if (this.cachedHInfoComps) {
|
||||||
for (let i = this.hero_info_node.children.length - 1; i >= 0; i--) {
|
this.cachedHInfoComps.forEach(comp => {
|
||||||
const child = this.hero_info_node.children[i];
|
if (comp && comp.node && comp.node.isValid) {
|
||||||
if (child && child.isValid) child.destroy();
|
comp.node.active = false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
// 不再销毁子节点,因为它们是预先放置的
|
||||||
|
// 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;
|
this.heroInfoSyncTimer = 0;
|
||||||
this.syncMissionHeroData(0);
|
this.syncMissionHeroData(0);
|
||||||
this.updateHeroNumUI(false, false);
|
this.updateHeroNumUI(false, false);
|
||||||
|
|||||||
@@ -197,8 +197,8 @@ export class MissionHeroCompComp extends CCComp {
|
|||||||
|
|
||||||
// 优先中路(1) -> 上路(0) -> 下路(2)
|
// 优先中路(1) -> 上路(0) -> 下路(2)
|
||||||
const priority = [1, 0, 2];
|
const priority = [1, 0, 2];
|
||||||
for (const lane of priority) {
|
for (let indexInLane = 0; indexInLane < MissionHeroCompComp.HERO_LANE_CAP; indexInLane++) {
|
||||||
for (let indexInLane = 0; indexInLane < MissionHeroCompComp.HERO_LANE_CAP; indexInLane++) {
|
for (const lane of priority) {
|
||||||
if (!occupied[lane][indexInLane]) {
|
if (!occupied[lane][indexInLane]) {
|
||||||
return { lane, indexInLane };
|
return { lane, indexInLane };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user