实现 英雄不在动一个x点,和 伤害队列显示

This commit is contained in:
2025-02-07 15:36:25 +08:00
parent 56b365cbe7
commit f5fe35d36b
2 changed files with 108 additions and 16 deletions

View File

@@ -2,11 +2,13 @@ import { HeroViewComp } from "../../../hero/HeroViewComp";
import { BattleMoveComp } from "./BattleMoveComp"; import { BattleMoveComp } from "./BattleMoveComp";
import { ecs } from "../../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; import { ecs } from "../../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { smc } from "../../SingletonModuleComp"; import { smc } from "../../SingletonModuleComp";
import { BoxSet } from "../../config/BoxSet";
@ecs.register('BattleMoveSystem') @ecs.register('BattleMoveSystem')
export class BattleMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { export class BattleMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
filter(): ecs.IMatcher { filter(): ecs.IMatcher {
return ecs.allOf(BattleMoveComp, HeroViewComp); return ecs.allOf(BattleMoveComp, HeroViewComp);
} }
update(e: ecs.Entity) { update(e: ecs.Entity) {
@@ -16,9 +18,13 @@ export class BattleMoveSystem extends ecs.ComblockSystem implements ecs.ISystemU
if (!move.moving) return; if (!move.moving) return;
// 检测攻击范围内是否有敌人 // 检测攻击范围内是否有敌人
const shouldStop = this.checkEnemiesInRange(e, view.dis); // 检测友方碰撞和敌方攻击范围
const alliesStop = this.checkAlliesInProximity(e);
const enemiesStop = this.checkEnemiesInRange(e, view.dis);
const shouldStop = alliesStop || enemiesStop;
view.is_atking = shouldStop; view.is_atking = shouldStop;
// 同步攻击状态
// 同步状态
if (!shouldStop) { if (!shouldStop) {
if(view.is_stop||view.is_dead) return //停止移动或者死亡不移动 if(view.is_stop||view.is_dead) return //停止移动或者死亡不移动
// 计算移动量 // 计算移动量
@@ -51,6 +57,60 @@ export class BattleMoveSystem extends ecs.ComblockSystem implements ecs.ISystemU
newX >= move.targetX; newX >= move.targetX;
} }
/** 检测友方单位碰撞 */
private checkAlliesInProximity(entity: ecs.Entity): boolean {
const current = entity.get(HeroViewComp);
const currentPos = current.node.position;
const SAFE_DISTANCE = 30; // 安全距离
// 查找同阵营同类型的所有友军(包括当前单位)
const allAllies = ecs.query(ecs.allOf(HeroViewComp)).filter(e => {
const other = e.get(HeroViewComp);
return (e === entity || (
other.fac === current.fac &&
other.type === current.type
));
});
// 按uuid从小到大排序
const sortedAllies = allAllies.sort((a, b) => {
return a.get(HeroViewComp).hero_uuid - b.get(HeroViewComp).hero_uuid;
});
// 找到当前单位在排序中的位置
const currentIndex = sortedAllies.findIndex(e => e === entity);
// 设置渲染顺序
if (current.is_boss) {
// boss显示在最上层
current.node.setSiblingIndex(999);
} else {
// 非boss单位uuid越小的显示在下层索引越小
current.node.setSiblingIndex(currentIndex);
}
// 如果是uuid最小的单位直接移动
if (currentIndex === 0) {
current.is_stop_temp = false;
return false;
}
// 获取前一个单位uuid比当前小的最近单位
const prevUnit = sortedAllies[currentIndex - 1];
const prevView = prevUnit.get(HeroViewComp);
const distToPrev = Math.abs(currentPos.x - prevView.node.position.x);
// 如果与前一个单位距离小于安全距离,则停止
if (distToPrev < SAFE_DISTANCE) {
current.is_stop_temp = true;
return true;
}
// 如果与前一个单位距离大于安全距离,则移动
current.is_stop_temp = false;
return false;
}
/** 检测攻击范围内敌人 */ /** 检测攻击范围内敌人 */
private checkEnemiesInRange(entity: ecs.Entity, range: number): boolean { private checkEnemiesInRange(entity: ecs.Entity, range: number): boolean {
const currentPos = entity.get(HeroViewComp).node.position; const currentPos = entity.get(HeroViewComp).node.position;

View File

@@ -108,6 +108,15 @@ export class HeroViewComp extends CCComp {
ice_cd: number = 0; //冰冻倒计时 ice_cd: number = 0; //冰冻倒计时
dir_y:number = 0; dir_y:number = 0;
speek_time:number = 0; speek_time:number = 0;
is_stop_temp:boolean = false;i
private damageQueue: Array<{
damage: number,
isCrit: boolean,
delay: number
}> = [];
private isProcessingDamage: boolean = false;
private damageInterval: number = 0.2; // 伤害数字显示间隔
onLoad() { onLoad() {
this.as = this.getComponent(HeroSpine); this.as = this.getComponent(HeroSpine);
@@ -147,6 +156,8 @@ export class HeroViewComp extends CCComp {
this.at += dt; this.at += dt;
this.in_stop(dt); this.in_stop(dt);
// 处理伤害队列
this.processDamageQueue();
} }
get isActive() { get isActive() {
return this.ent.has(HeroViewComp) && this.node?.isValid; return this.ent.has(HeroViewComp) && this.node?.isValid;
@@ -357,20 +368,41 @@ export class HeroViewComp extends CCComp {
/** 显示伤害数字 */ /** 显示伤害数字 */
showDamage(damage: number, isCrit: boolean) { showDamage(damage: number, isCrit: boolean) {
this.BUFFCOMP.in_atked() this.damageQueue.push({
// this.as.atked(); damage,
this.atked_count++; isCrit,
this.exp_add(this.uaexp) delay: this.damageInterval
this.power_add(this.uapw) });
if(isCrit){
this.BUFFCOMP.tooltip(4,damage.toFixed(0),damage)
console.log("暴击伤害:"+damage)
}else{
this.BUFFCOMP.tooltip(1,damage.toFixed(0),damage)
console.log("普通伤害:"+damage)
} }
/** 处理伤害队列 */
private processDamageQueue() {
if (this.isProcessingDamage || this.damageQueue.length === 0) return;
this.isProcessingDamage = true;
const damageInfo = this.damageQueue.shift()!;
this.showDamageImmediate(damageInfo.damage, damageInfo.isCrit);
// 设置延时处理下一个伤害
this.scheduleOnce(() => {
this.isProcessingDamage = false;
}, this.damageInterval);
}
/** 立即显示伤害效果 */
private showDamageImmediate(damage: number, isCrit: boolean) {
this.BUFFCOMP.in_atked();
this.atked_count++;
this.exp_add(this.uaexp);
this.power_add(this.uapw);
if (isCrit) {
this.BUFFCOMP.tooltip(4, damage.toFixed(0), damage);
console.log("暴击伤害:" + damage);
} else {
this.BUFFCOMP.tooltip(1, damage.toFixed(0), damage);
console.log("普通伤害:" + damage);
}
} }
} }