diff --git a/assets/resources/gui/role_controller.prefab b/assets/resources/gui/role_controller.prefab index 73942396..b39a17ee 100644 --- a/assets/resources/gui/role_controller.prefab +++ b/assets/resources/gui/role_controller.prefab @@ -184,7 +184,7 @@ "_lpos": { "__type__": "cc.Vec3", "x": 0, - "y": 1120, + "y": 1070, "z": 0 }, "_lrot": { @@ -196,8 +196,8 @@ }, "_lscale": { "__type__": "cc.Vec3", - "x": 1, - "y": 1, + "x": 2, + "y": 2, "z": 1 }, "_mobility": 0, @@ -234,7 +234,7 @@ "_lpos": { "__type__": "cc.Vec3", "x": 0, - "y": 0, + "y": -50.705, "z": 0 }, "_lrot": { @@ -275,7 +275,7 @@ "_contentSize": { "__type__": "cc.Size", "width": 200, - "height": 100 + "height": 200 }, "_anchorPoint": { "__type__": "cc.Vec2", @@ -305,9 +305,9 @@ "_dstBlendFactor": 4, "_color": { "__type__": "cc.Color", - "r": 255, - "g": 255, - "b": 255, + "r": 0, + "g": 0, + "b": 0, "a": 255 }, "_spriteFrame": { @@ -373,7 +373,7 @@ "_lpos": { "__type__": "cc.Vec3", "x": 0, - "y": 0, + "y": 67.606, "z": 0 }, "_lrot": { @@ -2674,6 +2674,8 @@ "__id__": 0 }, "fileId": "a2T+9jtpFDK6TbGmUuF01c", + "instance": null, + "targetOverrides": null, "nestedPrefabInstanceRoots": null }, { @@ -3667,6 +3669,8 @@ "__id__": 0 }, "fileId": "92fF6VNGhL4KGhc565gFRM", + "instance": null, + "targetOverrides": null, "nestedPrefabInstanceRoots": null }, { @@ -5593,6 +5597,8 @@ "__id__": 0 }, "fileId": "24VpHkRBxCuZkdMazUpc/Y", + "instance": null, + "targetOverrides": null, "nestedPrefabInstanceRoots": null }, { @@ -8937,6 +8943,7 @@ "__id__": 397 }, "debugMode": false, + "showMemoryPanel": true, "coins_node": null, "lv_node": null, "chou_node": null, diff --git a/assets/script/game/hero/DamageQueueComp.ts b/assets/script/game/hero/DamageQueueComp.ts index 213fd9f8..85c2f036 100644 --- a/assets/script/game/hero/DamageQueueComp.ts +++ b/assets/script/game/hero/DamageQueueComp.ts @@ -38,6 +38,7 @@ export interface DamageEvent { export class DamageQueueComp extends ecs.Comp { /** 伤害事件队列 */ damageEvents: DamageEvent[] = []; + private readIndex: number = 0; /** 队列创建时间 */ createTime: number = 0; @@ -49,7 +50,8 @@ export class DamageQueueComp extends ecs.Comp { processedCount: number = 0; reset() { - this.damageEvents = []; + this.damageEvents.length = 0; + this.readIndex = 0; this.createTime = 0; this.isProcessing = false; this.processedCount = 0; @@ -60,14 +62,13 @@ export class DamageQueueComp extends ecs.Comp { */ addDamageEvent(attrs: any, casterEid: number, s_uuid: number,ext_dmg:number=0,dmg_ratio:number=1): void { const timestamp = Date.now(); - const eventId = `${casterEid}_${s_uuid}_${timestamp}_${Math.random()}`; const damageEvent: DamageEvent = { - Attrs: attrs ? { ...attrs } : null, // 深拷贝属性数据 + Attrs: attrs || null, casterEid: casterEid, s_uuid: s_uuid, timestamp: timestamp, - eventId: eventId, + eventId: "", ext_dmg:ext_dmg, dmg_ratio:dmg_ratio, }; @@ -75,7 +76,7 @@ export class DamageQueueComp extends ecs.Comp { this.damageEvents.push(damageEvent); // 如果是第一个伤害事件,记录创建时间 - if (this.damageEvents.length === 1) { + if (this.getRemainingCount() === 1) { this.createTime = timestamp; } } @@ -84,29 +85,36 @@ export class DamageQueueComp extends ecs.Comp { * 获取下一个待处理的伤害事件 */ getNextDamageEvent(): DamageEvent | null { - if (this.damageEvents.length === 0) return null; - return this.damageEvents.shift() || null; + if (this.readIndex >= this.damageEvents.length) return null; + const event = this.damageEvents[this.readIndex]; + this.readIndex += 1; + if (this.readIndex >= 32 && this.readIndex * 2 >= this.damageEvents.length) { + this.damageEvents = this.damageEvents.slice(this.readIndex); + this.readIndex = 0; + } + return event || null; } /** * 获取队列中剩余的伤害事件数量 */ getRemainingCount(): number { - return this.damageEvents.length; + return this.damageEvents.length - this.readIndex; } /** * 检查队列是否为空 */ isEmpty(): boolean { - return this.damageEvents.length === 0; + return this.readIndex >= this.damageEvents.length; } /** * 清空队列 */ clear(): void { - this.damageEvents = []; + this.damageEvents.length = 0; + this.readIndex = 0; this.processedCount = 0; this.isProcessing = false; } @@ -115,6 +123,10 @@ export class DamageQueueComp extends ecs.Comp { * 按时间戳排序伤害事件(可选功能) */ sortByTimestamp(): void { + if (this.readIndex > 0) { + this.damageEvents = this.damageEvents.slice(this.readIndex); + this.readIndex = 0; + } this.damageEvents.sort((a, b) => a.timestamp - b.timestamp); } @@ -123,6 +135,10 @@ export class DamageQueueComp extends ecs.Comp { */ removeDuplicates(): void { const seen = new Set(); + if (this.readIndex > 0) { + this.damageEvents = this.damageEvents.slice(this.readIndex); + this.readIndex = 0; + } this.damageEvents = this.damageEvents.filter(event => { if (seen.has(event.eventId)) { return false; @@ -145,7 +161,7 @@ export class DamageQueueComp extends ecs.Comp { return { totalEvents: this.processedCount + this.damageEvents.length, processedEvents: this.processedCount, - remainingEvents: this.damageEvents.length, + remainingEvents: this.getRemainingCount(), isProcessing: this.isProcessing, createTime: this.createTime }; @@ -187,4 +203,4 @@ export class DamageQueueHelper { const damageQueue = entity.get(DamageQueueComp); return damageQueue ? damageQueue.getQueueStats() : null; } -} \ No newline at end of file +} diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index 4266a4f6..42d7493c 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -38,7 +38,7 @@ interface IntervalBuffState { } @ecs.register('HeroAttrs') export class HeroAttrsComp extends ecs.Comp { - public debugMode: boolean = true; + public debugMode: boolean = false; Ebus:any=null! // ==================== 角色基础信息 ==================== @@ -159,7 +159,9 @@ export class HeroAttrsComp extends ecs.Comp { this.hp += addValue; this.hp = Math.max(0, Math.min(this.hp, this.hp_max)); this.dirty_hp = true; // ✅ 仅标记需要更新 - mLogger.log(this.debugMode, 'HeroAttrs', ` HP变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldHp.toFixed(1)} -> ${this.hp.toFixed(1)}`); + if (this.debugMode) { + mLogger.log(this.debugMode, 'HeroAttrs', ` HP变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldHp.toFixed(1)} -> ${this.hp.toFixed(1)}`); + } } add_shield(value:number,isValue:boolean){ @@ -173,7 +175,9 @@ export class HeroAttrsComp extends ecs.Comp { if (this.shield < 0) this.shield = 0; if (this.shield_max < 0) this.shield_max = 0; this.dirty_shield = true; // 标记护盾需要更新 - mLogger.log(this.debugMode, 'HeroAttrs', ` 护盾变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldShield.toFixed(1)} -> ${this.shield.toFixed(1)}`); + if (this.debugMode) { + mLogger.log(this.debugMode, 'HeroAttrs', ` 护盾变更: ${this.hero_name}, 变化=${addValue.toFixed(1)}, ${oldShield.toFixed(1)} -> ${this.shield.toFixed(1)}`); + } } // ==================== BUFF 管理 ==================== /** @@ -225,7 +229,9 @@ export class HeroAttrsComp extends ecs.Comp { this.applyAttrChange(buffConf.buff, normalized.value, normalized.BType); - mLogger.log(this.debugMode, 'HeroAttrs', `添加Buff: ${buffConf.name}, 属性:${buffConf.buff}, 值:${normalized.value}, 时间:${duration}`); + if (this.debugMode) { + mLogger.log(this.debugMode, 'HeroAttrs', `添加Buff: ${buffConf.name}, 属性:${buffConf.buff}, 值:${normalized.value}, 时间:${duration}`); + } } /** @@ -410,7 +416,9 @@ export class HeroAttrsComp extends ecs.Comp { this.applyAttrChange(buff.attr, buff.value, buff.BType, true); buffs.splice(i, 1); - mLogger.log(this.debugMode, 'HeroAttrs', `Buff过期: 属性:${buff.attr}, 恢复值:${buff.value}`); + if (this.debugMode) { + mLogger.log(this.debugMode, 'HeroAttrs', `Buff过期: 属性:${buff.attr}, 恢复值:${buff.value}`); + } } } diff --git a/assets/script/game/hero/Mon.ts b/assets/script/game/hero/Mon.ts index 5e29e779..b15602a7 100644 --- a/assets/script/game/hero/Mon.ts +++ b/assets/script/game/hero/Mon.ts @@ -20,22 +20,51 @@ export class Monster extends ecs.Entity { // 多键对象池:Map static pools: Map = new Map(); + static readonly MAX_POOL_SIZE: number = 24; static getFromPool(path: string): Node | null { if (this.pools.has(path)) { const pool = this.pools.get(path)!; - if (pool.size() > 0) { - return pool.get(); + while (pool.size() > 0) { + const node = pool.get(); + if (node && node.isValid) { + return node; + } } } return null; } static putToPool(path: string, node: Node) { + if (!node || !node.isValid) return; if (!this.pools.has(path)) { this.pools.set(path, new NodePool()); } - this.pools.get(path)!.put(node); + const pool = this.pools.get(path)!; + if (pool.size() >= this.MAX_POOL_SIZE) { + node.destroy(); + return; + } + pool.put(node); + } + + static clearPools() { + this.pools.forEach((pool) => { + pool.clear(); + }); + this.pools.clear(); + } + + static getPoolStats() { + let total = 0; + this.pools.forEach((pool) => { + total += pool.size(); + }); + return { + paths: this.pools.size, + total, + maxPerPath: this.MAX_POOL_SIZE + }; } protected init() { diff --git a/assets/script/game/hero/MoveComp.ts b/assets/script/game/hero/MoveComp.ts index b43622e1..b64471a2 100644 --- a/assets/script/game/hero/MoveComp.ts +++ b/assets/script/game/hero/MoveComp.ts @@ -41,6 +41,10 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate private readonly minSpacingY = 30; private readonly renderSortInterval = 0.05; private renderSortElapsed = 0; + private heroMoveMatcher: ecs.IMatcher | null = null; + private heroViewMatcher: ecs.IMatcher | null = null; + private readonly renderEntries: { node: Node; frontScore: number; spawnOrder: number; eid: number }[] = []; + private renderEntryCount = 0; private readonly facConfigs: Record = { [FacSet.HERO]: { @@ -57,6 +61,20 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate } }; + private getHeroMoveMatcher(): ecs.IMatcher { + if (!this.heroMoveMatcher) { + this.heroMoveMatcher = ecs.allOf(HeroAttrsComp, HeroViewComp, MoveComp); + } + return this.heroMoveMatcher; + } + + private getHeroViewMatcher(): ecs.IMatcher { + if (!this.heroViewMatcher) { + this.heroViewMatcher = ecs.allOf(HeroAttrsComp, HeroViewComp); + } + return this.heroViewMatcher; + } + filter(): ecs.IMatcher { return ecs.allOf(MoveComp, HeroViewComp, HeroAttrsComp); } @@ -239,7 +257,7 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate const selfPriority = selfAttrs ? this.getCombatPriority(selfAttrs) : 0; let nearestAheadX = Infinity; let nearestBehindX = -Infinity; - ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp, MoveComp)).forEach(e => { + ecs.query(this.getHeroMoveMatcher()).forEach(e => { if (e === self) return; const attrs = e.get(HeroAttrsComp); const view = e.get(HeroViewComp); @@ -272,7 +290,7 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate private hasAnyActorTooClose(self: ecs.Entity, x: number, y: number): boolean { const myAttrs = self.get(HeroAttrsComp); if (!myAttrs) return false; - return ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).some(e => { + return ecs.query(this.getHeroViewMatcher()).some(e => { if (e === self) return false; const attrs = e.get(HeroAttrsComp); if (!attrs || attrs.is_dead) return false; @@ -303,7 +321,7 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate let minDis = Infinity; // 优化查询:一次遍历 - ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp)).forEach(e => { + ecs.query(this.getHeroViewMatcher()).forEach(e => { const m = e.get(HeroAttrsComp); if (m.fac !== myFac && !m.is_dead) { const v = e.get(HeroViewComp); @@ -332,8 +350,8 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate if (this.renderSortElapsed < this.renderSortInterval) return; this.renderSortElapsed = 0; - const renderList: { node: Node; frontScore: number; spawnOrder: number; eid: number }[] = []; - ecs.query(ecs.allOf(HeroAttrsComp, HeroViewComp, MoveComp)).forEach(e => { + this.renderEntryCount = 0; + ecs.query(this.getHeroMoveMatcher()).forEach(e => { const attrs = e.get(HeroAttrsComp); const actorView = e.get(HeroViewComp); const actorMove = e.get(MoveComp); @@ -343,21 +361,27 @@ export class MoveSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate actorView.node.parent = actorRoot; } const frontScore = attrs.fac === FacSet.HERO ? actorView.node.position.x : -actorView.node.position.x; - renderList.push({ - node: actorView.node, - frontScore, - spawnOrder: actorMove.spawnOrder, - eid: e.eid - }); + const entryIndex = this.renderEntryCount; + let entry = this.renderEntries[entryIndex]; + if (!entry) { + entry = { node: actorView.node, frontScore: 0, spawnOrder: 0, eid: 0 }; + this.renderEntries.push(entry); + } + entry.node = actorView.node; + entry.frontScore = frontScore; + entry.spawnOrder = actorMove.spawnOrder; + entry.eid = e.eid; + this.renderEntryCount += 1; }); + this.renderEntries.length = this.renderEntryCount; - renderList.sort((a, b) => { + this.renderEntries.sort((a, b) => { if (a.frontScore !== b.frontScore) return a.frontScore - b.frontScore; if (a.spawnOrder !== b.spawnOrder) return a.spawnOrder - b.spawnOrder; return a.eid - b.eid; }); - renderList.forEach((item, index) => { + this.renderEntries.forEach((item, index) => { item.node.setSiblingIndex(index); }); } diff --git a/assets/script/game/map/MissionComp.ts b/assets/script/game/map/MissionComp.ts index 6bcd25e6..3c63a721 100644 --- a/assets/script/game/map/MissionComp.ts +++ b/assets/script/game/map/MissionComp.ts @@ -11,6 +11,8 @@ import { UIID } from "../common/config/GameUIConfig"; import { SkillView } from "../skill/SkillView"; import { FightSet } from "../common/config/GameSet"; import { mLogger } from "../common/Logger"; +import { Monster } from "../hero/Mon"; +import { Skill } from "../skill/Skill"; const { ccclass, property } = _decorator; @@ -22,6 +24,8 @@ const { ccclass, property } = _decorator; export class MissionComp extends CCComp { @property({ tooltip: "是否启用调试日志" }) private debugMode: boolean = false; + @property({ tooltip: "是否显示战斗内存观测面板" }) + private showMemoryPanel: boolean = true; // VictoryComp:any = null; // reward:number = 0; @@ -50,6 +54,19 @@ export class MissionComp extends CCComp { } private lastTimeStr: string = ""; + private lastTimeSecond: number = -1; + private memoryLabel: Label | null = null; + private memoryRefreshTimer: number = 0; + private lastMemoryText: string = ""; + private perfDtAcc: number = 0; + private perfFrameCount: number = 0; + private heapBaseMB: number = -1; + private heapPeakMB: number = 0; + private heapTrendPerMinMB: number = 0; + private heapTrendTimer: number = 0; + private heapTrendBaseMB: number = -1; + private readonly heroViewMatcher = ecs.allOf(HeroViewComp); + private readonly skillViewMatcher = ecs.allOf(SkillView); // 记录已触发的特殊刷怪索引 private spawnedSpecialIndices: Set = new Set(); @@ -60,7 +77,7 @@ export class MissionComp extends CCComp { // this.on(GameEvent.FightEnd,this.fight_end,this) this.on(GameEvent.MissionEnd,this.mission_end,this) this.on(GameEvent.DO_AD_BACK,this.do_ad,this) - + this.initMemoryPanel() } protected update(dt: number): void { if(!smc.mission.play) return @@ -73,12 +90,16 @@ export class MissionComp extends CCComp { // 检查特殊刷怪时间 this.checkSpecialSpawns(smc.vmdata.mission_data.fight_time); this.update_time(); + this.updateMemoryPanel(dt); } } update_time(){ - let time = Math.max(0, this.FightTime); - let m = Math.floor(time / 60); - let s = Math.floor(time % 60); + const time = Math.max(0, this.FightTime); + const remainSecond = Math.floor(time); + if (remainSecond === this.lastTimeSecond) return; + this.lastTimeSecond = remainSecond; + let m = Math.floor(remainSecond / 60); + let s = remainSecond % 60; let str = `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`; if(str != this.lastTimeStr){ this.time_node.getChildByName("time").getComponent(Label).string = str; @@ -99,6 +120,77 @@ export class MissionComp extends CCComp { }); } + private initMemoryPanel() { + if (!this.showMemoryPanel || !this.time_node) return; + let panel = this.time_node.getChildByName("mem_panel"); + if (!panel) { + panel = new Node("mem_panel"); + panel.parent = this.time_node; + panel.setPosition(0, -32, 0); + } + let label = panel.getComponent(Label); + if (!label) { + label = panel.addComponent(Label); + } + label.fontSize = 16; + label.lineHeight = 20; + this.memoryLabel = label; + } + + private updateMemoryPanel(dt: number) { + if (!this.showMemoryPanel || !this.memoryLabel) return; + this.perfDtAcc += dt; + this.perfFrameCount += 1; + this.memoryRefreshTimer += dt; + if (this.memoryRefreshTimer < 0.5) return; + this.memoryRefreshTimer = 0; + let heroCount = 0; + ecs.query(this.heroViewMatcher).forEach(() => { + heroCount++; + }); + let skillCount = 0; + ecs.query(this.skillViewMatcher).forEach(() => { + skillCount++; + }); + const monPool = Monster.getPoolStats(); + const skillPool = Skill.getPoolStats(); + const perf = (globalThis as any).performance; + const heapBytes = perf && perf.memory ? perf.memory.usedJSHeapSize : 0; + let heapMB = heapBytes > 0 ? heapBytes / 1024 / 1024 : -1; + if (heapMB > 0 && this.heapBaseMB < 0) { + this.heapBaseMB = heapMB; + this.heapPeakMB = heapMB; + this.heapTrendBaseMB = heapMB; + this.heapTrendTimer = 0; + } + if (heapMB > this.heapPeakMB) { + this.heapPeakMB = heapMB; + } + this.heapTrendTimer += 0.5; + if (heapMB > 0 && this.heapTrendBaseMB > 0 && this.heapTrendTimer >= 10) { + const deltaMB = heapMB - this.heapTrendBaseMB; + this.heapTrendPerMinMB = (deltaMB / this.heapTrendTimer) * 60; + this.heapTrendBaseMB = heapMB; + this.heapTrendTimer = 0; + } + const heapText = heapMB > 0 ? heapMB.toFixed(1) : "N/A"; + const heapDeltaText = this.heapBaseMB > 0 && heapMB > 0 ? (heapMB - this.heapBaseMB).toFixed(1) : "N/A"; + const heapPeakText = this.heapPeakMB > 0 ? this.heapPeakMB.toFixed(1) : "N/A"; + const avgDt = this.perfFrameCount > 0 ? this.perfDtAcc / this.perfFrameCount : 0; + const fps = avgDt > 0 ? 1 / avgDt : 0; + this.perfDtAcc = 0; + this.perfFrameCount = 0; + const text = + `Heap:${heapText}MB Δ:${heapDeltaText} Peak:${heapPeakText}\n` + + `Trend:${this.heapTrendPerMinMB.toFixed(2)}MB/min\n` + + `Perf dt:${(avgDt * 1000).toFixed(1)}ms fps:${fps.toFixed(1)}\n` + + `Ent H:${heroCount} S:${skillCount}\n` + + `Pool M:${monPool.total}(${monPool.paths}) K:${skillPool.total}(${skillPool.paths})`; + if (text === this.lastMemoryText) return; + this.lastMemoryText = text; + this.memoryLabel.string = text; + } + //奖励发放 do_reward(){ @@ -180,6 +272,7 @@ do_ad(){ this.scheduleOnce(() => { smc.mission.play=false this.cleanComponents() + this.clearBattlePools() }, 0.5) } @@ -188,6 +281,7 @@ do_ad(){ // 合并 FightEnd 逻辑:清理组件、停止游戏循环 smc.mission.play=false this.cleanComponents() + this.clearBattlePools() this.node.active=false } @@ -205,6 +299,17 @@ do_ad(){ this.rewards=[] // 改为数组,用于存储掉落物品列表 this.revive_times = 1; // 每次任务开始重置复活次数 this.spawnedSpecialIndices.clear(); // 重置特殊刷怪记录 + this.lastTimeStr = ""; + this.lastTimeSecond = -1; + this.memoryRefreshTimer = 0; + this.lastMemoryText = ""; + this.perfDtAcc = 0; + this.perfFrameCount = 0; + this.heapBaseMB = -1; + this.heapPeakMB = 0; + this.heapTrendPerMinMB = 0; + this.heapTrendTimer = 0; + this.heapTrendBaseMB = -1; // 重置全局属性加成和主角引用 (确保新一局数据干净) // smc.role = null; @@ -217,14 +322,19 @@ do_ad(){ private cleanComponents() { // 优化销毁顺序:直接销毁实体,让ECS系统自动处理组件清理 // 这样可以避免在组件reset方法中访问已经被销毁的实体引用 - ecs.query(ecs.allOf(HeroViewComp)).forEach(entity => { + ecs.query(this.heroViewMatcher).forEach(entity => { entity.destroy(); }); - ecs.query(ecs.allOf(SkillView)).forEach(entity => { + ecs.query(this.skillViewMatcher).forEach(entity => { entity.destroy(); }); } + + private clearBattlePools() { + Monster.clearPools(); + Skill.clearPools(); + } /** 视图层逻辑代码分离演示 */ @@ -233,4 +343,4 @@ do_ad(){ reset() { this.node.destroy(); } -} \ No newline at end of file +} diff --git a/assets/script/game/skill/Skill.ts b/assets/script/game/skill/Skill.ts index 453cc84c..859df3a5 100644 --- a/assets/script/game/skill/Skill.ts +++ b/assets/script/game/skill/Skill.ts @@ -19,6 +19,7 @@ export class Skill extends ecs.Entity { private debugMode: boolean = false; /** 多键对象池:Map */ static pools: Map = new Map(); + static readonly MAX_POOL_SIZE: number = 64; static getFromPool(path: string): Node | null { if (this.pools.has(path)) { @@ -38,7 +39,31 @@ export class Skill extends ecs.Entity { if (!this.pools.has(path)) { this.pools.set(path, new NodePool()); } - this.pools.get(path)!.put(node); + const pool = this.pools.get(path)!; + if (pool.size() >= this.MAX_POOL_SIZE) { + node.destroy(); + return; + } + pool.put(node); + } + + static clearPools() { + this.pools.forEach((pool) => { + pool.clear(); + }); + this.pools.clear(); + } + + static getPoolStats() { + let total = 0; + this.pools.forEach((pool) => { + total += pool.size(); + }); + return { + paths: this.pools.size, + total, + maxPerPath: this.MAX_POOL_SIZE + }; } /** ---------- 数据层 ---------- */ diff --git a/assets/script/game/skill/SkillView.ts b/assets/script/game/skill/SkillView.ts index cfad60f0..02e23c76 100644 --- a/assets/script/game/skill/SkillView.ts +++ b/assets/script/game/skill/SkillView.ts @@ -21,7 +21,7 @@ export class SkillView extends CCComp { atk_y: number = 0 @property({ tooltip: "是否启用调试日志" }) - private debugMode: boolean = true; + private debugMode: boolean = false; anim:Animation=null; group:number=0; @@ -65,13 +65,14 @@ export class SkillView extends CCComp { } if (this.isDisposing) return; if (!this.node || !this.node.activeInHierarchy) return; - // 安全获取双方信息用于日志 - const casterName = this.sData.caster?.ent?.get(HeroAttrsComp)?.hero_name ?? '未知施法者'; - const casterEid = this.sData.casterEid; const targetView = oCol.getComponent(HeroViewComp); - const targetName = targetView?.ent?.get(HeroAttrsComp)?.hero_name ?? '非英雄对象'; - const targetEid = targetView?.ent?.eid ?? '未知EID'; - mLogger.log(this.debugMode, 'SkillView', `[skillView] 碰撞1 [${this.sData.caster.box_group}][${casterName}][${casterEid}]的[${seCol.group}]:[${this.SConf.name}][${this.ent.eid}]碰撞了 [${oCol.group}]:[ ${targetName}][${targetEid}]`); + if (this.debugMode) { + const casterName = this.sData.caster?.ent?.get(HeroAttrsComp)?.hero_name ?? '未知施法者'; + const casterEid = this.sData.casterEid; + const targetName = targetView?.ent?.get(HeroAttrsComp)?.hero_name ?? '非英雄对象'; + const targetEid = targetView?.ent?.eid ?? '未知EID'; + mLogger.log(this.debugMode, 'SkillView', `[skillView] 碰撞1 [${this.sData.caster.box_group}][${casterName}][${casterEid}]的[${seCol.group}]:[${this.SConf.name}][${this.ent.eid}]碰撞了 [${oCol.group}]:[ ${targetName}][${targetEid}]`); + } if (oCol.group === seCol.group) return; if (this.pendingDisableCollider) return; if (this.sData.hit_count >= this.sData.max_hit_count) { @@ -91,7 +92,9 @@ export class SkillView extends CCComp { return; } let model = targetView.ent.get(HeroAttrsComp); - mLogger.log(this.debugMode, 'SkillView', `[skillView] 碰撞3`, oCol.group, seCol.group, model); + if (this.debugMode) { + mLogger.log(this.debugMode, 'SkillView', `[skillView] 碰撞3`, oCol.group, seCol.group, model); + } if (!model) return; if (model.is_dead) return; if (this.sData.fac == model.fac) return; @@ -126,11 +129,11 @@ export class SkillView extends CCComp { if (!target.ent) return; if (!this.sData) return; if (!this.SConf) return; - // 安全获取名称,防止实体销毁导致的空指针异常 - const casterName = this.sData.caster?.ent?.get(HeroAttrsComp)?.hero_name ?? "未知施法者"; - const targetName = target.ent.get(HeroAttrsComp)?.hero_name ?? "未知目标"; - - mLogger.log(this.debugMode, 'SkillView', `[skillView] 伤害 [${this.group}][${casterName}][${this.sData.casterEid}]的 [${this.SConf.name}]对 [${target.box_group}][ ${targetName}][${target.ent.eid}]`); + if (this.debugMode) { + const casterName = this.sData.caster?.ent?.get(HeroAttrsComp)?.hero_name ?? "未知施法者"; + const targetName = target.ent.get(HeroAttrsComp)?.hero_name ?? "未知目标"; + mLogger.log(this.debugMode, 'SkillView', `[skillView] 伤害 [${this.group}][${casterName}][${this.sData.casterEid}]的 [${this.SConf.name}]对 [${target.box_group}][ ${targetName}][${target.ent.eid}]`); + } // 使用伤害队列系统处理伤害 DamageQueueHelper.addDamageToEntity( target.ent,