From 4af9a6fd9e48bc5a0fd58d1d3a97c53f6e7306cd Mon Sep 17 00:00:00 2001 From: walkpan Date: Sat, 15 Nov 2025 10:52:39 +0800 Subject: [PATCH] =?UTF-8?q?refactor(hero):=20=E9=87=8D=E6=9E=84=E8=8B=B1?= =?UTF-8?q?=E9=9B=84=E5=B1=9E=E6=80=A7=E7=B3=BB=E7=BB=9F=E4=B8=8E=E5=8F=97?= =?UTF-8?q?=E5=87=BB=E7=89=B9=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将HeroAttrSystem从HeroAttrsComp中分离为独立文件 删除废弃的05-outline-glow资源文件 优化TalComp.ts中的代码格式 使用FlashSprite替换旧的受击特效实现 --- assets/resources/game/05-outline-glow.meta | 9 - .../resources/game/05-outline-glow/.DS_Store | Bin 6148 -> 0 bytes .../game/05-outline-glow/materials.meta | 1 - .../materials/outline-glow.mtl | 41 ----- .../materials/outline-glow.mtl.meta | 1 - .../materials/outline-glow2.mtl | 40 ----- .../materials/outline-glow2.mtl.meta | 1 - .../game/05-outline-glow/shaders.meta | 1 - .../builtin-sprite-outline-glow.effect | 169 ------------------ .../builtin-sprite-outline-glow.effect.meta | 15 -- .../builtin-sprite-outline-glow2.effect | 169 ------------------ .../builtin-sprite-outline-glow2.effect.meta | 1 - assets/script/game/hero/HeroAttrsComp.ts | 127 +------------ assets/script/game/hero/HeroAttrsSystem.ts | 128 +++++++++++++ .../script/game/hero/HeroAttrsSystem.ts.meta | 1 + assets/script/game/hero/HeroViewComp.ts | 18 +- assets/script/game/hero/TalComp.ts | 4 +- assets/script/game/map/FlashSprite.ts | 29 --- assets/script/game/map/FlashSprite.ts.meta | 9 - 19 files changed, 144 insertions(+), 620 deletions(-) delete mode 100644 assets/resources/game/05-outline-glow.meta delete mode 100644 assets/resources/game/05-outline-glow/.DS_Store delete mode 100644 assets/resources/game/05-outline-glow/materials.meta delete mode 100644 assets/resources/game/05-outline-glow/materials/outline-glow.mtl delete mode 100644 assets/resources/game/05-outline-glow/materials/outline-glow.mtl.meta delete mode 100644 assets/resources/game/05-outline-glow/materials/outline-glow2.mtl delete mode 100644 assets/resources/game/05-outline-glow/materials/outline-glow2.mtl.meta delete mode 100644 assets/resources/game/05-outline-glow/shaders.meta delete mode 100644 assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow.effect delete mode 100644 assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow.effect.meta delete mode 100644 assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow2.effect delete mode 100644 assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow2.effect.meta create mode 100644 assets/script/game/hero/HeroAttrsSystem.ts create mode 100644 assets/script/game/hero/HeroAttrsSystem.ts.meta delete mode 100644 assets/script/game/map/FlashSprite.ts delete mode 100644 assets/script/game/map/FlashSprite.ts.meta diff --git a/assets/resources/game/05-outline-glow.meta b/assets/resources/game/05-outline-glow.meta deleted file mode 100644 index f2e12717..00000000 --- a/assets/resources/game/05-outline-glow.meta +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ver": "1.2.0", - "importer": "directory", - "imported": true, - "uuid": "af691440-7aca-4cb5-9a78-9bfed9cb70de", - "files": [], - "subMetas": {}, - "userData": {} -} diff --git a/assets/resources/game/05-outline-glow/.DS_Store b/assets/resources/game/05-outline-glow/.DS_Store deleted file mode 100644 index 41d5bb343da44e73e3b245e5dcd4b476f995bac3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-ve05I)n2ma*FyedJ|6397S1W(;gG^xMUs!@K`~q%qvx6a&*>= zh`G3T;ZmC?X44fF^O-Q8pT(|J0>D@ko_yd2kB3%`Q1ahwb2Q_x5`_7_}=kKx`hX88h`2)cmif$5Kc Mmq8m<;7=9!2Civ`VgLXD diff --git a/assets/resources/game/05-outline-glow/materials.meta b/assets/resources/game/05-outline-glow/materials.meta deleted file mode 100644 index 67e789b0..00000000 --- a/assets/resources/game/05-outline-glow/materials.meta +++ /dev/null @@ -1 +0,0 @@ -{"ver":"1.2.0","importer":"directory","imported":true,"uuid":"551a2611-69c0-45ae-bfc6-37f056a34b33","files":[],"subMetas":{},"userData":{}} diff --git a/assets/resources/game/05-outline-glow/materials/outline-glow.mtl b/assets/resources/game/05-outline-glow/materials/outline-glow.mtl deleted file mode 100644 index dce6b77f..00000000 --- a/assets/resources/game/05-outline-glow/materials/outline-glow.mtl +++ /dev/null @@ -1,41 +0,0 @@ -{ - "__type__": "cc.Material", - "_name": "", - "_objFlags": 0, - "__editorExtras__": {}, - "_native": "", - "_effectAsset": { - "__uuid__": "cfeeea4f-db9c-42cd-a0f7-fc5cb37bd3d7", - "__expectedType__": "cc.EffectAsset" - }, - "_techIdx": 0, - "_defines": [ - { - "USE_TEXTURE": true - } - ], - "_states": [ - { - "rasterizerState": {}, - "depthStencilState": {}, - "blendState": { - "targets": [ - {} - ] - } - } - ], - "_props": [ - { - "glowColor": { - "__type__": "cc.Color", - "r": 0, - "g": 0, - "b": 0, - "a": 255 - }, - "glowWidth": 0.003, - "glowThreshold": 0.645 - } - ] -} \ No newline at end of file diff --git a/assets/resources/game/05-outline-glow/materials/outline-glow.mtl.meta b/assets/resources/game/05-outline-glow/materials/outline-glow.mtl.meta deleted file mode 100644 index 1357534f..00000000 --- a/assets/resources/game/05-outline-glow/materials/outline-glow.mtl.meta +++ /dev/null @@ -1 +0,0 @@ -{"ver":"1.0.21","importer":"material","imported":true,"uuid":"2fcd55a9-38ca-45aa-9164-68e48aaf51ce","files":[".json"],"subMetas":{},"userData":{}} diff --git a/assets/resources/game/05-outline-glow/materials/outline-glow2.mtl b/assets/resources/game/05-outline-glow/materials/outline-glow2.mtl deleted file mode 100644 index 0cc42b69..00000000 --- a/assets/resources/game/05-outline-glow/materials/outline-glow2.mtl +++ /dev/null @@ -1,40 +0,0 @@ -{ - "__type__": "cc.Material", - "_name": "", - "_objFlags": 0, - "__editorExtras__": {}, - "_native": "", - "_effectAsset": { - "__uuid__": "40c25c17-db22-4ae7-8d3a-f73cbb6d36ba", - "__expectedType__": "cc.EffectAsset" - }, - "_techIdx": 0, - "_defines": [ - { - "USE_TEXTURE": true - } - ], - "_states": [ - { - "rasterizerState": {}, - "depthStencilState": {}, - "blendState": { - "targets": [ - {} - ] - } - } - ], - "_props": [ - { - "glowColor": { - "__type__": "cc.Color", - "r": 255, - "g": 235, - "b": 0, - "a": 255 - }, - "glowWidth": 0.002 - } - ] -} \ No newline at end of file diff --git a/assets/resources/game/05-outline-glow/materials/outline-glow2.mtl.meta b/assets/resources/game/05-outline-glow/materials/outline-glow2.mtl.meta deleted file mode 100644 index 3edca7ef..00000000 --- a/assets/resources/game/05-outline-glow/materials/outline-glow2.mtl.meta +++ /dev/null @@ -1 +0,0 @@ -{"ver":"1.0.21","importer":"material","imported":true,"uuid":"974af3c9-d7ee-449f-a5df-cd8e2dd49188","files":[".json"],"subMetas":{},"userData":{}} diff --git a/assets/resources/game/05-outline-glow/shaders.meta b/assets/resources/game/05-outline-glow/shaders.meta deleted file mode 100644 index d5b5f1bb..00000000 --- a/assets/resources/game/05-outline-glow/shaders.meta +++ /dev/null @@ -1 +0,0 @@ -{"ver":"1.2.0","importer":"directory","imported":true,"uuid":"7d369c63-9191-4323-abcc-edda5799a410","files":[],"subMetas":{},"userData":{}} diff --git a/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow.effect b/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow.effect deleted file mode 100644 index beb5620f..00000000 --- a/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow.effect +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. -CCEffect %{ - techniques: - - passes: - - vert: sprite-vs:vert - frag: sprite-fs:frag - depthStencilState: - depthTest: false - depthWrite: false - blendState: - targets: - - blend: true - blendSrc: src_alpha - blendDst: one_minus_src_alpha - blendDstAlpha: one_minus_src_alpha - rasterizerState: - cullMode: none - properties: - alphaThreshold: { value: 0.5 } - - glowColor: { value: [1, 1, 1, 1], editor: { type: color } } - glowWidth: { value: 0.05, editor: { slide: true, range: [0, 0.3], step: 0.001 } } - glowThreshold: { value: 1, editor: { slide: true, range: [0, 1], step: 0.001 } } -}% - -CCProgram sprite-vs %{ - precision highp float; - #include - #if USE_LOCAL - #include - #endif - #if SAMPLE_FROM_RT - #include - #endif - in vec3 a_position; - in vec2 a_texCoord; - in vec4 a_color; - - out vec4 color; - out vec2 uv0; - - vec4 vert () { - vec4 pos = vec4(a_position, 1); - - #if USE_LOCAL - pos = cc_matWorld * pos; - #endif - - #if USE_PIXEL_ALIGNMENT - pos = cc_matView * pos; - pos.xyz = floor(pos.xyz); - pos = cc_matProj * pos; - #else - pos = cc_matViewProj * pos; - #endif - - uv0 = a_texCoord; - #if SAMPLE_FROM_RT - CC_HANDLE_RT_SAMPLE_FLIP(uv0); - #endif - color = a_color; - - return pos; - } -}% - -CCProgram sprite-fs %{ - precision highp float; - #include - #include - - in vec4 color; - - uniform FSConstants { - vec4 glowColor; - float glowWidth; - float glowThreshold; - }; - - #if USE_TEXTURE - in vec2 uv0; - #pragma builtin(local) - layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; - #endif - - vec4 getTextureColor (sampler2D mainTexture, vec2 uv) { - if (uv.x > 1.0 || uv.x < 0.0 || uv.y > 1.0 || uv.y < 0.0) { - return vec4(0.0, 0.0, 0.0, 0.0); - } - return texture(mainTexture, uv); - } - - float getColorAlpha (float angle, float dist) { - // 角度转弧度,公式为:弧度 = 角度 * (pi / 180) - float radian = angle * 3.14 / 180.0; - vec2 newUV = uv0 + vec2(dist * cos(radian), dist * sin(radian)); - vec4 color = getTextureColor(cc_spriteTexture, newUV); - return color.a; - } - - float getAverageAlpha (float dist) { - float totalAlpha = 0.0; - - totalAlpha += getColorAlpha(0.0, dist); - totalAlpha += getColorAlpha(30.0, dist); - totalAlpha += getColorAlpha(60.0, dist); - totalAlpha += getColorAlpha(90.0, dist); - totalAlpha += getColorAlpha(120.0, dist); - totalAlpha += getColorAlpha(150.0, dist); - totalAlpha += getColorAlpha(180.0, dist); - totalAlpha += getColorAlpha(210.0, dist); - totalAlpha += getColorAlpha(240.0, dist); - totalAlpha += getColorAlpha(270.0, dist); - totalAlpha += getColorAlpha(300.0, dist); - totalAlpha += getColorAlpha(330.0, dist); - - return totalAlpha * 0.0833; - } - - float getGlowAlpha () { - if (glowWidth == 0.0 ) { - return 0.0; - } - - float totalAlpha = 0.0; - totalAlpha += getAverageAlpha(glowWidth * 0.1); - totalAlpha += getAverageAlpha(glowWidth * 0.2); - totalAlpha += getAverageAlpha(glowWidth * 0.3); - totalAlpha += getAverageAlpha(glowWidth * 0.4); - totalAlpha += getAverageAlpha(glowWidth * 0.5); - totalAlpha += getAverageAlpha(glowWidth * 0.6); - totalAlpha += getAverageAlpha(glowWidth * 0.7); - totalAlpha += getAverageAlpha(glowWidth * 0.8); - totalAlpha += getAverageAlpha(glowWidth * 0.9); - totalAlpha += getAverageAlpha(glowWidth * 1.0); - - return totalAlpha * 0.1; - } - - vec4 frag () { - vec4 o = vec4(1, 1, 1, 1); - - #if USE_TEXTURE - o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0); - #if IS_GRAY - float gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b; - o.r = o.g = o.b = gray; - #endif - #endif - - float alpha = getGlowAlpha(); - - if (alpha <= glowThreshold) { - alpha /= glowThreshold; - alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0; - } else { - alpha = 0.0; - } - - vec4 dstColor = glowColor * alpha; - vec4 scrColor = o; - - o = scrColor * scrColor.a + dstColor * (1.0 - scrColor.a); - - o *= color; - ALPHA_TEST(o); - return o; - } -}% diff --git a/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow.effect.meta b/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow.effect.meta deleted file mode 100644 index bdfeb08b..00000000 --- a/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow.effect.meta +++ /dev/null @@ -1,15 +0,0 @@ -{ - "ver": "1.7.1", - "importer": "effect", - "imported": true, - "uuid": "cfeeea4f-db9c-42cd-a0f7-fc5cb37bd3d7", - "files": [ - ".json" - ], - "subMetas": {}, - "userData": { - "combinations": [ - {} - ] - } -} diff --git a/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow2.effect b/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow2.effect deleted file mode 100644 index beb5620f..00000000 --- a/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow2.effect +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd. -CCEffect %{ - techniques: - - passes: - - vert: sprite-vs:vert - frag: sprite-fs:frag - depthStencilState: - depthTest: false - depthWrite: false - blendState: - targets: - - blend: true - blendSrc: src_alpha - blendDst: one_minus_src_alpha - blendDstAlpha: one_minus_src_alpha - rasterizerState: - cullMode: none - properties: - alphaThreshold: { value: 0.5 } - - glowColor: { value: [1, 1, 1, 1], editor: { type: color } } - glowWidth: { value: 0.05, editor: { slide: true, range: [0, 0.3], step: 0.001 } } - glowThreshold: { value: 1, editor: { slide: true, range: [0, 1], step: 0.001 } } -}% - -CCProgram sprite-vs %{ - precision highp float; - #include - #if USE_LOCAL - #include - #endif - #if SAMPLE_FROM_RT - #include - #endif - in vec3 a_position; - in vec2 a_texCoord; - in vec4 a_color; - - out vec4 color; - out vec2 uv0; - - vec4 vert () { - vec4 pos = vec4(a_position, 1); - - #if USE_LOCAL - pos = cc_matWorld * pos; - #endif - - #if USE_PIXEL_ALIGNMENT - pos = cc_matView * pos; - pos.xyz = floor(pos.xyz); - pos = cc_matProj * pos; - #else - pos = cc_matViewProj * pos; - #endif - - uv0 = a_texCoord; - #if SAMPLE_FROM_RT - CC_HANDLE_RT_SAMPLE_FLIP(uv0); - #endif - color = a_color; - - return pos; - } -}% - -CCProgram sprite-fs %{ - precision highp float; - #include - #include - - in vec4 color; - - uniform FSConstants { - vec4 glowColor; - float glowWidth; - float glowThreshold; - }; - - #if USE_TEXTURE - in vec2 uv0; - #pragma builtin(local) - layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture; - #endif - - vec4 getTextureColor (sampler2D mainTexture, vec2 uv) { - if (uv.x > 1.0 || uv.x < 0.0 || uv.y > 1.0 || uv.y < 0.0) { - return vec4(0.0, 0.0, 0.0, 0.0); - } - return texture(mainTexture, uv); - } - - float getColorAlpha (float angle, float dist) { - // 角度转弧度,公式为:弧度 = 角度 * (pi / 180) - float radian = angle * 3.14 / 180.0; - vec2 newUV = uv0 + vec2(dist * cos(radian), dist * sin(radian)); - vec4 color = getTextureColor(cc_spriteTexture, newUV); - return color.a; - } - - float getAverageAlpha (float dist) { - float totalAlpha = 0.0; - - totalAlpha += getColorAlpha(0.0, dist); - totalAlpha += getColorAlpha(30.0, dist); - totalAlpha += getColorAlpha(60.0, dist); - totalAlpha += getColorAlpha(90.0, dist); - totalAlpha += getColorAlpha(120.0, dist); - totalAlpha += getColorAlpha(150.0, dist); - totalAlpha += getColorAlpha(180.0, dist); - totalAlpha += getColorAlpha(210.0, dist); - totalAlpha += getColorAlpha(240.0, dist); - totalAlpha += getColorAlpha(270.0, dist); - totalAlpha += getColorAlpha(300.0, dist); - totalAlpha += getColorAlpha(330.0, dist); - - return totalAlpha * 0.0833; - } - - float getGlowAlpha () { - if (glowWidth == 0.0 ) { - return 0.0; - } - - float totalAlpha = 0.0; - totalAlpha += getAverageAlpha(glowWidth * 0.1); - totalAlpha += getAverageAlpha(glowWidth * 0.2); - totalAlpha += getAverageAlpha(glowWidth * 0.3); - totalAlpha += getAverageAlpha(glowWidth * 0.4); - totalAlpha += getAverageAlpha(glowWidth * 0.5); - totalAlpha += getAverageAlpha(glowWidth * 0.6); - totalAlpha += getAverageAlpha(glowWidth * 0.7); - totalAlpha += getAverageAlpha(glowWidth * 0.8); - totalAlpha += getAverageAlpha(glowWidth * 0.9); - totalAlpha += getAverageAlpha(glowWidth * 1.0); - - return totalAlpha * 0.1; - } - - vec4 frag () { - vec4 o = vec4(1, 1, 1, 1); - - #if USE_TEXTURE - o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0); - #if IS_GRAY - float gray = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b; - o.r = o.g = o.b = gray; - #endif - #endif - - float alpha = getGlowAlpha(); - - if (alpha <= glowThreshold) { - alpha /= glowThreshold; - alpha = -1.0 * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) * (alpha - 1.0) + 1.0; - } else { - alpha = 0.0; - } - - vec4 dstColor = glowColor * alpha; - vec4 scrColor = o; - - o = scrColor * scrColor.a + dstColor * (1.0 - scrColor.a); - - o *= color; - ALPHA_TEST(o); - return o; - } -}% diff --git a/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow2.effect.meta b/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow2.effect.meta deleted file mode 100644 index 90cf0835..00000000 --- a/assets/resources/game/05-outline-glow/shaders/builtin-sprite-outline-glow2.effect.meta +++ /dev/null @@ -1 +0,0 @@ -{"ver":"1.7.1","importer":"effect","imported":true,"uuid":"40c25c17-db22-4ae7-8d3a-f73cbb6d36ba","files":[".json"],"subMetas":{},"userData":{"combinations":[{}]}} diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index c24626d6..d6c0da25 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -1,9 +1,7 @@ -import { Timer } from "db://oops-framework/core/common/timer/Timer"; import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; -import { smc } from "../common/SingletonModuleComp"; import { Attrs, AttrsType, BType, NeAttrs } from "../common/config/HeroAttrs"; -import { BuffConf, SkillSet } from "../common/config/SkillSet"; -import { HeroInfo, AttrSet, HeroUpSet } from "../common/config/heroSet"; +import { BuffConf } from "../common/config/SkillSet"; +import { HeroInfo, AttrSet } from "../common/config/heroSet"; import { HeroSkillsComp } from "./HeroSkills"; @@ -427,124 +425,3 @@ export class HeroAttrsComp extends ecs.Comp { } } -/** - * ==================== 英雄属性更新系统 ==================== - * - * 按照 ECS 设计理念: - * - Component(HeroAttrsComp):存储数据 - * - System(HeroAttrSystem):处理业务逻辑 - * - * 系统职责: - * 1. 每帧更新临时 Buff(时间递减,过期移除) - * 2. 每帧更新 HP/MP 自然回复 - * 3. 限制属性值在合理范围内 - * -/** - * 使用方式: - * 在 RootSystem 中注册此系统,它会自动每帧更新所有拥有 HeroAttrsComp 的实体 - */ -@ecs.register('HeroAttrSystem') -export class HeroAttrSystem extends ecs.ComblockSystem - implements ecs.ISystemUpdate, ecs.IEntityEnterSystem, ecs.ISystemFirstUpdate { - - // ==================== 调试统计(可选)==================== - private entityCount: number = 0; // 本帧处理的实体数 - private frameCount: number = 0; // 总帧数 - private debugMode: boolean = false; // 是否启用调试模式 - private timer:Timer=new Timer(1) - /** - * 过滤器:只处理拥有 HeroAttrsComp 的实体 - */ - filter(): ecs.IMatcher { - return ecs.allOf(HeroAttrsComp); - } - - /** - * 实体首次进入系统时调用(每个实体只调用一次) - */ - entityEnter(e: ecs.Entity): void { - if(!smc.mission.play || smc.mission.pause) return; - const model = e.get(HeroAttrsComp); - if (!model) return; - - console.log(`[HeroAttrSystem] 英雄进入系统: ${model.hero_name} (uuid: ${model.hero_uuid})`); - } - - /** - * 系统首次更新前调用(整个系统只调用一次) - */ - firstUpdate(): void { - console.log("[HeroAttrSystem] 系统首次更新"); - } - - /** - * 每帧更新(为每个英雄调用一次) - * - * ⭐ 关键理解: - * - 如果有 3 个英雄,这个方法每帧会被调用 3 次 - * - 每次调用处理不同的实体 e - * - 这是正确的设计,不是 bug - */ - update(e: ecs.Entity): void { - if(!smc.mission.play || smc.mission.pause) return; - const model = e.get(HeroAttrsComp); - if (!model || model.is_dead) return; - - // 统计:记录本帧处理的实体数 - this.entityCount++; - - // 调试日志(可选,调试时启用) - if (this.debugMode) { - console.log(` [${this.entityCount}] 更新英雄: ${model.hero_name}, HP: ${model.hp.toFixed(2)}`); - } - - // 1. 更新临时 Buff/Debuff(时间递减,过期自动移除) - model.updateTemporaryBuffsDebuffs(this.dt); - // 记录MP变化前的值 - const oldMp = model.mp; - - if(this.timer.update(this.dt)){ - // 2. HP/MP 自然回复(业务规则) - model.mp += HeroUpSet.MP - model.hp += HeroUpSet.HP - } - - // 3. 限制属性值在合理范围内 - if (model.mp > model.Attrs[Attrs.MP_MAX]) { - model.mp = model.Attrs[Attrs.MP_MAX]; - } - if (model.hp > model.Attrs[Attrs.HP_MAX]) { - model.hp = model.Attrs[Attrs.HP_MAX]; - } - - // 4. 如果MP发生变化,更新最大技能距离缓存(最小距离不受MP影响) - if (model.mp !== oldMp) { - const skillsComp = e.get(HeroSkillsComp); - if (skillsComp) { - model.updateSkillDistanceCache(skillsComp); - } - } - - // 每 60 帧输出一次统计 - this.frameCount++; - if (this.frameCount % 60 === 0 && this.entityCount === 1) { - console.log(`[HeroAttrSystem] 第 ${this.frameCount} 帧,处理 ${this.entityCount} 个英雄`); - } - - // 注意:显示更新由 HeroViewComp 负责,这里只处理数据 - } - - /** - * 启用调试模式(调试时使用) - */ - enableDebug() { - this.debugMode = true; - } - - /** - * 禁用调试模式(正式运行) - */ - disableDebug() { - this.debugMode = false; - } -} diff --git a/assets/script/game/hero/HeroAttrsSystem.ts b/assets/script/game/hero/HeroAttrsSystem.ts new file mode 100644 index 00000000..e732cf9e --- /dev/null +++ b/assets/script/game/hero/HeroAttrsSystem.ts @@ -0,0 +1,128 @@ +import { Timer } from "db://oops-framework/core/common/timer/Timer"; +import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; +import { smc } from "../common/SingletonModuleComp"; +import { Attrs } from "../common/config/HeroAttrs"; +import { HeroUpSet } from "../common/config/heroSet"; +import { HeroSkillsComp } from "./HeroSkills"; +import { HeroAttrsComp } from "./HeroAttrsComp"; +/** + * ==================== 英雄属性更新系统 ==================== + * + * 按照 ECS 设计理念: + * - Component(HeroAttrsComp):存储数据 + * - System(HeroAttrSystem):处理业务逻辑 + * + * 系统职责: + * 1. 每帧更新临时 Buff(时间递减,过期移除) + * 2. 每帧更新 HP/MP 自然回复 + * 3. 限制属性值在合理范围内 + * +/** + * 使用方式: + * 在 RootSystem 中注册此系统,它会自动每帧更新所有拥有 HeroAttrsComp 的实体 + */ +@ecs.register('HeroAttrSystem') +export class HeroAttrSystem extends ecs.ComblockSystem + implements ecs.ISystemUpdate, ecs.IEntityEnterSystem, ecs.ISystemFirstUpdate { + + // ==================== 调试统计(可选)==================== + private entityCount: number = 0; // 本帧处理的实体数 + private frameCount: number = 0; // 总帧数 + private debugMode: boolean = false; // 是否启用调试模式 + private timer:Timer=new Timer(1) + /** + * 过滤器:只处理拥有 HeroAttrsComp 的实体 + */ + filter(): ecs.IMatcher { + return ecs.allOf(HeroAttrsComp); + } + + /** + * 实体首次进入系统时调用(每个实体只调用一次) + */ + entityEnter(e: ecs.Entity): void { + if(!smc.mission.play || smc.mission.pause) return; + const model = e.get(HeroAttrsComp); + if (!model) return; + + console.log(`[HeroAttrSystem] 英雄进入系统: ${model.hero_name} (uuid: ${model.hero_uuid})`); + } + + /** + * 系统首次更新前调用(整个系统只调用一次) + */ + firstUpdate(): void { + console.log("[HeroAttrSystem] 系统首次更新"); + } + + /** + * 每帧更新(为每个英雄调用一次) + * + * ⭐ 关键理解: + * - 如果有 3 个英雄,这个方法每帧会被调用 3 次 + * - 每次调用处理不同的实体 e + * - 这是正确的设计,不是 bug + */ + update(e: ecs.Entity): void { + if(!smc.mission.play || smc.mission.pause) return; + const model = e.get(HeroAttrsComp); + if (!model || model.is_dead) return; + + // 统计:记录本帧处理的实体数 + this.entityCount++; + + // 调试日志(可选,调试时启用) + if (this.debugMode) { + console.log(` [${this.entityCount}] 更新英雄: ${model.hero_name}, HP: ${model.hp.toFixed(2)}`); + } + + // 1. 更新临时 Buff/Debuff(时间递减,过期自动移除) + model.updateTemporaryBuffsDebuffs(this.dt); + // 记录MP变化前的值 + const oldMp = model.mp; + + if(this.timer.update(this.dt)){ + // 2. HP/MP 自然回复(业务规则) + model.mp += HeroUpSet.MP + model.hp += HeroUpSet.HP + } + + // 3. 限制属性值在合理范围内 + if (model.mp > model.Attrs[Attrs.MP_MAX]) { + model.mp = model.Attrs[Attrs.MP_MAX]; + } + if (model.hp > model.Attrs[Attrs.HP_MAX]) { + model.hp = model.Attrs[Attrs.HP_MAX]; + } + + // 4. 如果MP发生变化,更新最大技能距离缓存(最小距离不受MP影响) + if (model.mp !== oldMp) { + const skillsComp = e.get(HeroSkillsComp); + if (skillsComp) { + model.updateSkillDistanceCache(skillsComp); + } + } + + // 每 60 帧输出一次统计 + this.frameCount++; + if (this.frameCount % 60 === 0 && this.entityCount === 1) { + console.log(`[HeroAttrSystem] 第 ${this.frameCount} 帧,处理 ${this.entityCount} 个英雄`); + } + + // 注意:显示更新由 HeroViewComp 负责,这里只处理数据 + } + + /** + * 启用调试模式(调试时使用) + */ + enableDebug() { + this.debugMode = true; + } + + /** + * 禁用调试模式(正式运行) + */ + disableDebug() { + this.debugMode = false; + } +} diff --git a/assets/script/game/hero/HeroAttrsSystem.ts.meta b/assets/script/game/hero/HeroAttrsSystem.ts.meta new file mode 100644 index 00000000..143bde9d --- /dev/null +++ b/assets/script/game/hero/HeroAttrsSystem.ts.meta @@ -0,0 +1 @@ +{"ver":"4.0.24","importer":"typescript","imported":true,"uuid":"7763ec0e-8d85-4af0-8595-e3b078a128b6","files":[],"subMetas":{},"userData":{}} diff --git a/assets/script/game/hero/HeroViewComp.ts b/assets/script/game/hero/HeroViewComp.ts index 0718966b..a145a096 100644 --- a/assets/script/game/hero/HeroViewComp.ts +++ b/assets/script/game/hero/HeroViewComp.ts @@ -14,6 +14,7 @@ import { Tooltip } from "../skill/Tooltip"; import { timedCom } from "../skill/timedCom"; import { HeroInfo, HType } from "../common/config/heroSet"; import { Timer } from "db://oops-framework/core/common/timer/Timer"; +import { FlashSprite } from "./materials/scripts/FlashSprite"; const { ccclass, property } = _decorator; @@ -37,6 +38,7 @@ export class HeroViewComp extends CCComp { // 血条显示相关 hpBarShowTime:number = 5; // 血条显示持续时间(秒) hpBarShowCD:number = 0; // 血条显示计时器 + fsSprite:FlashSprite = null!; // ==================== UI 节点引用 ==================== private top_node: Node = null!; @@ -79,7 +81,7 @@ export class HeroViewComp extends CCComp { // 初始化 UI 节点 this.initUINodes(); - + /** 方向 */ this.node.setScale(this.scale*this.node.scale.x,1*this.node.scale.y); this.top_node.setScale(this.scale*this.top_node.scale.x,1*this.top_node.scale.y); @@ -101,6 +103,7 @@ export class HeroViewComp extends CCComp { this.top_node = this.node.getChildByName("top"); let hp_y = this.node.getComponent(UITransform).height+10; this.top_node.setPosition(0, hp_y, 0); + this.fsSprite = this.node.getComponent(FlashSprite); } @@ -214,12 +217,13 @@ export class HeroViewComp extends CCComp { /** 受击特效 */ private in_atked(anm: string = "atked", scale: number = 1) { - var path = "game/skill/end/" + anm; - var prefab: Prefab = oops.res.get(path, Prefab)!; - var node = instantiate(prefab); - node.setScale(node.scale.x * scale, node.scale.y); - node.setPosition(this.node.position.x, this.node.position.y+50, this.node.position.z); - node.parent = this.node.parent; + this.fsSprite.clickFlash(); + // var path = "game/skill/end/" + anm; + // var prefab: Prefab = oops.res.get(path, Prefab)!; + // var node = instantiate(prefab); + // node.setScale(node.scale.x * scale, node.scale.y); + // node.setPosition(this.node.position.x, this.node.position.y+50, this.node.position.z); + // node.parent = this.node.parent; } /** 冰冻特效 */ diff --git a/assets/script/game/hero/TalComp.ts b/assets/script/game/hero/TalComp.ts index ac61afcf..0c287ea9 100644 --- a/assets/script/game/hero/TalComp.ts +++ b/assets/script/game/hero/TalComp.ts @@ -14,9 +14,9 @@ const { ccclass } = _decorator; */ interface FightStats { aCount: number; // 普通攻击计数 - 用于 ACTION_COUNT 类型天赋 - sCount: number; // 技能使用计数 - 用于 SKILL_COUNT 类型天赋 + sCount: number; // 技能使用计数 - 用于 SKILL_COUNT 类型天赋 dCount: number; // 受伤次数计数 - 用于 DAMAGE_COUNT 类型天赋 - level: number; // 当前等级 - 用于 LEVEL/LEVEL_UP 类型天赋 + level: number; // 当前等级 - 用于 LEVEL/LEVEL_UP 类型天赋 } /** diff --git a/assets/script/game/map/FlashSprite.ts b/assets/script/game/map/FlashSprite.ts deleted file mode 100644 index 73c98cce..00000000 --- a/assets/script/game/map/FlashSprite.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { _decorator, color, Component, Material, Node, Sprite } from 'cc'; -const { ccclass, property } = _decorator; - -@ccclass('FlashSprite') -export class FlashSprite extends Component { - - @property(Material) - hitFlashMaterial: Material; - orginalFlashMaterial: Material; - sprite: Sprite; - - start() { - this.sprite = this.node.getComponent(Sprite); - this.orginalFlashMaterial = this.sprite.getRenderMaterial(0); - - } - - update(deltaTime: number) { - - } - - public clickFlash() { - this.sprite.setSharedMaterial(this.hitFlashMaterial, 0); - this.scheduleOnce(() => { - this.sprite.setSharedMaterial(this.orginalFlashMaterial, 0); - }, 0.1); - } -} - diff --git a/assets/script/game/map/FlashSprite.ts.meta b/assets/script/game/map/FlashSprite.ts.meta deleted file mode 100644 index 3290238f..00000000 --- a/assets/script/game/map/FlashSprite.ts.meta +++ /dev/null @@ -1,9 +0,0 @@ -{ - "ver": "4.0.24", - "importer": "typescript", - "imported": true, - "uuid": "df953176-a9fa-4f3e-865e-7956fccc4c52", - "files": [], - "subMetas": {}, - "userData": {} -}