chenxin
2020-11-18 b8d221ed856544aec0ae376783e09f9814276722
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
using System.Collections.Generic;
using UnityEngine;
using TowerDefense.Agents;
using TowerDefense.Level;
 
/**
 * 泡泡炸弹
 * @Author: chenxin
 * @Date: 2020-11-02 17:09:03
 */
namespace KTGMGemClient
{
    /// <summary>
    /// 泡泡炸弹配置数据
    /// </summary>
    public class BubbleBombConfig
    {
        public BubbleBombAgent Agent { get; set; }
 
        public GameObject obj { get; set; }
 
        /// <summary>
        /// 需要被攻击的次数,攻击 * 次炸弹才会被销毁
        /// </summary>
        public int NeedAttackCount { get; set; }
 
        /// <summary>
        /// 已经被攻击的次数
        /// </summary>
        public int AttackCount { get; set; }
 
        /// <summary>
        /// 是否抵达基地,抵达基地后,不能继续被塔攻击
        /// </summary>
        public bool IsArrived { get; set; }
 
        /// <summary>
        /// 出生点坐标
        /// </summary>
        public Vector3 StartPosition { get; set; }
 
        /// <summary>
        /// 目的地坐标,也就是基地位置
        /// </summary>
        public Vector3 TargetPosition { get; set; }
 
        /// <summary>
        /// 是否被攻击打死,被塔打死或者被火技能宝石打死(火技能宝石是直接秒杀炸弹的)
        /// </summary>
        public bool IsAttackDeath { get; set; }
 
        /// <summary>
        /// 销毁时间,被塔打死或者攻击玩家基地后,时间减为0之后销毁
        /// </summary>
        public float DestroyTime { get; set; }
 
        /// <summary>
        /// 移动速度
        /// </summary>
        public float MoveSpeed { get; set; }
 
        /// <summary>
        /// 是否被眩晕
        /// </summary>
        public bool IsDizzinessed { get; set; }
 
        /// <summary>
        /// 眩晕时间
        /// </summary>
        public float DizzinessTime { get; set; }
 
        /// <summary>
        /// 是否是攻击状态,延时取摧毁基地
        /// </summary>
        public bool IsAttack { get; set; }
 
        /// <summary>
        /// 延迟产生伤害时间
        /// </summary>
        public float AttackTime { get; set; }
    }
 
    public class BossSkillBubbleBomb : EndlessBossSkill
    {
        public BossSkillBubbleBomb(boss_skill param) : base(param) { }
 
        /// <summary>
        /// 被攻击的次数
        /// </summary>
        protected int beAttackedCount;
 
        protected string prefabPath = "Prefabs/Endless/BubbleBomb";
 
        /// <summary>
        /// 所有存在于场景中的泡泡炸弹
        /// </summary>
        protected List<BubbleBombConfig> bubbleBombList;
 
        /// <summary>
        /// 泡泡炸弹对象池
        /// </summary>
        protected List<GameObject> bubbleBombPool;
 
        protected int capacity = 10;
 
        private int getCount;
 
        private int recycleCount;
 
        /// <summary>
        /// 释放技能
        /// </summary>
        public override void ReleaseSkill()
        {
            base.ReleaseSkill();
            Debug.Log("--------------------- 泡泡炸弹释放 ---------------------");
            SpawnBubbleBomb();
        }
 
        /// <summary>
        /// 在场景中生成泡泡炸弹
        /// </summary>
        protected void SpawnBubbleBomb()
        {
            switch ((EndlessBossSkillUseTarget)SkillData.target[0])
            {
                case EndlessBossSkillUseTarget.Tower:
                    Debug.Log("--------------------- WTF 不支持哦~ ---------------------");
                    break;
                case EndlessBossSkillUseTarget.Agent:
                    Debug.Log("--------------------- WTF 不支持哦~ ---------------------");
                    break;
                case EndlessBossSkillUseTarget.Tunel:
                    SpawnOnTunel();
                    break;
            }
        }
 
