11import { BaseSummon , type ISummonInitData } from './BaseSummon' ;
22import { GameConfig } from '../../config/GameConfig' ;
33import AudioManager from '../../managers/AudioManager' ;
4- import { AudioKeys } from '../../config/AssetKeys' ;
4+ import { AudioKeys , VFXTextureKeys } from '../../config/AssetKeys' ;
5+ import { PipelineID } from '../../managers/RenderManager' ;
6+ import type LightningFadePipeline from '../../pipelines/LightningFadePipeline' ;
57
68export class LightningColumn extends BaseSummon {
79 private isStriking : boolean = false ; // 是否处于伤害阶段
810 private warningRect ?: Phaser . GameObjects . Rectangle ; // 预警线
9- private strikeRect ?: Phaser . GameObjects . Rectangle ; // 正式闪电
11+ private alertIcon ?: Phaser . GameObjects . Image ; // 预警图标
12+ private alertBg ?: Phaser . GameObjects . Sprite ; // 预警背景动效
13+ private strikeSprite ?: Phaser . GameObjects . Sprite ; // 正式闪电
14+ private strikeProgress : number = 0 ;
1015
1116 // 伤害配置
1217 private readonly WARNING_WIDTH = 200 ; // 预警线宽度
@@ -24,31 +29,61 @@ export class LightningColumn extends BaseSummon {
2429 const screenHeight = this . scene . scale . height ;
2530 // const screenWidth = this.scene.scale.width;
2631 this . isStriking = false ;
32+ this . strikeProgress = 0 ;
2733
28- // 1. 创建预警线 (淡淡的细线 )
34+ // 1. 创建预警线 (红色闪烁 )
2935 // 随机 X 位置已经在 Spawn 时决定了 (this.x)
3036 this . warningRect = this . scene . add . rectangle (
31- this . x ,
32- screenHeight / 2 ,
33- this . WARNING_WIDTH ,
34- screenHeight / minZoom ,
35- 0xFFFFFF , 0.3
37+ this . x ,
38+ screenHeight / 2 ,
39+ this . WARNING_WIDTH ,
40+ screenHeight / minZoom ,
41+ 0xFF3333 , 0.3
3642 )
3743 . setScrollFactor ( 0 )
3844 . setDepth ( 40 ) ; // 在玩家下面一点
3945
46+ const alertAnimKey = 'alert_lightning_bg' ;
47+ if ( ! this . scene . anims . exists ( alertAnimKey ) ) {
48+ this . scene . anims . create ( {
49+ key : alertAnimKey ,
50+ frames : this . scene . anims . generateFrameNumbers ( VFXTextureKeys . VfxAlertBg , { start : 0 , end : 8 } ) ,
51+ frameRate : 12 ,
52+ repeat : - 1
53+ } ) ;
54+ }
55+
56+ this . alertBg = this . scene . add . sprite ( this . x , screenHeight / 2 , VFXTextureKeys . VfxAlertBg )
57+ . setScrollFactor ( 0 )
58+ . setDepth ( 41 )
59+ . setScale ( 2.5 ) ;
60+ this . alertBg . play ( alertAnimKey ) ;
61+
62+ this . alertIcon = this . scene . add . image ( this . x , screenHeight / 2 , VFXTextureKeys . VfxAlertIcon )
63+ . setScrollFactor ( 0 )
64+ . setDepth ( 42 )
65+ . setScale ( 0.5 ) ;
66+
4067 // 2. 预警动画 (1.5秒后劈下)
4168 this . scene . tweens . add ( {
4269 targets : this . warningRect ,
43- alpha : { from : 0.1 , to : 0.5 } ,
70+ alpha : { from : 0.1 , to : 0.7 } ,
4471 yoyo : true ,
45- repeat : 3 ,
72+ repeat : 4 ,
4673 duration : 200 ,
4774 onComplete : ( ) => {
4875 this . strike ( ) ;
4976 }
5077 } ) ;
51-
78+
79+ this . scene . tweens . add ( {
80+ targets : this . alertIcon ,
81+ alpha : { from : 0.2 , to : 1 } ,
82+ yoyo : true ,
83+ repeat : 4 ,
84+ duration : 200
85+ } ) ;
86+
5287 // 3. 禁用物理 (手动判定)
5388 if ( this . body ) this . body . enable = false ;
5489 }
@@ -62,45 +97,71 @@ export class LightningColumn extends BaseSummon {
6297
6398 // 移除预警
6499 this . warningRect ?. destroy ( ) ;
100+ this . alertIcon ?. destroy ( ) ;
101+ this . alertBg ?. destroy ( ) ;
65102
66- // 创建闪电 (高亮粗柱子)
67- // 颜色:雷电紫/白
68- this . strikeRect = this . scene . add . rectangle (
69- this . x ,
70- screenHeight / 2 ,
71- this . DAMAGE_WIDTH ,
72- screenHeight / minZoom ,
73- 0x8844FF
103+ const frameIndex = Phaser . Math . Between ( 0 , 5 ) ;
104+ this . strikeSprite = this . scene . add . sprite (
105+ this . x ,
106+ screenHeight / 2 ,
107+ VFXTextureKeys . VfxLightningLine ,
108+ frameIndex
74109 )
75110 . setScrollFactor ( 0 )
76111 . setDepth ( 100 ) ; // 最上层
112+ this . strikeSprite . setRotation ( Math . PI / 2 ) ;
113+ this . strikeSprite . setDisplaySize ( screenHeight / minZoom , this . DAMAGE_WIDTH ) ;
77114
78115 AudioManager . playSfx ( AudioKeys . SfxThunderbolt ) ;
116+
117+ let pipeline : LightningFadePipeline | undefined ;
118+ if ( this . scene . game . renderer instanceof Phaser . Renderer . WebGL . WebGLRenderer ) {
119+ this . strikeSprite . setPipeline ( PipelineID . LightningFade ) ;
120+ pipeline = this . strikeSprite . pipeline as LightningFadePipeline ;
121+ pipeline ?. setProgress ( 0 ) ;
122+ // pipeline?.setColor(0x3aa0ff);
123+ }
79124
80- // 闪电冲击动画 (0.2秒瞬间 )
125+ // 闪电冲击动画 (0.5秒进度 + 0.5秒淡出 )
81126 this . scene . tweens . add ( {
82- targets : this . strikeRect ,
83- alpha : { from : 1 , to : 0 } ,
84- width : { from : this . DAMAGE_WIDTH , to : 0 } ,
85- duration : 300 ,
127+ targets : this ,
128+ strikeProgress : 1 ,
129+ duration : 500 ,
86130 ease : 'Sine.easeOut' ,
131+ onUpdate : ( ) => {
132+ if ( pipeline ) {
133+ pipeline . setProgress ( this . strikeProgress ) ;
134+ }
135+ } ,
87136 onComplete : ( ) => {
88- // ✅ 1. 视觉上:彻底移除闪电,让玩家以为结束了
89- if ( this . strikeRect ) {
90- this . strikeRect . destroy ( ) ;
91- this . strikeRect = undefined ;
137+ if ( ! this . strikeSprite ) {
138+ this . isStriking = false ;
139+ return ;
92140 }
93-
94- // ✅ 2. 逻辑上:强制关闭伤害判定 (防止隐形电人)
95- this . isStriking = false ;
96-
97- // ✅ 3. 核心修改:延迟 2秒 再真正回收
98- // 这 2秒 期间,getActiveCount() 依然是 1,
99- // 所以 LightningStrikeAction 会一直返回,不会生成新雷
100- const COOLDOWN_TIME = 2000 ;
101-
102- this . scene . time . delayedCall ( COOLDOWN_TIME , ( ) => {
103- this . despawn ( ) ;
141+ this . scene . tweens . add ( {
142+ targets : this . strikeSprite ,
143+ alpha : 0 ,
144+ duration : 500 ,
145+ ease : 'Sine.easeOut' ,
146+ onComplete : ( ) => {
147+ // ? 1. 视觉上:彻底移除闪电,让玩家以为结束了
148+ if ( this . strikeSprite ) {
149+ this . strikeSprite . destroy ( ) ;
150+ this . strikeSprite = undefined ;
151+ }
152+
153+ // ? 2. 逻辑上:强制关闭伤害判定 (防止隐形电人)
154+ this . isStriking = false ;
155+
156+ // ? 3. 核心修改:延迟 2秒 再真正回收
157+ // 这 2秒 期间,getActiveCount() 依然是 1,
158+ // 所以 LightningStrikeAction 会一直返回,不会生成新雷
159+ const COOLDOWN_TIME = 2000 ;
160+
161+ this . scene . time . delayedCall ( COOLDOWN_TIME , ( ) => {
162+ this . despawn ( ) ;
163+ } ) ;
164+ }
104165 } ) ;
105166 }
106167 } ) ;
@@ -111,8 +172,8 @@ export class LightningColumn extends BaseSummon {
111172
112173 protected onUpdate ( _dt : number ) : void {
113174 // 只有在劈下的一瞬间 (isStriking) 且 闪电还没完全消失时判定
114- // ✅ 增加 check:如果 strikeRect 已经被销毁了 (处于幽灵冷却期),直接返回
115- if ( ! this . isStriking || ! this . strikeRect || this . strikeRect . alpha < 0.5 ) return ;
175+ // ✅ 增加 check:如果 strikeSprite 已经被销毁了 (处于幽灵冷却期),直接返回
176+ if ( ! this . isStriking || ! this . strikeSprite || this . strikeProgress >= 1 ) return ;
116177 if ( ! this . target || ! this . target . active ) return ;
117178
118179 // --- 碰撞判定 (屏幕空间) ---
@@ -154,7 +215,10 @@ export class LightningColumn extends BaseSummon {
154215
155216 protected override onDespawn ( ) : void {
156217 this . warningRect ?. destroy ( ) ;
157- this . strikeRect ?. destroy ( ) ;
218+ this . strikeSprite ?. destroy ( ) ;
158219 this . kill ( ) ;
159220 }
160- }
221+ }
222+
223+
224+
0 commit comments