少年修仙传客户端代码仓库
hch
2025-06-12 204ef05a831c9484e2abc561d27ecbff7c797453
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
//--------------------------------------------------------
//    [Author]:           第二世界
//    [  Date ]:           Monday, November 27, 2017
//--------------------------------------------------------
 
using DG.Tweening;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
 
//战斗力增加
namespace vnxbqy.UI
{
    public class PowerAddWin : Window
    {
        [SerializeField] TextEx txtBase;        //提升或降低前的战斗力
        [SerializeField] TextEx txtChange;      //战斗力变化了多少
        [SerializeField] ImageEx imgArrow;      //箭头
        [SerializeField] Transform transZhanLi;         //战力整体框
        [SerializeField] Transform transZhanLiNumAll;         //战力所有变化部分
        [SerializeField] RectTransform transChange;         //箭头和变化数字整体框
        string uiFrameKey = "zhanli_dt";
        [SerializeField] UIFrame uiFrame;
        [SerializeField] List<PowerUpPosition> powerUpPositions;
 
        [Header("淡入变大")]
        [SerializeField] Vector3 startVector;                       //起始大小
 
        [SerializeField] float fadeInToBigDuration;                 //淡入变大动画完成时间
        [SerializeField] Ease fadeInToBigEaseType;
        [SerializeField] Vector3 fadeInToBigVector;                 //淡入变大目标大小
 
        [Header("淡入变小")]
        [SerializeField] Vector3 fadeInToSmallVector;               //淡入变小目标大小
 
        [SerializeField] float fadeInToSmallDuration;               //淡入变小动画完成时间
        [SerializeField] Ease fadeInToSmallEaseType;
 
        [Header("淡入后移动开始前等待时间/s")]
        [SerializeField] float moveStartWaitTime;
 
        [Header("变化值移动")]
        [SerializeField] float moveDuration;                        //变化值移动动画完成时间
 
        [SerializeField] Ease moveEaseType;
 
        [Header("变化值透明度降到0")]
        [SerializeField] float textFadeDuration;                    //变化值透明度降到0的时间
 
        [SerializeField] Ease textFadeEaseType;
 
        [Header("数字滚动")]
        [SerializeField] float rollDuration;                        //数字滚动动画完成时间
 
        [SerializeField] float rollCount;                           //数字滚动次数
        [SerializeField] Ease rollEaseType;
 
        [Header("移动结束后淡出开始前等待时间/s")]
        [SerializeField] float moveEndWaitTime;
 
        [Header("淡出变大")]
        [SerializeField] Vector3 fadeOutToBigVector;                //淡出变大目标大小
 
        [SerializeField] float fadeOutToBigDuration;                //淡出变大动画完成时间
        [SerializeField] Ease fadeOutToBigEaseType;
 
        [Header("淡出变小")]
        [SerializeField] float fadeOutToSmallDuration;              //淡出变小动画完成时间
 
        [SerializeField] Ease fadeOutToSmallEaseType;
 
        [Header("战力数字位置计算相关")]
        [SerializeField] float txtBaseMultiple;                     //前置的战力数字字母距离倍数
 
        [SerializeField] float txtChangeMultiple;                   //后置的战力数字字母距离倍数
        [SerializeField] int baseFontWidth;                         //前置的战力数字字母一个多大
        [SerializeField] int changeFontWidth;                       //后置的战力数字字母一个多大
        [SerializeField] float baseAndChangeInterval;               //前置和后置的战力数字中间的间隔大小
        [SerializeField] float changeAndArrowInterval;              //后置的战力数字和箭头之间的间隔大小
        [SerializeField] float transChangeY;                        //Change组件的Y值
        [SerializeField] float intArrowAddInterval;                 //增加或减少值是整数时,后置的战力数字和箭头之间的间隔增加多少
        private float fadeInEndTime; // 播完淡入动画后的时间
        private float moveEndTime;   // 播完移动动画后的时间
        long basePower;
        long nowPower;
        long changePower;
        bool isAdd;
 