        /// <summary>
        /// 在赛道上生成炸弹
        /// </summary>
        protected void SpawnOnTunel()
        {
            List<int> tunelIdList = GetTunelList();
 
            for (int i = 0; i < tunelIdList.Count; ++i)
            {
                GameObject obj = GetBubbleBomb();
                BubbleBombAgent bubbleBomb = obj.GetComponent<BubbleBombAgent>();
 
                // 分配唯一id
                bubbleBomb.Id = GameUtils.GetId();
                bubbleBomb.waveLineID = tunelIdList[i] - 1;
                bubbleBomb.AgentType = SpawnAgentType.BubbleBomb;
                bubbleBomb.opponentAgent = false;
                bubbleBomb.Reset();
                bubbleBomb.Initialize();
 
                // 出生位置
                Vector3 spawnPosition = EndlessLevelManager.instance.GetTunelWorldPosition(tunelIdList[i], (EndlessBossSkillTunelType)SkillData.target[1]);
                obj.transform.position = spawnPosition;
                bubbleBomb.PlayNormalEffect();
                AgentInsManager.instance.addAgent(bubbleBomb);
 
                BubbleBombConfig config = new BubbleBombConfig();
                config.Agent = bubbleBomb;
                config.obj = obj;
                config.NeedAttackCount = (int)SkillData.effect[0];
                config.StartPosition = spawnPosition;
                config.TargetPosition = EndlessLevelManager.instance.GetHomeBasePosition(tunelIdList[i]);
                config.DestroyTime = bubbleBomb.GetExplodeTime();
                config.MoveSpeed = SkillData.effect[1];
                bubbleBombList.Add(config);
            }
        }
 
        public override void Reset()
        {
            base.Reset();
            beAttackedCount = 0;
            ClearBubbleBomb();
        }
 
        public override void Clear()
        {
            base.Clear();
            ClearBubbleBomb();
            ClearBubbleBombPool();
        }
 
        /// <summary>
        /// 清理在场景中的所有炸弹
        /// </summary>
        private void ClearBubbleBomb()
        {
            for (int i = 0; i < bubbleBombList.Count; ++i)
            {
                bubbleBombList[i].Agent.Reset();
                bubbleBombList[i].Agent.StopNormalEffect();
                bubbleBombList[i].Agent.StopExplodeEffect();
 
                AgentInsManager.instance.removeAgent(bubbleBombList[i].Agent);
                RecycleBubbleBomb(bubbleBombList[i].obj);
            }
 
            bubbleBombList.Clear();
        }
 
        public override void Init()
        {
            base.Init();
            Debug.Log("--------------------- 泡泡炸弹技能初始化 ---------------------");
            bubbleBombList = new List<BubbleBombConfig>();
            bubbleBombPool = new List<GameObject>();
 
            GameObject prefab = Resources.Load<GameObject>(prefabPath);
 
            for (int i = 0; i < capacity; ++i)
            {
                GameObject obj = GameObject.Instantiate(prefab);
                obj.SetActive(false);
                bubbleBombPool.Add(obj);
            }
        }
 
        /// <summary>
        /// 从对象池中获取一个炸弹
        /// </summary>
        protected GameObject GetBubbleBomb()
        {
            GameObject ret;
 
            if (bubbleBombPool.Count > 0)
            {
                ret = bubbleBombPool[0];
                bubbleBombPool.Remove(bubbleBombPool[0]);
            }
            else
            {
                GameObject prefab = Resources.Load<GameObject>(prefabPath);
                ret = GameObject.Instantiate(prefab);
            }
 
            ret.SetActive(true);
 
            return ret;
        }
 
        /// <summary>
        /// 回收泡泡炸弹
        /// </summary>
        /// <param name="obj"></param>
        protected void RecycleBubbleBomb(GameObject obj)
        {
            if (obj != null)
            {
                obj.SetActive(false);
                bubbleBombPool.Add(obj);
            }
        }
 
        /// <summary>
        /// 清空泡泡炸弹对象池
        /// </summary>
        protected void ClearBubbleBombPool()
        {
            while (bubbleBombPool.Count > 0)
            {
                GameObject obj = bubbleBombPool[0];
                bubbleBombPool.Remove(obj);
                GameObject.Destroy(obj);
            }
        }
 
        protected override void AddEvent()
        {
            EventCenter.Ins.Add<int>((int)KTGMGemClient.EventType.EndlessBossSkillBubbleBombGetHit, OnGetHit);
            EventCenter.Ins.Add<int>((int)KTGMGemClient.EventType.EndlessFireSkillKillBubbleBomb, OnFireSkillKillBubbleBomb);
            EventCenter.Ins.Add<int, int>((int)KTGMGemClient.EventType.EndlessBubbleBombBeDizzinessed, OnBubbleBombBeDizzinessed);
        }
 
        protected override void RemoveEvent()
        {
            EventCenter.Ins.Remove<int>((int)KTGMGemClient.EventType.EndlessBossSkillBubbleBombGetHit, OnGetHit);
            EventCenter.Ins.Remove<int>((int)KTGMGemClient.EventType.EndlessFireSkillKillBubbleBomb, OnFireSkillKillBubbleBomb);
            EventCenter.Ins.Remove<int, int>((int)KTGMGemClient.EventType.EndlessBubbleBombBeDizzinessed, OnBubbleBombBeDizzinessed);
        }
 
