feat(渲染): 实现基于线路和生成顺序的层级管理系统

添加IndexSet枚举定义基础层级和增量
修改怪物生成逻辑以支持线路(lane)和生成顺序(spawnOrder)
重构MonMoveSystem中的渲染层级更新逻辑
优化HeroViewComp中血条显示逻辑
调整怪物位置配置以支持双线路布局
This commit is contained in:
2025-11-03 06:38:06 +08:00
parent 1f5792aa99
commit 2a309a14d0
6 changed files with 96 additions and 36 deletions

View File

@@ -112,6 +112,7 @@ export class HeroViewComp extends CCComp {
/** 显示护盾 */
private show_shield(shield: number = 0, shield_max: number = 0) {
if(!this.top_node.active) return
let shield_progress = shield / shield_max;
this.node.getChildByName("shielded").active = shield > 0;
this.top_node.getChildByName("shield").active = shield > 0;
@@ -123,6 +124,11 @@ export class HeroViewComp extends CCComp {
/** 显示血量 */
private hp_show(hp: number, hp_max: number) {
if(hp==hp_max) {
this.top_node.active=false;
return
}
this.top_node.active=true
let hp_progress = hp / hp_max;
this.top_node.getChildByName("hp").getComponent(ProgressBar).progress = hp_progress;
this.scheduleOnce(() => {
@@ -132,12 +138,14 @@ export class HeroViewComp extends CCComp {
/** 显示魔法值 */
private mp_show(mp: number, mp_max: number) {
if(!this.top_node.active) return
this.top_node.getChildByName("mp").getComponent(ProgressBar).progress = mp / mp_max;
this.scheduleOnce(() => {
this.top_node.getChildByName("mp").getChildByName("mpb").getComponent(ProgressBar).progress = mp / mp_max;
}, 0.15);
}
private pow_show(pow: number, pow_max: number) {
if(!this.top_node.active) return
this.top_node.getChildByName("pow").getComponent(ProgressBar).progress = pow / pow_max;
this.scheduleOnce(() => {
this.top_node.getChildByName("pow").getChildByName("mpb").getComponent(ProgressBar).progress = pow / pow_max;

View File

@@ -35,7 +35,7 @@ export class Monster extends ecs.Entity {
}
/** 加载角色 */
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001,lv:number=1,monType:MonType=MonType.NORMAL, buffs: BuffConf[] = [],is_call=false) {
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001,lv:number=1,monType:MonType=MonType.NORMAL, buffs: BuffConf[] = [],is_call=false, lane: number = 0, spawnOrder: number = 0) {
scale=-1
var scene = smc.map.MapView.scene;
var path = "game/heros/"+HeroInfo[uuid].path;
@@ -86,10 +86,12 @@ export class Monster extends ecs.Entity {
this.add(view);
oops.message.dispatchEvent("monster_load",this)
// 初始化移动参数
// 初始化移动参数,包括线路和生成顺序
const move = this.get(MonMoveComp);
move.direction = -1; // 向左移动
move.targetX = -800; // 左边界
move.lane = lane; // 设置线路标识
move.spawnOrder = spawnOrder; // 设置生成顺序
smc.vmdata.mission_data.mon_num++
}

View File

@@ -2,7 +2,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
import { HeroViewComp } from "./HeroViewComp";
import { HeroAttrsComp } from "./HeroAttrsComp";
import { smc } from "../common/SingletonModuleComp";
import { FacSet } from "../common/config/GameSet";
import { FacSet, IndexSet } from "../common/config/GameSet";
import { Attrs } from "../common/config/HeroAttrs";
/** 怪物移动组件 */
@@ -14,11 +14,17 @@ export class MonMoveComp extends ecs.Comp {
targetX: number = 0;
/** 是否处于移动状态 */
moving: boolean = true;
/** 线路标识0=一线(y=120)1=二线(y=80) */
lane: number = 0;
/** 生成顺序:用于同线路内的层级排序,数值越大越晚生成,层级越前 */
spawnOrder: number = 0;
reset() {
this.direction = 1;
this.targetX = 0;
this.moving = true;
this.lane = 0;
this.spawnOrder = 0;
}
}
@@ -134,31 +140,55 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
/** 更新渲染层级 */
private updateRenderOrder(entity: ecs.Entity) {
const currentView = entity.get(HeroViewComp);
const currentModel = entity.get(HeroAttrsComp);
// 查找所有怪物单位
const allUnits = ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp))
.filter(e => {
const otherModel = e.get(HeroAttrsComp);
return otherModel.fac === currentModel.fac; // 按阵营分组
})
.map(e => e);
// 直接调用全局更新方法,避免重复计算
this.updateAllUnitsRenderOrder();
}
// 按x坐标排序x坐标越大越前面的显示在上层
const sortedUnits = allUnits.sort((a, b) => {
const viewA = a.get(HeroViewComp);
const viewB = b.get(HeroViewComp);
if (!viewA || !viewA.node || !viewB || !viewB.node) return 0;
const posA = viewA.node.position.x;
const posB = viewB.node.position.x;
return posA - posB; // x坐标从小到大排序
/** 更新所有单位的渲染层级 */
private updateAllUnitsRenderOrder() {
// 获取所有单位
const allUnits = ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp));
// 创建单位数组,包含层级信息
const unitsWithOrder: Array<{
entity: ecs.Entity,
view: HeroViewComp,
order: number
}> = [];
allUnits.forEach(e => {
const model = e.get(HeroAttrsComp);
const view = e.get(HeroViewComp);
if (!view || !view.node || !model) return;
let order = 0;
if (model.fac === FacSet.HERO) {
// 英雄层级:基础层级 + y轴位置影响
order = IndexSet.HERO + Math.floor(view.node.position.y);
} else if (model.fac === FacSet.MON) {
const move = e.get(MonMoveComp);
if (move) {
// 怪物层级:基于线路和生成顺序
const baseLane = move.lane === 0 ? IndexSet.MON1 : IndexSet.MON2;
order = baseLane + (move.spawnOrder * IndexSet.MON_INCREMENT);
}
}
unitsWithOrder.push({
entity: e,
view: view,
order: order
});
});
// 设置渲染顺序x坐标越大的显示在上层index越大层级越高
sortedUnits.forEach((unit, index) => {
const model = unit.get(HeroViewComp);
model.node.setSiblingIndex(index); // 直接使用indexx坐标大的index大层级高
// 按层级排序order值小的在后面siblingIndex小order值大的在前面siblingIndex大
unitsWithOrder.sort((a, b) => a.order - b.order);
// 设置 siblingIndex
unitsWithOrder.forEach((unit, index) => {
unit.view.node.setSiblingIndex(index);
});
}
}