        private enum AnimeState
        {
            FadeIn,
            WaitMove,
            Move,
            WaitFadeOut,
            FadeOut,
        }
 
        AnimeState nowState;
 
        #region Built-in
 
        PlayerMainDate m_MainModel;
        PlayerMainDate onMainModel { get { return m_MainModel ?? (m_MainModel = ModelCenter.Instance.GetModel<PlayerMainDate>()); } }
 
        protected override void BindController()
        {
        }
 
        protected override void AddListeners()
        {
        }
 
        protected override void OnPreOpen()
        {
            onMainModel.AddPowerEvent += ResetToWaitMove;
            ResetToFadeIn();
        }
 
        protected override void OnAfterOpen()
        {
        }
 
        protected override void OnPreClose()
        {
            onMainModel.AddPowerEvent -= ResetToWaitMove;
        }
 
        protected override void OnAfterClose()
        {
        }
 
        #endregion
 
        Sequence sequence;
        Sequence textChangeSequence;
        Sequence fadeOutSequence;
 
        protected override void LateUpdate()
        {
            if (nowState == AnimeState.WaitMove)
            {
                if (Time.time - fadeInEndTime > moveStartWaitTime)
                {
                    nowState = AnimeState.Move;
 
                    sequence = DOTween.Sequence();
                    sequence.Join(transChange.DOMove(new Vector3(txtBase.rectTransform.position.x, transChange.position.y, transChange.position.z) , moveDuration).SetEase(moveEaseType));
                    sequence.Join(txtChange.DOFade(0f, textFadeDuration).SetEase(textFadeEaseType));
                    sequence.Join(imgArrow.DOFade(0f, textFadeDuration).SetEase(textFadeEaseType));
 
                    textChangeSequence = DOTween.Sequence();
                    float rollTime = rollDuration / rollCount;
                    for (int i = 0; i < rollCount + 1; i++)
                    {
                        long changeValue = changePower / (int)rollCount * (i + 1);
                        long nowValue;
                        if (i == rollCount)
                        {
                            nowValue = nowPower;
                            sequence.Append(txtBase.DOText(DisplayBasePowerNum(nowValue), rollTime).SetEase(rollEaseType).OnComplete(() => { SetInitPosition(nowValue, changePower, isAdd); }));
                        }
                        else
                        {
                            if (isAdd)
                            {
                                nowValue = basePower + changeValue;
                                sequence.Append(txtBase.DOText(DisplayBasePowerNum(nowValue), rollTime).SetEase(rollEaseType).OnComplete(() => { SetInitPosition(nowValue, changePower, isAdd); }));
                            }
                            else
                            {
                                nowValue = basePower - changeValue;
                                sequence.Append(txtBase.DOText(DisplayBasePowerNum(nowValue), rollTime).SetEase(rollEaseType).OnComplete(() => { SetInitPosition(nowValue, changePower, isAdd); }));
                            }
                        }
#if UNITY_EDITOR
                        DebugEx.Log($"count {i} changeValue {changeValue} nowValue {nowValue} isAdd {isAdd}  basePower {basePower} changePower {changePower} nowPower {nowPower} rollTime {rollTime}");
#endif
                    }
                    sequence.Join(textChangeSequence);
 
                    sequence.OnComplete(() =>
                    {
                        moveEndTime = Time.time;
                        nowState = AnimeState.WaitFadeOut;
                    });
                }
            }
            else if (nowState == AnimeState.WaitFadeOut)
            {
                if (Time.time - moveEndTime > moveEndWaitTime)
                {
                    nowState = AnimeState.FadeOut;
                    fadeOutSequence = DOTween.Sequence();
                    fadeOutSequence.Append(transZhanLi.DOScale(fadeOutToBigVector, fadeOutToBigDuration).SetEase(fadeOutToBigEaseType));
                    fadeOutSequence.Append(transZhanLi.DOScale(startVector, fadeOutToSmallDuration).SetEase(fadeOutToSmallEaseType).OnComplete(CloseClick));
                }
            }
        }
 
