feat(渲染): 实现基于线路和生成顺序的层级管理系统
添加IndexSet枚举定义基础层级和增量 修改怪物生成逻辑以支持线路(lane)和生成顺序(spawnOrder) 重构MonMoveSystem中的渲染层级更新逻辑 优化HeroViewComp中血条显示逻辑 调整怪物位置配置以支持双线路布局
This commit is contained in:
@@ -131,7 +131,16 @@ export enum FightSet {
|
|||||||
// AP_UPDATE_RATE=100,
|
// AP_UPDATE_RATE=100,
|
||||||
// AP_CHANGE_RATE=0,
|
// AP_CHANGE_RATE=0,
|
||||||
}
|
}
|
||||||
|
export enum IndexSet {
|
||||||
|
/** 英雄基础层级 */
|
||||||
|
HERO = 200,
|
||||||
|
/** 一线怪物基础层级(y=120) - 层级较低,在后面 */
|
||||||
|
MON1 = 100,
|
||||||
|
/** 二线怪物基础层级(y=80) - 层级较高,在前面 */
|
||||||
|
MON2 = 300,
|
||||||
|
/** 每个怪物的层级增量,确保后生成的在前面 */
|
||||||
|
MON_INCREMENT = 1,
|
||||||
|
}
|
||||||
export const TooltipTypes = {
|
export const TooltipTypes = {
|
||||||
life:1,
|
life:1,
|
||||||
health:2,
|
health:2,
|
||||||
|
|||||||
@@ -51,14 +51,14 @@ export const HeroPos={
|
|||||||
2:{pos:v3(0,100,0)},
|
2:{pos:v3(0,100,0)},
|
||||||
}
|
}
|
||||||
export const MonSet = {
|
export const MonSet = {
|
||||||
0:{pos:v3(240,100,0)},
|
0:{pos:v3(240,110,0)},
|
||||||
1:{pos:v3(320,100,0)},
|
1:{pos:v3(240,90,0)},
|
||||||
2:{pos:v3(360,100,0)},
|
2:{pos:v3(320,110,0)},
|
||||||
3:{pos:v3(400,100,0)},
|
3:{pos:v3(320,90,0)},
|
||||||
4:{pos:v3(440,100,0)},
|
4:{pos:v3(360,110,0)},
|
||||||
5:{pos:v3(480,100,0)},
|
5:{pos:v3(360,90,0)},
|
||||||
6:{pos:v3(520,100,0)},
|
6:{pos:v3(400,110,0)},
|
||||||
7:{pos:v3(560,100,0)},
|
7:{pos:v3(400,90,0)},
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum HeroConf{
|
export enum HeroConf{
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
|
|
||||||
/** 显示护盾 */
|
/** 显示护盾 */
|
||||||
private show_shield(shield: number = 0, shield_max: number = 0) {
|
private show_shield(shield: number = 0, shield_max: number = 0) {
|
||||||
|
if(!this.top_node.active) return
|
||||||
let shield_progress = shield / shield_max;
|
let shield_progress = shield / shield_max;
|
||||||
this.node.getChildByName("shielded").active = shield > 0;
|
this.node.getChildByName("shielded").active = shield > 0;
|
||||||
this.top_node.getChildByName("shield").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) {
|
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;
|
let hp_progress = hp / hp_max;
|
||||||
this.top_node.getChildByName("hp").getComponent(ProgressBar).progress = hp_progress;
|
this.top_node.getChildByName("hp").getComponent(ProgressBar).progress = hp_progress;
|
||||||
this.scheduleOnce(() => {
|
this.scheduleOnce(() => {
|
||||||
@@ -132,12 +138,14 @@ export class HeroViewComp extends CCComp {
|
|||||||
|
|
||||||
/** 显示魔法值 */
|
/** 显示魔法值 */
|
||||||
private mp_show(mp: number, mp_max: number) {
|
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.top_node.getChildByName("mp").getComponent(ProgressBar).progress = mp / mp_max;
|
||||||
this.scheduleOnce(() => {
|
this.scheduleOnce(() => {
|
||||||
this.top_node.getChildByName("mp").getChildByName("mpb").getComponent(ProgressBar).progress = mp / mp_max;
|
this.top_node.getChildByName("mp").getChildByName("mpb").getComponent(ProgressBar).progress = mp / mp_max;
|
||||||
}, 0.15);
|
}, 0.15);
|
||||||
}
|
}
|
||||||
private pow_show(pow: number, pow_max: number) {
|
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.top_node.getChildByName("pow").getComponent(ProgressBar).progress = pow / pow_max;
|
||||||
this.scheduleOnce(() => {
|
this.scheduleOnce(() => {
|
||||||
this.top_node.getChildByName("pow").getChildByName("mpb").getComponent(ProgressBar).progress = pow / pow_max;
|
this.top_node.getChildByName("pow").getChildByName("mpb").getComponent(ProgressBar).progress = pow / pow_max;
|
||||||
|
|||||||
@@ -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
|
scale=-1
|
||||||
var scene = smc.map.MapView.scene;
|
var scene = smc.map.MapView.scene;
|
||||||
var path = "game/heros/"+HeroInfo[uuid].path;
|
var path = "game/heros/"+HeroInfo[uuid].path;
|
||||||
@@ -86,10 +86,12 @@ export class Monster extends ecs.Entity {
|
|||||||
this.add(view);
|
this.add(view);
|
||||||
oops.message.dispatchEvent("monster_load",this)
|
oops.message.dispatchEvent("monster_load",this)
|
||||||
|
|
||||||
// 初始化移动参数
|
// 初始化移动参数,包括线路和生成顺序
|
||||||
const move = this.get(MonMoveComp);
|
const move = this.get(MonMoveComp);
|
||||||
move.direction = -1; // 向左移动
|
move.direction = -1; // 向左移动
|
||||||
move.targetX = -800; // 左边界
|
move.targetX = -800; // 左边界
|
||||||
|
move.lane = lane; // 设置线路标识
|
||||||
|
move.spawnOrder = spawnOrder; // 设置生成顺序
|
||||||
smc.vmdata.mission_data.mon_num++
|
smc.vmdata.mission_data.mon_num++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec
|
|||||||
import { HeroViewComp } from "./HeroViewComp";
|
import { HeroViewComp } from "./HeroViewComp";
|
||||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
import { FacSet } from "../common/config/GameSet";
|
import { FacSet, IndexSet } from "../common/config/GameSet";
|
||||||
import { Attrs } from "../common/config/HeroAttrs";
|
import { Attrs } from "../common/config/HeroAttrs";
|
||||||
|
|
||||||
/** 怪物移动组件 */
|
/** 怪物移动组件 */
|
||||||
@@ -14,11 +14,17 @@ export class MonMoveComp extends ecs.Comp {
|
|||||||
targetX: number = 0;
|
targetX: number = 0;
|
||||||
/** 是否处于移动状态 */
|
/** 是否处于移动状态 */
|
||||||
moving: boolean = true;
|
moving: boolean = true;
|
||||||
|
/** 线路标识:0=一线(y=120),1=二线(y=80) */
|
||||||
|
lane: number = 0;
|
||||||
|
/** 生成顺序:用于同线路内的层级排序,数值越大越晚生成,层级越前 */
|
||||||
|
spawnOrder: number = 0;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.direction = 1;
|
this.direction = 1;
|
||||||
this.targetX = 0;
|
this.targetX = 0;
|
||||||
this.moving = true;
|
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) {
|
private updateRenderOrder(entity: ecs.Entity) {
|
||||||
const currentView = entity.get(HeroViewComp);
|
// 直接调用全局更新方法,避免重复计算
|
||||||
const currentModel = entity.get(HeroAttrsComp);
|
this.updateAllUnitsRenderOrder();
|
||||||
|
}
|
||||||
// 查找所有怪物单位
|
|
||||||
const allUnits = ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp))
|
|
||||||
.filter(e => {
|
|
||||||
const otherModel = e.get(HeroAttrsComp);
|
|
||||||
return otherModel.fac === currentModel.fac; // 按阵营分组
|
|
||||||
})
|
|
||||||
.map(e => e);
|
|
||||||
|
|
||||||
// 按x坐标排序:x坐标越大(越前面)的显示在上层
|
/** 更新所有单位的渲染层级 */
|
||||||
const sortedUnits = allUnits.sort((a, b) => {
|
private updateAllUnitsRenderOrder() {
|
||||||
const viewA = a.get(HeroViewComp);
|
// 获取所有单位
|
||||||
const viewB = b.get(HeroViewComp);
|
const allUnits = ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp));
|
||||||
if (!viewA || !viewA.node || !viewB || !viewB.node) return 0;
|
|
||||||
const posA = viewA.node.position.x;
|
// 创建单位数组,包含层级信息
|
||||||
const posB = viewB.node.position.x;
|
const unitsWithOrder: Array<{
|
||||||
return posA - posB; // x坐标从小到大排序
|
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越大,层级越高)
|
// 按层级排序:order值小的在后面(siblingIndex小),order值大的在前面(siblingIndex大)
|
||||||
sortedUnits.forEach((unit, index) => {
|
unitsWithOrder.sort((a, b) => a.order - b.order);
|
||||||
const model = unit.get(HeroViewComp);
|
|
||||||
model.node.setSiblingIndex(index); // 直接使用index,x坐标大的index大,层级高
|
// 设置 siblingIndex
|
||||||
|
unitsWithOrder.forEach((unit, index) => {
|
||||||
|
unit.view.node.setSiblingIndex(index);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ import { GameEvent } from "../common/config/GameEvent";
|
|||||||
// 导入肉鸽配置
|
// 导入肉鸽配置
|
||||||
import { MonType, EventType, getStageMonConfigs} from "./RogueConfig";
|
import { MonType, EventType, getStageMonConfigs} from "./RogueConfig";
|
||||||
import { BuffConf } from "../common/config/SkillSet";
|
import { BuffConf } from "../common/config/SkillSet";
|
||||||
|
import { IndexSet } from "../common/config/GameSet";
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
/** 视图层对象 */
|
/** 视图层对象 */
|
||||||
@@ -30,6 +31,8 @@ export class MissionMonCompComp extends CCComp {
|
|||||||
private isPausing: boolean = false; // 是否正在暂停
|
private isPausing: boolean = false; // 是否正在暂停
|
||||||
private currentEvent: EventType | null = null; // 当前关卡的随机事件
|
private currentEvent: EventType | null = null; // 当前关卡的随机事件
|
||||||
private eventProcessed: boolean = false; // 事件是否已处理
|
private eventProcessed: boolean = false; // 事件是否已处理
|
||||||
|
/** 全局生成顺序计数器,用于层级管理 */
|
||||||
|
private globalSpawnOrder: number = 0;
|
||||||
|
|
||||||
|
|
||||||
onLoad(){
|
onLoad(){
|
||||||
@@ -46,6 +49,8 @@ export class MissionMonCompComp extends CCComp {
|
|||||||
fight_ready(){
|
fight_ready(){
|
||||||
// console.log("[MissionMonComp]:fight_ready")
|
// console.log("[MissionMonComp]:fight_ready")
|
||||||
smc.vmdata.mission_data.mon_num=0
|
smc.vmdata.mission_data.mon_num=0
|
||||||
|
// 重置生成顺序计数器
|
||||||
|
this.globalSpawnOrder = 0
|
||||||
this.do_mon_wave()
|
this.do_mon_wave()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,8 +190,14 @@ export class MissionMonCompComp extends CCComp {
|
|||||||
let scale = -1;
|
let scale = -1;
|
||||||
let pos: Vec3 = v3(MonSet[i].pos);
|
let pos: Vec3 = v3(MonSet[i].pos);
|
||||||
|
|
||||||
// 生成怪物
|
// 根据位置判断线路:y=110为一线(lane=0),y=80为二线(lane=1)
|
||||||
mon.load(pos,scale,uuid,lv,monType,buffs);
|
const lane = pos.y === 110 ? 0 : 1;
|
||||||
|
|
||||||
|
// 递增全局生成顺序
|
||||||
|
this.globalSpawnOrder++;
|
||||||
|
|
||||||
|
// 生成怪物,传递线路和生成顺序
|
||||||
|
mon.load(pos, scale, uuid, lv, monType, buffs, false, lane, this.globalSpawnOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user