chenxin
2020-11-04 80b4237334a773b29bf69f38532a90ca659b3bfe
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
using TowerDefense.UI.HUD;
using Core.Utilities;
using System.Collections.Generic;
using UnityEngine;
using TowerDefense.Agents;
using TowerDefense.Level;
 
/**
 * 泡泡炸弹
 * @Author: chenxin
 * @Date: 2020-11-02 17:09:03
 */
namespace KTGMGemClient
{
    public class BubbleBombConfig
    {
        public BubbleBombAgent Agent { 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; }
 
        public float AttackTime { get; set; }
    }
 
    public class BossSkillBubbleBomb : EndlessBossSkill
    {
        public BossSkillBubbleBomb(boss_skill param) : base(param)
        {
            random = new System.Random();
        }
 
        /// <summary>
        /// 被攻击的次数
        /// </summary>
        protected int beAttackedCount;
 
        protected string prefabPath = "Prefabs/Endless/BubbleBomb";
 
        /// <summary>
        /// 所有存在于场景中的泡泡炸弹
        /// </summary>
        protected List<BubbleBombConfig> bubbleBombList;
 
        protected System.Random random;
 
        /// <summary>
        /// 释放技能
        /// </summary>
        public override void ReleaseSkill()
        {
            base.ReleaseSkill();
            Debug.Log("--------------------- 泡泡炸弹释放 ---------------------");
            // cx test
            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:
                    EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBossSkillGlintTitle);
                    SpawnOnTunel();
                    break;
            }
        }
 
        /// <summary>
        /// 在赛道上生成炸弹
        /// </summary>
        protected void SpawnOnTunel()
        {
            // 有可能只在某一条赛道生成,也有可能在所有赛道生成
            List<int> tunelIdList = GetTunelList();
            GameObject prefab = Resources.Load<GameObject>(prefabPath);
 
            for (int i = 0; i < tunelIdList.Count; ++i)
            {
                Poolable poolable = Poolable.TryGetPoolable<Poolable>(prefab);
                BubbleBombAgent bubbleBomb = poolable.GetComponent<BubbleBombAgent>();
 
                // 分配唯一id
                bubbleBomb.Id = GameUtils.GetId();
                bubbleBomb.waveLineID = tunelIdList[i] - 1;
                bubbleBomb.AgentType = SpawnAgentType.BubbleBomb;
                bubbleBomb.opponentAgent = false;
 
                // 出生位置
                Vector3 spawnPosition = EndlessLevelManager.instance.GetTunelWorldPosition(tunelIdList[i], (EndlessBossSkillTunelType)SkillData.target[1]);
                bubbleBomb.transform.position = spawnPosition;
                bubbleBomb.PlayNormalEffect();
                AgentInsManager.instance.addAgent(bubbleBomb);
 
                BubbleBombConfig config = new BubbleBombConfig();
                config.Agent = bubbleBomb;
                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);
            }
        }
 
        /// <summary>
        /// 获取赛道列表
        /// </summary>
        protected List<int> GetTunelList()
        {
            List<int> tunelIdList = new List<int>();
            // cx test 后面改
            int configTunel = SkillData.tunnel[0];
 
            if (configTunel <= 5)
                // 直接对应具体的一条赛道
                tunelIdList.Add(configTunel);
            else if (configTunel == 6)
            {
                // 所有赛道
                for (int i = 1; i <= 5; ++i)
                {
                    tunelIdList.Add(i);
                }
            }
            else if (configTunel == 7)
                // 随机一条
                tunelIdList.Add(random.Next(1, 6));
 
            return tunelIdList;
        }
 
        public override void Reset()
        {
            base.Reset();
            beAttackedCount = 0;
            ClearBubbleBomb();
        }
 
        public override void Clear()
        {
            base.Clear();
            ClearBubbleBomb();
        }
 
        /// <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();
 
                if (!bubbleBombList[i].Agent.bInDeathState)
                    AgentInsManager.instance.removeAgent(bubbleBombList[i].Agent);
 
                Poolable.TryPool(bubbleBombList[i].Agent.gameObject);
            }
 
            bubbleBombList.Clear();
        }
 
        public override void Init()
        {
            base.Init();
            Debug.Log("--------------------- 泡泡炸弹技能初始化 ---------------------");
            bubbleBombList = new List<BubbleBombConfig>();
        }
 
        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;
 
                    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)
            {
                if (bubbleBombList[i] == null) continue;
 
                BubbleBombConfig config = bubbleBombList[i];
 
                if (config.IsAttack)
                {
                    config.AttackTime -= deltaTime;
 
                    if (config.AttackTime <= 0)
                    {
                        EndlessGameUI.instance.DestroyTowerGrid(config.Agent.waveLineID);
                        config.IsAttack = false;
                    }
                }
 
                // 被打死了 或 到达基地
                if (config.IsAttackDeath || config.IsArrived)
                {
                    config.DestroyTime -= deltaTime;
 
                    if (config.DestroyTime <= 0)
                    {
                        bubbleBombList[i].Agent.Reset();
                        Poolable.TryPool(bubbleBombList[i].Agent.gameObject);
                        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.bInDeathState && config.Agent.CanMove)
                {
                    Vector3 pos = config.Agent.transform.position;
                    pos.z -= deltaTime * config.MoveSpeed;
                    config.Agent.transform.position = pos;
 
                    if (pos.z <= config.TargetPosition.z)
                    {
                        AgentArrived(config);
                        config.IsAttack = true;
                        config.AttackTime = 0.65f;
                    }
                }
            }
        }
    }
}