refactor(map): 优化任务卡片英雄位置刷新逻辑

1. 重构注释排版,统一说明战场节点对应规则
2. 调整英雄位置更新流程:先清理失效单位,再批量处理位置变更,最后统一刷新信息
3. 修复多英雄同帧位置变动可能导致的数据覆盖问题
This commit is contained in:
panw
2026-05-13 17:27:22 +08:00
parent 8f65282af7
commit d72e161150

View File

@@ -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);
}