refactor(英雄移动): 简化移动逻辑并统一渲染排序

- 移除 HeroMove.ts.meta 和 MonMove.ts.meta 文件
- 将所有英雄和怪物节点统一挂载到 HERO 父节点下,不再使用多行(LINE1-4)布局
- 简化 MoveSystem 中的 Y 轴位置计算,直接使用 baseY
- 重构渲染排序逻辑,基于阵营和位置计算前后顺序
- 移除过时的线路切换和碰撞检测逻辑
This commit is contained in:
panw
2026-03-16 14:39:57 +08:00
parent b53741ffeb
commit 662ae9a6c9
4 changed files with 49 additions and 67 deletions

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "b8ffb934-e91e-466c-a857-5f88cc83b542",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -73,13 +73,7 @@ export class Monster extends ecs.Entity {
node = instantiate(prefab);
}
let LINE1=scene.entityLayer!.node!.getChildByName("LINE1")!;
let LINE2=scene.entityLayer!.node!.getChildByName("LINE2")!;
let LINE3=scene.entityLayer!.node!.getChildByName("LINE3")!;
let LINE4=scene.entityLayer!.node!.getChildByName("LINE4")!;
// 🔥 设置初始 SiblingIndex - 防止溢出
const baseLane = lane === 0 ? LINE1 : lane === 1 ? LINE2 : lane === 2 ? LINE3 : LINE4;
node.parent = baseLane
node.parent = scene.entityLayer!.node!.getChildByName("HERO")!;
var view = node.getComponent(HeroViewComp)!;
const collider = node.getComponent(BoxCollider2D);
if (collider) {
@@ -109,7 +103,6 @@ export class Monster extends ecs.Entity {
model.type = hero.type;
model.fac = FacSet.MON;
model.is_boss = monType == MonType.BOSS;
if(model.is_boss) node.parent = scene.entityLayer!.node!.getChildByName("HERO")!;
if(!model.is_boss){
model.is_kalami = true;
}

View File

@@ -1,9 +0,0 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "8993c5a5-5b0a-4814-b53b-8cc441e9a359",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -5,6 +5,7 @@ import { smc } from "../common/SingletonModuleComp";
import { FacSet } from "../common/config/GameSet";
import { HType } from "../common/config/heroSet";
import { SkillRange } from "../common/config/SkillSet";
import { Node } from "cc";
@ecs.register('MoveComp')
export class MoveComp extends ecs.Comp {
@@ -36,14 +37,10 @@ interface MoveFacConfig {
@ecs.register('MoveSystem')
export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
private readonly ySlots = [
{ offset: 0, lineName: "LINE1" },
{ offset: 30, lineName: "LINE2" },
{ offset: -30, lineName: "LINE3" },
// { offset: 30, lineName: "LINE4" },
];
private readonly minSpacingX = 50;
private readonly minSpacingY = 30;
private readonly renderSortInterval = 0.05;
private renderSortElapsed = 0;
private readonly facConfigs: Record<number, MoveFacConfig> = {
[FacSet.HERO]: {
@@ -81,11 +78,10 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
return;
}
const snappedY = this.applyLineAndY(e, view, move, view.node.position.x);
if (snappedY !== null && view.node.position.y !== snappedY) {
view.node.setPosition(view.node.position.x, snappedY, 0);
if (view.node.position.y !== move.baseY) {
view.node.setPosition(view.node.position.x, move.baseY, 0);
}
this.updateRenderOrder(e);
this.updateRenderOrder(view);
const nearestEnemy = this.findNearestEnemy(e);
if (nearestEnemy) {
this.processCombatLogic(e, move, view, model, nearestEnemy);
@@ -256,38 +252,10 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
return;
}
newX = Math.max(moveMinX, Math.min(moveMaxX, newX));
const newY = this.applyLineAndY(view.ent, view, move, newX);
if (newY === null) {
view.status_change("idle");
return;
}
view.node.setPosition(newX, newY, 0);
view.node.setPosition(newX, move.baseY, 0);
view.status_change("move");
}
private applyLineAndY(entity: ecs.Entity, view: HeroViewComp, move: MoveComp, x: number): number | null {
if (!view.node) return 0;
const baseY = move.baseY;
for (const slot of this.ySlots) {
const y = baseY + slot.offset;
if (!this.hasAnyActorTooClose(entity, x, y)) {
const lineNode = this.getLineNode(slot.lineName);
if (lineNode && view.node.parent !== lineNode) {
view.node.parent = lineNode;
}
return y;
}
}
return null;
}
private getLineNode(lineName: string) {
const scene = smc.map?.MapView?.scene;
const layerRoot = scene?.entityLayer?.node;
if (!layerRoot) return null;
return layerRoot.getChildByName(lineName);
}
private hasAnyActorTooClose(self: ecs.Entity, x: number, y: number): boolean {
const myAttrs = self.get(HeroAttrsComp);
if (!myAttrs) return false;
@@ -338,7 +306,46 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
return nearest;
}
private updateRenderOrder(entity: ecs.Entity) {
return;
private updateRenderOrder(view: HeroViewComp) {
this.renderSortElapsed += this.dt;
const scene = smc.map?.MapView?.scene;
const actorRoot = scene?.entityLayer?.node?.getChildByName("HERO");
if (!actorRoot) return;
if (view.node.parent !== actorRoot) {
view.node.parent = actorRoot;
}
if (this.renderSortElapsed < this.renderSortInterval) return;
this.renderSortElapsed = 0;
const renderList: { node: Node; frontScore: number; spawnOrder: number; eid: number }[] = [];
ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp, MoveComp)).forEach(e => {
const attrs = e.get(HeroAttrsComp);
const actorView = e.get(HeroViewComp);
const actorMove = e.get(MoveComp);
if (!attrs || !actorView?.node || !actorMove || attrs.is_dead) return;
if (attrs.fac !== FacSet.HERO && attrs.fac !== FacSet.MON) return;
if (actorView.node.parent !== actorRoot) {
actorView.node.parent = actorRoot;
}
const frontScore = attrs.fac === FacSet.HERO ? actorView.node.position.x : -actorView.node.position.x;
renderList.push({
node: actorView.node,
frontScore,
spawnOrder: actorMove.spawnOrder,
eid: e.eid
});
});
renderList.sort((a, b) => {
if (a.frontScore !== b.frontScore) return a.frontScore - b.frontScore;
if (a.spawnOrder !== b.spawnOrder) return a.spawnOrder - b.spawnOrder;
return a.eid - b.eid;
});
renderList.forEach((item, index) => {
item.node.setSiblingIndex(index);
});
}
}