diff --git a/assets/script/game/hero/HSkillSystem.ts b/assets/script/game/hero/HSkillSystem.ts index a895e122..7f4f9785 100644 --- a/assets/script/game/hero/HSkillSystem.ts +++ b/assets/script/game/hero/HSkillSystem.ts @@ -52,7 +52,6 @@ export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEn * 过滤器:拥有技能数据 + 施法请求的实体 */ filter(): ecs.IMatcher { - console.log("[SkillCastSystem] filter"); return ecs.allOf(HeroSkillsComp, HeroAttrsComp, CastSkillRequestComp); } @@ -187,7 +186,6 @@ export class SkillCastSystem extends ecs.ComblockSystem implements ecs.IEntityEn export class SkillCDSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { filter(): ecs.IMatcher { - console.log("[SkillCDSystem] filter"); return ecs.allOf(HeroSkillsComp); } @@ -218,7 +216,6 @@ export class SkillCDSystem extends ecs.ComblockSystem implements ecs.ISystemUpda export class SkillAutocastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate { filter(): ecs.IMatcher { - console.log("[SkillAutocastSystem] filter"); return ecs.allOf(HeroSkillsComp, HeroAttrsComp, HeroViewComp); } @@ -226,7 +223,6 @@ export class SkillAutocastSystem extends ecs.ComblockSystem implements ecs.ISyst const skillsData = e.get(HeroSkillsComp); const heroModel = e.get(HeroAttrsComp); const heroView = e.get(HeroViewComp); - console.log("[SkillAutocastSystem] update"); if (!skillsData || !heroModel || !heroView) return; // 检查基本条件 diff --git a/assets/script/game/hero/Hero.ts b/assets/script/game/hero/Hero.ts index 0b474468..36c05dcb 100644 --- a/assets/script/game/hero/Hero.ts +++ b/assets/script/game/hero/Hero.ts @@ -114,6 +114,7 @@ export class Hero extends ecs.Entity { } +@ecs.register('HeroLifecycleSystem') export class HeroLifecycleSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem { @@ -123,11 +124,21 @@ export class HeroLifecycleSystem extends ecs.ComblockSystem entityEnter(e: ecs.Entity): void { // 英雄实体创建时的特殊处理 - console.log(`英雄进入世界: ${e.get(HeroAttrsComp).hero_name}`); + const heroAttrs = e.get(HeroAttrsComp); + if (heroAttrs) { + console.log(`英雄进入世界: ${heroAttrs.hero_name}`); + } else { + console.log(`英雄进入世界: 实体ID ${e.eid}`); + } } entityRemove(e: ecs.Entity): void { // 英雄实体销毁时的清理工作 - console.log(`英雄离开世界: ${e.get(HeroAttrsComp).hero_name}`); + const heroAttrs = e.get(HeroAttrsComp); + if (heroAttrs) { + console.log(`英雄离开世界: ${heroAttrs.hero_name}`); + } else { + console.log(`英雄离开世界: 实体ID ${e.eid}`); + } } } \ No newline at end of file diff --git a/assets/script/game/hero/HeroAtk.ts b/assets/script/game/hero/HeroAtk.ts index cee7649d..54977ee0 100644 --- a/assets/script/game/hero/HeroAtk.ts +++ b/assets/script/game/hero/HeroAtk.ts @@ -16,6 +16,7 @@ export class HeroAtkComp extends ecs.Comp { } /** 业务层业务逻辑处理对象 */ +@ecs.register('HeroAtkSystem') export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate, ecs.IEntityEnterSystem { private debugMode: boolean = false; // 是否启用调试模式 diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index 4eff9d23..f7f714ca 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -392,9 +392,11 @@ export class HeroAttrsComp extends ecs.Comp { * 2. 每帧更新 HP/MP 自然回复 * 3. 限制属性值在合理范围内 * +/** * 使用方式: * 在 RootSystem 中注册此系统,它会自动每帧更新所有拥有 HeroAttrsComp 的实体 */ +@ecs.register('HeroAttrSystem') export class HeroAttrSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate, ecs.IEntityEnterSystem, ecs.ISystemFirstUpdate { diff --git a/assets/script/game/hero/HeroMove.ts b/assets/script/game/hero/HeroMove.ts index c18adba4..04680f7f 100644 --- a/assets/script/game/hero/HeroMove.ts +++ b/assets/script/game/hero/HeroMove.ts @@ -159,7 +159,10 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd /** 找到最近的敌人 */ private findNearestEnemy(entity: ecs.Entity): HeroViewComp | null { - const currentPos = entity.get(HeroViewComp).node.position; + const currentView = entity.get(HeroViewComp); + if (!currentView || !currentView.node) return null; + + const currentPos = currentView.node.position; const team = entity.get(HeroAttrsComp).fac; let nearestEnemyView: HeroViewComp | null = null; let minDistance = Infinity; @@ -167,7 +170,7 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).forEach(e => { const model = e.get(HeroAttrsComp); const view = e.get(HeroViewComp); - if (model.fac !== team && !model.is_dead) { + if (model.fac !== team && !model.is_dead && view && view.node) { const distance = Math.abs(currentPos.x - view.node.position.x); if (distance < minDistance) { minDistance = distance; @@ -181,12 +184,16 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd /** 检测攻击范围内敌人 */ private checkEnemiesInRange(entity: ecs.Entity, range: number): boolean { - const currentPos = entity.get(HeroViewComp).node.position; + const currentView = entity.get(HeroViewComp); + if (!currentView || !currentView.node) return false; + + const currentPos = currentView.node.position; const team = entity.get(HeroAttrsComp).fac; let found = false; ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).some(e => { const model = e.get(HeroAttrsComp); const view = e.get(HeroViewComp); + if (!view || !view.node) return false; const distance = Math.abs(currentPos.x - view.node.position.x); if (model.fac !== team && !model.is_dead) { if (distance <= range) { @@ -200,12 +207,16 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd /** 检测面前是否有敌人 */ private checkEnemiesInFace(entity: ecs.Entity): boolean { - const currentPos = entity.get(HeroViewComp).node.position; + const currentView = entity.get(HeroViewComp); + if (!currentView || !currentView.node) return false; + + const currentPos = currentView.node.position; const team = entity.get(HeroAttrsComp).fac; let found = false; ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).some(e => { const model = e.get(HeroAttrsComp); const view = e.get(HeroViewComp); + if (!view || !view.node) return false; const distance = Math.abs(currentPos.x - view.node.position.x); if (model.fac !== team && !model.is_dead) { if (distance <= 75) { @@ -232,8 +243,11 @@ export class HeroMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpd // 按x坐标排序:x坐标越大(越前面)的显示在上层 const sortedUnits = allUnits.sort((a, b) => { - const posA = a.get(HeroViewComp).node.position.x; - const posB = b.get(HeroViewComp).node.position.x; + 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坐标从小到大排序 }); diff --git a/assets/script/game/hero/Mon.ts b/assets/script/game/hero/Mon.ts index 5895c7d1..019ce19a 100644 --- a/assets/script/game/hero/Mon.ts +++ b/assets/script/game/hero/Mon.ts @@ -101,6 +101,7 @@ export class Monster extends ecs.Entity { } } +@ecs.register('MonLifecycleSystem') export class MonLifecycleSystem extends ecs.ComblockSystem implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem { @@ -110,11 +111,21 @@ export class MonLifecycleSystem extends ecs.ComblockSystem entityEnter(e: ecs.Entity): void { // 怪物实体创建时的特殊处理 - console.log(`怪物进入世界: ${e.get(HeroAttrsComp).hero_name}`); + const heroAttrs = e.get(HeroAttrsComp); + if (heroAttrs) { + console.log(`怪物进入世界: ${heroAttrs.hero_name}`); + } else { + console.log(`怪物进入世界: 实体ID ${e.eid}`); + } } entityRemove(e: ecs.Entity): void { // 怪物实体销毁时的清理工作 - console.log(`怪物离开世界: ${e.get(HeroAttrsComp).hero_name}`); + const heroAttrs = e.get(HeroAttrsComp); + if (heroAttrs) { + console.log(`怪物离开世界: ${heroAttrs.hero_name}`); + } else { + console.log(`怪物离开世界: 实体ID ${e.eid}`); + } } } \ No newline at end of file diff --git a/assets/script/game/hero/MonMove.ts b/assets/script/game/hero/MonMove.ts index a4a77dfa..71530a16 100644 --- a/assets/script/game/hero/MonMove.ts +++ b/assets/script/game/hero/MonMove.ts @@ -88,12 +88,16 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda /** 检测攻击范围内敌人 */ private checkEnemiesInRange(entity: ecs.Entity, range: number): boolean { - const currentPos = entity.get(HeroViewComp).node.position; + const currentView = entity.get(HeroViewComp); + if (!currentView || !currentView.node) return false; + + const currentPos = currentView.node.position; const team = entity.get(HeroAttrsComp).fac; let found = false; ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).some(e => { const model = e.get(HeroAttrsComp); const view = e.get(HeroViewComp); + if (!view || !view.node) return false; const distance = Math.abs(currentPos.x - view.node.position.x); if (model.fac !== team && !model.is_dead) { if (distance <= range) { @@ -107,12 +111,16 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda /** 检测面前是否有敌人 */ private checkEnemiesInFace(entity: ecs.Entity): boolean { - const currentPos = entity.get(HeroViewComp).node.position; + const currentView = entity.get(HeroViewComp); + if (!currentView || !currentView.node) return false; + + const currentPos = currentView.node.position; const team = entity.get(HeroAttrsComp).fac; let found = false; ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).some(e => { const model = e.get(HeroAttrsComp); const view = e.get(HeroViewComp); + if (!view || !view.node) return false; const distance = Math.abs(currentPos.x - view.node.position.x); if (model.fac !== team && !model.is_dead) { if (distance <= 75) { @@ -139,8 +147,11 @@ export class MonMoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpda // 按x坐标排序:x坐标越大(越前面)的显示在上层 const sortedUnits = allUnits.sort((a, b) => { - const posA = a.get(HeroViewComp).node.position.x; - const posB = b.get(HeroViewComp).node.position.x; + 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坐标从小到大排序 }); diff --git a/assets/script/game/hero/SkillConComp.ts b/assets/script/game/hero/SkillConComp.ts deleted file mode 100644 index b6c4f3ef..00000000 --- a/assets/script/game/hero/SkillConComp.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { _decorator, Component, Node, ProgressBar, v3, Vec3 } from 'cc'; -import { HeroViewComp } from './HeroViewComp'; -import { SkillSet, SType, TGroup, } from '../common/config/SkillSet'; -import { ecs } from 'db://oops-framework/libs/ecs/ECS'; -import { GameEvent } from '../common/config/GameEvent'; -import { FacSet } from '../common/config/BoxSet'; -import { smc } from '../common/SingletonModuleComp'; -import { CCComp } from 'db://oops-framework/module/common/CCComp'; -import { HeroAttrsComp } from './HeroAttrsComp'; -import { HeroSkillsComp } from './HeroSkills'; -import { CastSkillRequestComp } from './HSkillSystem'; -import { SkillEnt } from '../skill/SkillEnt'; -import { Attrs } from '../common/config/HeroAttrs'; -import { TalComp } from './TalComp'; -const { ccclass, property } = _decorator; - -@ccclass('SkillCon') -@ecs.register('SkillCon') -export class SkillConComp extends CCComp { - HeroView:any=null; - HeroEntity:any=null; - skill_cd=0 - private _timers: { [key: string]: any } = {}; - init(): void { - this.on(GameEvent.FightEnd, this.clear_timer, this); - } - onLoad(){ - this.HeroView=this.node.getComponent(HeroViewComp) - } - start() { - this.HeroEntity=this.HeroView.ent - } - - /** - * ⚠️ 注意:此方法已废弃 - * 技能CD更新和施法逻辑已迁移到 HSkillSystem(SkillCDSystem + SkillAutocastSystem) - * 保留此方法仅用于手动触发技能(如玩家点击技能按钮) - */ - update(dt: number) { - // 已由 SkillCDSystem 和 SkillAutocastSystem 处理 - // 此方法可以删除或改为手动施法的入口 - } - - /** - * 手动施放技能(玩家点击技能按钮) - * @param skillIndex 技能索引 - */ - manualCastSkill(skillIndex: number) { - if (!this.HeroEntity) return; - - // 选择目标 - const targets = this.selectTargets(1); - - // ✅ 通过添加标记组件请求施法 - const request = this.HeroEntity.add(CastSkillRequestComp) as CastSkillRequestComp; - request.skillIndex = skillIndex; - request.targetPositions = targets; - } - - - /** 施放技能 */ - castSkill(config: typeof SkillSet[keyof typeof SkillSet]) { - let wfuny=this.check_wfuny() - let dmg=0 - this.doSkill(config,wfuny,dmg); - } - - - private doSkill(config: typeof SkillSet[keyof typeof SkillSet],is_wfuny:boolean=false,dmg:number=0) { - // 添加节点有效性检查 - if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) { - return; - } - let targets:any=null - if(config.TGroup==TGroup.Self){ - targets = [this.node.position] - } - if(config.TGroup==TGroup.Enemy){ - targets = this.selectTargets(config.t_num) - } - this.HeroView.playSkillEffect(config.uuid) - const sEnt = ecs.getEntity(SkillEnt); - const timerId = setTimeout(() => { - // 再次检查节点有效性 - if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) { - return; - } - console.log("技能开始",sEnt) - sEnt.load( - this.node.position, - this.node.parent, - config.uuid, - targets, - this.HeroView, - dmg - ); - }, 300); - if(is_wfuny){ - this.scheduleOnce(()=>{ - this.doSkill(config,false,dmg) - },0.1) - } - // 保存定时器ID - this._timers[`skill_${config.uuid}`] = timerId; - } - - check_wfuny(){ - let random = Math.random()*100 - if(random < this.HeroView.Attrs[Attrs.WFUNY]){ - return true - } - return false - } - - check_target(){ - if(this.HeroView.fac==FacSet.HERO){ - return ecs.query(ecs.allOf(HeroAttrsComp)) - }else{ - return ecs.query(ecs.allOf(HeroAttrsComp)) - } - } - get_front(entities:any){ - let keyPos = this.HeroView.fac==FacSet.HERO ? - Math.min(...entities.map(e => e.get(HeroViewComp).node.position.x)) : - Math.max(...entities.map(e => e.get(HeroViewComp).node.position.x)); - let keyEntity = entities.find(e => e.get(HeroViewComp).node.position.x === keyPos); - return keyEntity.get(HeroViewComp).node.position; - } - /** - * 选择目标(整合版) - * @param t_num 目标数量,第一个是最近的前排,后续随机(可重复) - * @returns 目标坐标数组 - */ - private selectTargets(t_num: number): Vec3[] { - const targets: Vec3[] = []; - const entities = this.check_target(); - - // 如果没有目标实体 - if (entities.length === 0) { - const defaultPos = this.HeroView.fac === FacSet.HERO ? v3(400, 0, 0) : v3(-400, 0, 0); - // 返回t_num个相同的默认位置 - for (let i = 0; i < t_num; i++) { - targets.push(defaultPos.clone()); - } - return targets; - } - - // 第一个目标:最前排(离施法者最近的) - const frontPos = this.get_front(entities); - targets.push(v3(frontPos.x, frontPos.y, 0)); - - // 后续目标:随机选择(可以重复) - for (let i = 1; i < t_num; i++) { - const randomEntity = entities[Math.floor(Math.random() * entities.length)]; - const randomPos = randomEntity.get(HeroViewComp).node.position; - targets.push(v3(randomPos.x, randomPos.y, 0)); - } - - return targets; - } - - public clear_timer() { - // console.log("[SkillConComp]:clear_timer",this.HeroView); - - Object.values(this._timers).forEach(clearTimeout); - } - - reset() { - this.clear_timer(); - } - onDestroy() { - // 清理所有定时器 - // console.log("[SkillConComp]:onDestroy:",this.node.name) - Object.values(this._timers).forEach(clearTimeout); - this._timers = {}; - // 移除事件监听 - this.off(GameEvent.CastHeroSkill); - } -} - - diff --git a/assets/script/game/hero/SkillConComp.ts.meta b/assets/script/game/hero/SkillConComp.ts.meta deleted file mode 100644 index 521d4e18..00000000 --- a/assets/script/game/hero/SkillConComp.ts.meta +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ver": "4.0.24", - "importer": "typescript", - "imported": true, - "uuid": "6f882a1f-6f5a-4ef5-9ea0-21a0192c2785", - "files": [], - "subMetas": {}, - "userData": {} -} diff --git a/assets/script/game/hero/TalComp.ts b/assets/script/game/hero/TalComp.ts index af8d6ce1..ac61afcf 100644 --- a/assets/script/game/hero/TalComp.ts +++ b/assets/script/game/hero/TalComp.ts @@ -5,7 +5,6 @@ import { ItalConf, TalType, TalEType, talConf } from "../common/config/TalSet"; import { BuffConf, SkillSet } from "../common/config/SkillSet"; import { HeroInfo } from "../common/config/heroSet"; import { HeroViewComp } from "./HeroViewComp"; -import { SkillConComp } from "./SkillConComp"; const { ccclass } = _decorator; @@ -60,7 +59,6 @@ export class TalComp extends ecs.Comp { start() { // 运行时获取组件,避免编译时循环引用 this.heroView = this.ent.get(HeroViewComp); - this.skillCon = this.ent.get(SkillConComp); if (this.heroView) { this.heroUuid = this.heroView.hero_uuid; this.initializeTalents();