diff --git a/assets/script/game/map/MissionCardComp.ts b/assets/script/game/map/MissionCardComp.ts index 78dc79b9..409cf3a8 100644 --- a/assets/script/game/map/MissionCardComp.ts +++ b/assets/script/game/map/MissionCardComp.ts @@ -903,21 +903,14 @@ export class MissionCardComp extends CCComp { // 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; + // laneIdx = lanePriority[slotIndex % 3]; // priority: 1(中), 0(上), 2(下) + // model.lane = laneIdx; // - // 节点顺序预期: - // 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; + // 所以当: + // model.lane = 0 (上路), model.lane_index = 0 -> 对应 node_index = 1 + // model.lane = 1 (中路), model.lane_index = 0 -> 对应 node_index = 2 + // model.lane = 2 (下路), model.lane_index = 0 -> 对应 node_index = 3 + const expectedNodeIndex = model.lane_index * 3 + model.lane + 1; mLogger.log(this.debugMode, "MissionCardComp", `ensureHeroInfoPanel calculation: lane=${model.lane}, lane_index=${model.lane_index} -> expectedNodeIndex=${expectedNodeIndex}`); @@ -955,6 +948,8 @@ export class MissionCardComp extends CCComp { private refreshHeroInfoPanels() { const removeKeys: number[] = []; + + // 1. 先将已死亡的英雄移除,释放占用的节点 this.heroInfoItems.forEach((item, eid) => { if (!item.node || !item.node.isValid) { removeKeys.push(eid); @@ -965,32 +960,45 @@ export class MissionCardComp extends CCComp { removeKeys.push(eid); 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); }); for (let i = 0; i < removeKeys.length; i++) { this.heroInfoItems.delete(removeKeys[i]); } + + // 2. 然后再处理所有存活英雄的位置转移和信息刷新 + // 如果有多个英雄在同一帧发生位置变动,可能会出现目标节点暂时被其他还没更新的英雄占用的情况, + // 为了防止数据互相覆盖,我们先将需要转移的英雄收集起来。 + const needTransfer: Array<{eid: number, expectedNodeIndex: number}> = []; + + this.heroInfoItems.forEach((item, eid) => { + const expectedNodeIndex = item.model.lane_index * 3 + item.model.lane + 1; + if (item.comp.node_index !== expectedNodeIndex) { + needTransfer.push({eid, expectedNodeIndex}); + } else { + this.updateHeroInfoPanel(item); + } + }); + + // 执行位置转移 + for (const transfer of needTransfer) { + const item = this.heroInfoItems.get(transfer.eid); + if (!item) continue; + + const newComp = this.cachedHInfoComps.get(transfer.expectedNodeIndex); + if (newComp) { + // 隐藏旧节点 + item.node.active = false; + // 转移到新节点 + item.comp = newComp; + item.node = newComp.node; + item.node.active = true; + item.comp.bindData(transfer.eid, item.model); + item.comp.setBattlePhase(this.isBattlePhase); + + this.updateHeroInfoPanel(item); + } + } + this.updateHeroNumUI(false, false); }