        private void ResetToFadeIn()
        {
            sequence.Kill();
            textChangeSequence.Kill();
            fadeOutSequence.Kill();
            uiFrame.SetActive(false);
            fadeInEndTime = 0;
            moveEndTime = 0;
            transZhanLi.transform.localScale = startVector;
            CheckPosition();
            SetNum();
            SetInitPosition(basePower, changePower, isAdd);
            ResetColorA();
            DisplayNum();
            nowState = AnimeState.FadeIn;
            transZhanLi.DOScale(fadeInToBigVector, fadeInToBigDuration).SetEase(fadeInToBigEaseType).OnComplete(() =>
            {
                transZhanLi.DOScale(fadeInToSmallVector, fadeInToSmallDuration).SetEase(fadeInToSmallEaseType).OnComplete(() =>
                {
                    fadeInEndTime = Time.time;
                    nowState = AnimeState.WaitMove;
 
                    uiFrame.SetActive(true);
                    uiFrame.SetLoopCount(1);
                    uiFrame.ResetFrame(uiFrameKey);
                });
            });
        }
 
        private void ResetToWaitMove()
        {
            sequence.Kill();
            textChangeSequence.Kill();
            fadeOutSequence.Kill();
            uiFrame.SetActive(false);
            fadeInEndTime = Time.time;
            moveEndTime = 0;
            transZhanLi.transform.localScale = fadeInToSmallVector;
            SetNum();
            SetInitPosition(basePower, changePower, isAdd);
            ResetColorA();
            DisplayNum();
 
            uiFrame.SetActive(true);
            uiFrame.SetLoopCount(1);
            uiFrame.ResetFrame(uiFrameKey);
            nowState = AnimeState.WaitMove;
        }
 
        private void SetInitPosition(long basePower, long changePower, bool isAdd)
        {
            txtBase.rectTransform.anchorMin = new Vector2(0, 0);
            txtBase.rectTransform.anchorMax = new Vector2(0, 0);
            txtBase.rectTransform.pivot = new Vector2(0, 0);
            txtBase.rectTransform.anchoredPosition = new Vector2(0, 0);
 
            transChange.anchorMin = new Vector2(0, 0);
            transChange.anchorMax = new Vector2(0, 0);
            transChange.pivot = new Vector2(0, 0);
            string displayBasePowerNum = DisplayBasePowerNum(basePower);
            int txtBaseTransWidth = GetBaseTransWidth(displayBasePowerNum);
            float x = txtBaseTransWidth * txtBaseMultiple + baseAndChangeInterval;
            transChange.anchoredPosition = new Vector2(x, transChangeY);
 
            txtChange.rectTransform.anchorMin = new Vector2(0, 0);
            txtChange.rectTransform.anchorMax = new Vector2(0, 0);
            txtChange.rectTransform.pivot = new Vector2(0, 0);
            txtChange.rectTransform.anchoredPosition = new Vector2(0, 0);
 
            imgArrow.rectTransform.anchorMin = new Vector2(0, 0);
            imgArrow.rectTransform.anchorMax = new Vector2(0, 0);
            imgArrow.rectTransform.pivot = new Vector2(0, 0);
            string displayChangePowerNum = DisplayChangePowerNum(isAdd, changePower);
            int txtChangeTransWidth = GetChangeTransWidth(displayChangePowerNum);
            x = txtChangeTransWidth * txtChangeMultiple + changeAndArrowInterval;
            if (!IsHasPoint(changePower))
            {
                x += intArrowAddInterval;
            }
            imgArrow.rectTransform.anchoredPosition = new Vector2(x, 0);
        }
 
        private bool IsHasPoint(long changePower) 
        {
            var chars = UIHelper.ReplaceLargeArtNum(changePower);
            for (int i = 0; i < chars.Length; i++)
            {
                if (chars[i] == '.')
                {
                    return true;
                }
            }
            return false;
        }
 
        private int GetBaseTransWidth(string numStr)
        {
            return Mathf.CeilToInt(numStr.Length * baseFontWidth);
        }
 
