feat(怪物): 添加怪物y轴移动逻辑和死亡时间优化

为怪物添加y轴移动能力,使其能够向目标y坐标移动。同时优化怪物死亡时间,使用单独的monDeadTime变量控制怪物死亡时间,区别于英雄的realDeadTime。主要修改包括:
1. 在MonMoveComp中添加targetY字段用于y轴移动目标
2. 实现y轴移动逻辑和位置检查
3. 为HeroViewComp添加monDeadTime字段并应用
This commit is contained in:
walkpan
2026-01-02 14:53:44 +08:00
parent 91129505d2
commit f3039eb47b
2 changed files with 69 additions and 9 deletions

View File

@@ -47,6 +47,7 @@ export class HeroViewComp extends CCComp {
box_group:number = BoxSet.HERO; // 碰撞组
realDeadTime:number=10
deadCD:number=0
monDeadTime:number=0.5
// 血条显示相关
hpBarShowTime:number = 5; // 血条显示持续时间(秒)
hpBarShowCD:number = 0; // 血条显示计时器
@@ -357,6 +358,12 @@ export class HeroViewComp extends CCComp {
if(this.model.is_count_dead) return;
this.model.is_count_dead = true; // 防止重复触发,必须存在防止重复调用
this.top_node.active=false
// 怪物使用0.5秒死亡时间英雄使用realDeadTime
if(this.model.fac === FacSet.MON){
this.realDeadTime = this.monDeadTime;
}
// 播放死亡特效
this.as.dead();

View File

@@ -19,6 +19,8 @@ export class MonMoveComp extends ecs.Comp {
lane: number = 0;
/** 生成顺序:用于同线路内的层级排序,数值越大越晚生成,层级越前 */
spawnOrder: number = 0;
/** 目标y坐标 */
targetY: number = 0;
reset() {
this.direction = 1;
@@ -26,6 +28,7 @@ export class MonMoveComp extends ecs.Comp {
this.moving = true;
this.lane = 0;
this.spawnOrder = 0;
this.targetY = 0;
}
}
@@ -59,26 +62,34 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
view.status_change("idle");
return;
}
// 检查是否需要y轴靠近
this.checkAndSetTargetY(e);
// 怪物移动逻辑同时向目标x和y方向移动
const deltaX = (model.Attrs[Attrs.SPEED]/3) * this.dt * move.direction;
const newX = view.node.position.x + deltaX;
// 怪物简单移动逻辑:向目标方向移动
const delta = (model.Attrs[Attrs.SPEED]/3) * this.dt * move.direction;
const newX = view.node.position.x + delta;
let newY = view.node.position.y;
if (move.targetY !== 0) {
const deltaY = (model.Attrs[Attrs.SPEED]/3) * this.dt * Math.sign(move.targetY - newY);
newY = newY + deltaY;
if (Math.abs(newY - move.targetY) < Math.abs(deltaY)) {
newY = move.targetY;
move.targetY = 0;
}
}
// 限制移动范围
if (this.validatePosition(newX, move)) {
view.status_change("move");
view.node.setPosition(newX, view.node.position.y, 0);
view.node.setPosition(newX, newY, 0);
} else {
// 当达到目标位置边界时也切换为idle状态
view.status_change("idle");
// 达到边界是永久停止设置moving为false
move.moving = false;
}
} else {
view.status_change("idle");
// 因为敌人在面前而暂时停止不设置moving为false保持检查状态
}
}
@@ -192,4 +203,46 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
return false;
});
}
/** 检查并设置y轴目标位置 */
private checkAndSetTargetY(entity: ecs.Entity): void {
const move = entity.get(MonMoveComp);
const currentView = entity.get(HeroViewComp);
const heroAttrs = entity.get(HeroAttrsComp);
if (!currentView || !currentView.node || !heroAttrs) return;
if (move.targetY !== 0) return;
const currentPos = currentView.node.position;
const team = heroAttrs.fac;
let nearestHero: ecs.Entity | null = null;
let nearestDist = Infinity;
ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).forEach(e => {
const model = e.get(HeroAttrsComp);
const view = e.get(HeroViewComp);
if (!view || !view.node) return;
if (model.fac === team || model.is_dead) return;
const dist = Math.abs(currentPos.x - view.node.position.x);
if (dist < nearestDist) {
nearestDist = dist;
nearestHero = e;
}
});
if (!nearestHero || nearestDist > 100) return;
const heroView = nearestHero.get(HeroViewComp);
if (!heroView || !heroView.node) return;
const heroY = heroView.node.position.y;
const yDist = Math.abs(currentPos.y - heroY);
if (yDist > 50) {
const direction = heroY > currentPos.y ? 1 : -1;
move.targetY = heroY + direction * 50;
}
}
}