        /// <summary>
        /// 泡泡炸弹受到一次攻击
        /// </summary>
        /// <param name="id">炸弹代理的唯一id</param>
        private void OnGetHit(int id)
        {
            for (int i = 0; i < bubbleBombList.Count; ++i)
            {
                if (bubbleBombList[i].Agent.Id == id)
                {
                    BubbleBombConfig config = bubbleBombList[i];
                    // 攻击次数够了被打死了 或者 达到基地了
                    if (config.Agent.bInDeathState) return;
 
                    ++config.AttackCount;
                    Debug.Log($"--------------------- BubbleBombAgent Id: {id}, AttackCount:{config.AttackCount} ---------------------");
 
                    if (config.AttackCount >= config.NeedAttackCount)
                        AgentDead(config);
 
                    break;
                }
            }
        }
 
        /// <summary>
        /// 泡泡炸弹被火技能烧死
        /// </summary>
        /// <param name="id"></param>
        private void OnFireSkillKillBubbleBomb(int id)
        {
            for (int i = 0; i < bubbleBombList.Count; ++i)
            {
                if (bubbleBombList[i].Agent.Id == id)
                {
                    BubbleBombConfig config = bubbleBombList[i];
 
                    if (config.Agent.bInDeathState) return;
 
                    AgentDead(config);
                    break;
                }
            }
        }
 
        /// <summary>
        /// 泡泡炸弹被眩晕
        /// </summary>
        /// <param name="id"></param>
        /// <param name="duration">持续时间</param>
        private void OnBubbleBombBeDizzinessed(int id, int duration)
        {
            for (int i = 0; i < bubbleBombList.Count; ++i)
            {
                if (bubbleBombList[i].Agent.Id == id)
                {
                    BubbleBombConfig config = bubbleBombList[i];
 
                    if (config.Agent.bInDeathState) return;
 
                    config.IsDizzinessed = true;
                    config.Agent.CanMove = false;
                    // 直接覆盖持续时间
                    config.DizzinessTime = duration / 1000f;
                    break;
                }
            }
        }
 
        /// <summary>
        /// 炸弹突然去世
        /// </summary>
        /// <param name="config"></param>
        private void AgentDead(BubbleBombConfig config)
        {
            config.Agent.StopNormalEffect();
            config.Agent.PlayExplodeEffect();
            AgentInsManager.instance.removeAgent(config.Agent);
            config.Agent.bInDeathState = true;
            config.IsAttackDeath = true;
        }
 
        /// <summary>
        /// 炸弹到达基地
        /// </summary>
        /// <param name="config"></param>
        private void AgentArrived(BubbleBombConfig config)
        {
            config.IsArrived = true;
            config.Agent.StopNormalEffect();
            config.Agent.PlayExplodeEffect();
            AgentInsManager.instance.removeAgent(config.Agent);
            config.Agent.bInDeathState = true;
        }
 
        public override void Update(float deltaTime)
        {
            base.Update(deltaTime);
 
            for (int i = 0; i < bubbleBombList.Count; ++i)
            {
                BubbleBombConfig config = bubbleBombList[i];
 
                // 泡泡炸弹已经触发了攻击,延时一会过后掉爱心
                if (config.IsAttack)
                {
                    config.AttackTime -= deltaTime;
 
                    if (config.AttackTime <= 0)
                    {
                        EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessLoseHeart, 3);
                        config.IsAttack = false;
                    }
                }
 
                // 被打死了 或 到达基地
                if (config.IsAttackDeath || config.IsArrived)
                {
                    config.DestroyTime -= deltaTime;
 
                    if (config.DestroyTime <= 0)
                    {
                        bubbleBombList[i].Agent.Reset();
                        RecycleBubbleBomb(bubbleBombList[i].obj);
                        AgentInsManager.instance.removeAgent(bubbleBombList[i].Agent);
                        bubbleBombList.Remove(bubbleBombList[i]);
                        --i;
                    }
 
                    continue;
                }
 
                // 处理被眩晕的
                if (config.IsDizzinessed)
                {
                    config.DizzinessTime -= deltaTime;
 
                    if (config.DizzinessTime <= 0)
                    {
                        // 解除眩晕
                        config.IsDizzinessed = false;
                        config.Agent.CanMove = true;
                    }
                    else continue;
                }
 
                // 更新移动
                if (config.Agent != null && !config.Agent.bInDeathState && config.Agent.CanMove)
                {
                    Vector3 pos = config.obj.transform.position;
                    pos.z -= deltaTime * config.MoveSpeed;
                    config.obj.transform.position = pos;
 
                    if (pos.z <= config.TargetPosition.z)
                    {
                        AgentArrived(config);
                        config.IsAttack = true;
                        config.AttackTime = 0.65f;
                    }
                }
                else
                {
                    // cx test
                    Debug.Log("---------------------  ---------------------");
                }
            }
        }
    }
}