refactor(monster&hero): 重构三路分层逻辑与渲染排序
1. 移除飞行怪特殊判定,统一按Y轴高度处理三路渲染 2. 重命名飞行层相关变量为更准确的路次命名 3. 新增英雄自动分路均衡分配逻辑 4. 调整渲染排序规则,按Y轴高度决定上下层显示顺序 5. 修复怪物入场动画与刷怪分路逻辑
This commit is contained in:
@@ -123,7 +123,7 @@ export class Monster extends ecs.Entity {
|
||||
* 2) 初始化表现、属性、技能与阵营
|
||||
* 3) 播放下落入场并在落地后启用碰撞与移动
|
||||
*/
|
||||
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, is_boss:boolean=false, dropToY:number = pos.y,mon_lv:number=1, flyLaneIndex:number = 0) {
|
||||
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, is_boss:boolean=false, dropToY:number = pos.y,mon_lv:number=1, laneIndex:number = 0) {
|
||||
// 怪物默认朝左,表现缩放固定为负向
|
||||
scale=-1
|
||||
// 当前怪物尺寸固定,保留变量便于后续扩展
|
||||
@@ -220,18 +220,7 @@ export class Monster extends ecs.Entity {
|
||||
if (!node || !node.isValid) return;
|
||||
// 落地后锁定最终位置,切换到落地完成状态
|
||||
node.setPosition(pos.x, dropToY, 0);
|
||||
// 如果是飞行怪,可以保持空中状态,这里依然调用 down
|
||||
view.playEnd("down");
|
||||
|
||||
// 飞行怪加一个轻微的上下浮动动效
|
||||
if (flyLaneIndex > 0) {
|
||||
tween(node)
|
||||
.by(1.5, { position: v3(0, 15, 0) }, { easing: "sineOut" })
|
||||
.by(1.5, { position: v3(0, -15, 0) }, { easing: "sineIn" })
|
||||
.union()
|
||||
.repeatForever()
|
||||
.start();
|
||||
}
|
||||
|
||||
move.moving = true;
|
||||
// 落地后启用怪物碰撞分组
|
||||
|
||||
@@ -139,10 +139,8 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
||||
const inRange = this.isEnemyInAttackRange(model, selfX, enemyX);
|
||||
|
||||
// 接触判定距离,只有接触英雄才停止移动
|
||||
// 飞行怪忽略接触碰撞,不被阻挡
|
||||
const isFly = move.baseY > 50;
|
||||
const touchDistance = 50;
|
||||
const isTouching = !isFly && (dist <= touchDistance);
|
||||
const isTouching = dist <= touchDistance;
|
||||
|
||||
// 攻击判定
|
||||
if (inRange) {
|
||||
|
||||
@@ -65,7 +65,7 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
private lastRenderSortAt = 0;
|
||||
private heroMoveMatcher: ecs.IMatcher | null = null;
|
||||
private heroViewMatcher: ecs.IMatcher | null = null;
|
||||
private readonly renderEntries: { node: Node; bossPriority: number; frontScore: number; spawnOrder: number; eid: number }[] = [];
|
||||
private readonly renderEntries: { node: Node; bossPriority: number; frontScore: number; spawnOrder: number; eid: number; laneScore: number }[] = [];
|
||||
private renderEntryCount = 0;
|
||||
|
||||
/**
|
||||
@@ -391,18 +391,21 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
}
|
||||
|
||||
const isFly = actorView.node.position.y > 50;
|
||||
// 飞行怪在最前,其次是地面的 X 坐标
|
||||
const frontScore = isFly ? 999999 - actorView.node.position.x : (attrs.fac === FacSet.HERO ? actorView.node.position.x : -actorView.node.position.x);
|
||||
// 按 Y 轴计算渲染层级权重(Y 越小,说明越靠近屏幕下方,应该渲染在越前面)
|
||||
// 之前的 isFly 逻辑已被移除,统一按 Y 轴处理三路渲染
|
||||
const laneScore = -actorView.node.position.y;
|
||||
// X 轴权重:站在前排的(交战处)优先渲染
|
||||
const frontScore = attrs.fac === FacSet.HERO ? actorView.node.position.x : -actorView.node.position.x;
|
||||
|
||||
const entryIndex = this.renderEntryCount;
|
||||
let entry = this.renderEntries[entryIndex];
|
||||
if (!entry) {
|
||||
entry = { node: actorView.node, bossPriority: 0, frontScore: 0, spawnOrder: 0, eid: 0 };
|
||||
entry = { node: actorView.node, bossPriority: 0, frontScore: 0, spawnOrder: 0, eid: 0, laneScore: 0 };
|
||||
this.renderEntries.push(entry);
|
||||
}
|
||||
entry.node = actorView.node;
|
||||
entry.bossPriority = attrs.is_boss ? 1 : 0;
|
||||
entry.laneScore = laneScore;
|
||||
entry.frontScore = frontScore;
|
||||
entry.spawnOrder = spawnOrder;
|
||||
entry.eid = e.eid;
|
||||
@@ -410,9 +413,11 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
});
|
||||
this.renderEntries.length = this.renderEntryCount;
|
||||
|
||||
/** 定时重排同层节点:Boss 优先级 -> 前后位置 -> 出生序 -> eid */
|
||||
/** 定时重排同层节点:Boss 优先级 -> Y 轴路次 -> 前后位置 -> 出生序 -> eid */
|
||||
this.renderEntries.sort((a, b) => {
|
||||
if (a.bossPriority !== b.bossPriority) return a.bossPriority - b.bossPriority;
|
||||
// Y轴靠下的(laneScore 较大)应该在后面,从而渲染在上面
|
||||
if (Math.abs(a.laneScore - b.laneScore) > 10) return a.laneScore - b.laneScore;
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user