        private int GetChangeTransWidth(string numStr)
        {
            return Mathf.CeilToInt(numStr.Length * changeFontWidth);
        }
 
        private void SetNum()
        {
            nowPower = (long)onMainModel.prowNum;
            changePower = (long)onMainModel.prowNumChange;
            isAdd = onMainModel.isAdd;
            basePower = isAdd ? nowPower - changePower : nowPower + changePower;
        }
 
        private void DisplayNum()
        {
            txtBase.text = DisplayBasePowerNum(basePower);
            txtChange.text = DisplayChangePowerNum(isAdd, changePower);
            imgArrow.SetSprite(DisplayState(isAdd));
        }
 
        private string DisplayState(bool isAdd)
        {
            return StringUtility.Contact(isAdd ? "FightPointUP" : "FightPointDown");
        }
 
        private string DisplayBasePowerNum(long basePower)
        {
            var chars = basePower.ToString();
            StringBuilder stringBuild = new StringBuilder();
            for (var i = 0; i < chars.Length; i++)
            {
                var numChar = GetNumKey("FightPointBase", chars[i]);
                if (numChar > 0)
                {
                    stringBuild.Append((char)numChar);
                }
            }
            return stringBuild.ToString();
        }
 
        private string DisplayChangePowerNum(bool isAdd, long changePower)
        {
            var chars = UIHelper.ReplaceLargeArtNum(changePower);
 
            StringBuilder stringBuild = new StringBuilder();
            if (isAdd)
            {
                int plus = DamageNumConfig.Get("FightPointAdd").plus;
                stringBuild.Append((char)plus);
                for (var i = 0; i < chars.Length; i++)
                {
                    var numChar = GetNumKey("FightPointAdd", chars[i]);
                    if (numChar > 0)
                    {
                        stringBuild.Append((char)numChar);
                    }
                }
            }
            else
            {
                int minus = DamageNumConfig.Get("FightPointDec").minus;
                stringBuild.Append((char)minus);
                for (var i = 0; i < chars.Length; i++)
                {
                    var numChar = GetNumKey("FightPointDec", chars[i]);
                    if (numChar > 0)
                    {
                        stringBuild.Append((char)numChar);
                    }
                }
            }
            return stringBuild.ToString();
        }
 
        private int GetNumKey(string _pattern, int _num)
        {
            var key = string.Empty;
            var config = DamageNumConfig.Get(_pattern);
 
            //.的ASCII码是46
            if (_num == 46)
            {
                return config.nums[10];
            }
            //k的ASCII码是107
            else if (_num == 107)
            {
                return config.nums[11];
            }
            //m的ASCII码是109
            else if (_num == 109)
            {
                return config.nums[12];
            }
            //b的ASCII码是98
            else if (_num == 98)
            {
                return config.nums[13];
            }
            //t的ASCII码是116
            else if (_num == 116)
            {
                return config.nums[14];
            }
            return config.nums[_num - 48];
        }
 
        private void ResetColorA()
        {
            Color textColor = txtChange.color;
            textColor.a = 1f;
            txtChange.color = textColor;
            textColor = imgArrow.color;
            textColor.a = 1f;
            imgArrow.color = textColor;
        }
 
        private void CheckPosition()
        {
            var type = WindowType.None;
            if (WindowCenter.Instance.IsOpen<TreasureBaseWin>())
            {
                type = WindowType.TreasureLevelUp;
            }
            else if (WindowCenter.Instance.IsOpen<RealmWin>())
            {
                type = WindowType.Realm;
            }
            var _index = powerUpPositions.FindIndex((x) =>
            {
                return x.windowType == type;
            });
            if (_index != -1)
            {
                transZhanLi.transform.localPosition = powerUpPositions[_index].position;
            }
        }
 
        [Serializable]
        public struct PowerUpPosition
        {
            public WindowType windowType;
            public Vector3 position;
        }
 
        public enum WindowType
        {
            None,
            TreasureLevelUp,
            Realm,
        }
    }
}