NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/UI/UI_LevelSelectController.cs

1250 lines
41 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using cfg.FightCfg;
using cfg.LevelCfg;
using Cysharp.Threading.Tasks;
using Framework;
using Gameplay;
using Gameplay.Common;
using Gameplay.Level;
using PhxhSDK;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Button = UnityEngine.UI.Button;
using Constants = Framework.Constants;
using Image = UnityEngine.UI.Image;
public class UI_LevelSelectController : UIWindow
{
public TMP_Text Text_ChapterName;
public TMP_Text Text_ChapterNum;
public Image Image_ProcessBar;
public Button Button_GetAll;
public TMP_Text Text_StarNum;
public Button Button_Easy;
public Button Button_Hard;
/// <summary>
/// 打开关卡选择界面
/// </summary>
/// <param name="levelInfo">有数据则跳转到对应关卡选项,没有数据则显示默认</param>
/// <returns></returns>
public static async UniTask<UIWindow> Open(LevelInfo levelInfo = null)
{
// 切换场景会有瞬间卡顿先打开UI
UIWindow uiWindow = await UIManager.Instance.CreateAndOpenWindow(UINameConst.UI_LevelSelect, levelInfo);
CommonUtils.ChangeUIScene(Constants.UI_LEVEL_SELECTED_SCENE_PATH); // 切换到关卡选择场景
CameraManager.Instance.SetMainCameraActive(true);
return uiWindow;
}
#region 类
/// <summary>
/// 电池
/// </summary>
private class Batterie : UIGameObjectWrapper
{
/// <summary>
/// 电池电量
/// </summary>
private readonly List<GameObject> listBatteryPower;
public Batterie(GameObject root) : base(root)
{
listBatteryPower = new(GoRoot.transform.childCount);
for (int i = 0; i < GoRoot.transform.childCount; ++i)
{
listBatteryPower.Add(GoRoot.transform.GetChild(i).gameObject);
}
}
/// <summary>
/// 入口
/// </summary>
/// <param name="batteryPower"></param>
public void SetInfo(float batteryPower)
{
int showCount = Mathf.CeilToInt(listBatteryPower.Count * batteryPower);
for (int i = 0; i < listBatteryPower.Count; ++i)
{
listBatteryPower[i].IsScaleShow(i + 1 == showCount);
}
}
}
/// <summary>
/// WIFI
/// </summary>
private class NetSignal : UIGameObjectWrapper
{
/// <summary>
/// Wifi信号
/// </summary>
private readonly List<GameObject> listWifi;
public NetSignal(GameObject root) : base(root)
{
listWifi = new(GoRoot.transform.childCount);
for (int i = 0; i < GoRoot.transform.childCount; ++i)
{
listWifi.Add(GoRoot.transform.GetChild(i).gameObject);
}
}
/// <summary>
/// 入口
/// </summary>
/// <param name="networkSignal"></param>
public void SetInfo(float networkSignal)
{
int showCount = Mathf.CeilToInt(listWifi.Count * networkSignal);
for (int i = 0; i < listWifi.Count; ++i)
{
listWifi[i].IsScaleShow(i + 1 == showCount);
}
}
}
/// <summary>
/// 选择面板基类
/// </summary>
private abstract class BaseChoosePanel : UIGameObjectWrapper
{
protected ScrollRect scrollRect;
/// <summary>
/// 章节类型
/// </summary>
private LevelChapterType chapterType;
/// <summary>
/// 章节信息
/// </summary>
private LevelGroupInfo levelGroupInfo;
public LevelChapterType ChapterType
{
get { return chapterType; }
set { chapterType = value; }
}
public LevelGroupInfo ChapterInfo
{
get { return levelGroupInfo; }
set { levelGroupInfo = value; }
}
public new bool IsScaleShow
{
get
{
if (GoRoot.transform.localScale.x == 0f)
return false;
if (GoRoot.transform.localScale.y == 0f)
return false;
return true;
}
set
{
GoRoot.IsScaleShow(value);
if (scrollRect == null)
return;
scrollRect.enabled = value;
}
}
public BaseChoosePanel(GameObject root) : base(root)
{
}
public abstract void SetInfo();
}
/// <summary>
/// 模式选择面板
/// </summary>
private class ModeChoosePanel : BaseChoosePanel
{
/// <summary>
/// 模式选项
/// </summary>
private class ModeItem : UIGameObjectWrapper
{
#region UI
/// <summary>
/// 模式名
/// </summary>
private TMP_Text textModeName;
/// <summary>
/// 当前关卡名
/// </summary>
private TMP_Text textCurLevelName;
/// <summary>
/// 当前关卡编号
/// </summary>
private TMP_Text textCurLevelNum;
/// <summary>
/// 上一次关卡名
/// </summary>
private TMP_Text textLastLevelName;
/// <summary>
/// 上一次关卡编号
/// </summary>
private TMP_Text textLastLevelNum;
/// <summary>
/// 当前关卡
/// </summary>
private GameObject goCurLevel;
/// <summary>
/// 上一次关卡
/// </summary>
private GameObject goLastLevel;
/// <summary>
/// 选择章节按钮
/// </summary>
private Button buttonSelectChapter;
/// <summary>
/// 进入当前关卡按钮
/// </summary>
private Button buttonCurLevel;
/// <summary>
/// 进入上一次关卡按钮
/// </summary>
private Button buttonLastLevel;
#endregion
/// <summary>
/// 关卡章节类型
/// </summary>
private readonly LevelChapterType type;
/// <summary>
/// 点击模式
/// </summary>
private readonly Action<LevelChapterType> mode;
/// <summary>
/// 点击关卡
/// </summary>
private readonly Action<LevelInfo> level;
private LevelInfo curLevelInfo;
private LevelInfo lastLevelInfo;
public ModeItem(GameObject root, LevelChapterType levelChapterType, Action<LevelChapterType> modeAction, Action<LevelInfo> levelAction) : base(root)
{
type = levelChapterType;
mode = modeAction;
level = levelAction;
buttonSelectChapter = GoRoot.GetComponent<Button>();
buttonCurLevel = GetComponent<Button>("Image_TextBG/ButtonCurLevel");
buttonLastLevel = GetComponent<Button>("Image_TextBG/ButtonLastLevel");
textModeName = GetComponent<TMP_Text>("Image_TextBG/Text_MainLevel");
textCurLevelName = GetComponent<TMP_Text>("Image_TextBG/Image_BlackBar/Text_MainLevelName");
textCurLevelNum = GetComponent<TMP_Text>("Image_TextBG/Image_BlackBar/Text_MainLevelNum");
textLastLevelName = GetComponent<TMP_Text>("Image_TextBG/Image_LastRect/Text_MainLevelName");
textLastLevelNum = GetComponent<TMP_Text>("Image_TextBG/Image_LastRect/Text_MainLevelNum");
goCurLevel = FindObj("Image_TextBG/Image_BlackBar");
goLastLevel = FindObj("Image_TextBG/Image_LastRect");
buttonSelectChapter.onClick.AddListener(OnSelectMode);
buttonCurLevel.onClick.AddListener(OnSelectCurLevel);
buttonLastLevel.onClick.AddListener(OnSelectLastLevel);
}
public void SetInfo()
{
textModeName.text = type switch
{
LevelChapterType.Main => CommonUtils.GetLocalizeText("LevelSelect_MainLevel"),
LevelChapterType.Resource => CommonUtils.GetLocalizeText("LevelSelect_ResoureLevel"),
LevelChapterType.Storyline => CommonUtils.GetLocalizeText("LevelSelect_StorylineLevel"),
_ => throw new Exception("未处理类型"),
};
curLevelInfo = LevelManager.Instance.GetLatestLevelInfo(type);
if (curLevelInfo == null)
goCurLevel.IsScaleShow(false);
else
{
textCurLevelNum.text = $"{curLevelInfo.ChapterIndex:00}-{curLevelInfo.LevelIndex:00}";
textCurLevelName.text = curLevelInfo.Name;
goCurLevel.IsScaleShow(true);
}
lastLevelInfo = LevelManager.Instance.GetLastFightLevelInfo(type);
if (lastLevelInfo == null)
goLastLevel.IsScaleShow(false);
else
{
textLastLevelNum.text = $"{lastLevelInfo.ChapterIndex:00}-{lastLevelInfo.LevelIndex:00}";
textLastLevelName.text = lastLevelInfo.Name;
goLastLevel.IsScaleShow(true);
}
IsScaleShow = true;
}
/// <summary>
/// 选择模式
/// </summary>
private void OnSelectMode()
{
mode?.Invoke(type);
}
/// <summary>
/// 选择当前关卡
/// </summary>
private void OnSelectCurLevel()
{
if (curLevelInfo == null)
return;
level?.Invoke(curLevelInfo);
}
/// <summary>
/// 选择上一次关卡
/// </summary>
private void OnSelectLastLevel()
{
if (lastLevelInfo == null)
return;
level?.Invoke(lastLevelInfo);
}
}
/// <summary>
/// 选项列表
/// </summary>
private readonly List<ModeItem> listModeItem = new();
public ModeChoosePanel(GameObject root, Action<LevelChapterType> callbackAction, Action<LevelInfo> levelAction) : base(root)
{
scrollRect = GetComponent<ScrollRect>("Scroll View");
listModeItem.Add(new ModeItem(FindObj("Scroll View/Viewport/Content/Button_MainLevel"), LevelChapterType.Main, callbackAction, levelAction));
listModeItem.Add(new ModeItem(FindObj("Scroll View/Viewport/Content/Button_ResourceLevel"), LevelChapterType.Resource, callbackAction, levelAction));
listModeItem.Add(new ModeItem(FindObj("Scroll View/Viewport/Content/Button_StorylineLevel"), LevelChapterType.Storyline, callbackAction, levelAction));
IsScaleShow = false;
}
public override void SetInfo()
{
foreach (ModeItem modeItem in listModeItem)
{
modeItem.SetInfo();
}
IsScaleShow = true;
}
}
/// <summary>
/// 关卡类型选择面板
/// </summary>
private class ChapterChoosePanel : BaseChoosePanel
{
/// <summary>
/// 章节项
/// </summary>
private class ChapterItem : UIGameObjectWrapper
{
#region UI
/// <summary>
/// 章节编号
/// </summary>
private TMP_Text textChapterNum;
/// <summary>
/// 章节名
/// </summary>
private TMP_Text textChapterName;
/// <summary>
/// 当前简单星星数量
/// </summary>
private TMP_Text textEasyStarNow;
/// <summary>
/// 简单星星最大数量
/// </summary>
private TMP_Text textEasyStarMax;
/// <summary>
/// 当前困难星星数量
/// </summary>
private TMP_Text textHardStarNow;
/// <summary>
/// 困难星星最大数量
/// </summary>
private TMP_Text textHardStarMax;
/// <summary>
/// 简单进度条
/// </summary>
private Image imageProcessBarEasy;
/// <summary>
/// 困难进度条
/// </summary>
private Image imageProcessBarHard;
private RedPointUIController redPointUIController;
private Button button;
#endregion
private readonly Action<ChapterInfo> callback;
private ChapterInfo info;
public ChapterItem(GameObject root, Action<ChapterInfo> callbackAction) : base(root)
{
callback = callbackAction;
textChapterNum = GetComponent<TMP_Text>("Text_ChapterNum");
textChapterName = GetComponent<TMP_Text>("Text_ChapterName");
textEasyStarNow = GetComponent<TMP_Text>("UI_Easy/Text_EasyStarNow");
textEasyStarMax= GetComponent<TMP_Text>("UI_Easy/Text_EasyStarMax");
textHardStarNow = GetComponent<TMP_Text>("UI_Hard/Text_HardStarNow");
textHardStarMax = GetComponent<TMP_Text>("UI_Hard/Text_HardStarMax");
imageProcessBarEasy = GetComponent<Image>("UI_Easy/Image_ProcessBarEasy");
imageProcessBarHard = GetComponent<Image>("UI_Hard/Image_ProcessBarHard");
redPointUIController = GetComponent<RedPointUIController>("UI_RedPoint");
button = GoRoot.GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
public void SetInfo(int index, ChapterInfo chapterInfo)
{
info = chapterInfo;
textChapterNum.text = $"{index:D2}";
textChapterName.text = info.Name;
int starCountEasy = info.EasyLevelGroup?.StarCount ?? 0;
int starMaxEasy = info.EasyLevelGroup?.StarMax ?? 1;
imageProcessBarEasy.fillAmount = (float)starCountEasy / starMaxEasy;
textEasyStarNow.text = starCountEasy.ToString();
textEasyStarMax.text = starMaxEasy.ToString();
int starCountHard = info.HardLevelGroup?.StarCount ?? 0;
int starMaxHard = info.HardLevelGroup?.StarMax ?? 1;
imageProcessBarHard.fillAmount = (float)starCountHard / starMaxHard;
textHardStarNow.text = starCountHard.ToString();
textHardStarMax.text = starMaxHard.ToString();
if (redPointUIController != null)
redPointUIController.NodeID = info.RedPointNode.ID;
IsScaleShow = true;
}
private void OnClick()
{
callback?.Invoke(info);
}
}
/// <summary>
/// 列表箭头
/// </summary>
private GameObject goArrow;
/// <summary>
/// 循环列表
/// </summary>
private RecycleView recycleView;
/// <summary>
/// 章节字典
/// </summary>
private readonly Dictionary<int, ChapterItem> dicChapterItem = new();
private readonly Action<ChapterInfo> callback;
/// <summary>
/// 章节信息
/// </summary>
private List<ChapterInfo> listShowChapterInfo;
public ChapterChoosePanel(GameObject root, Action<ChapterInfo> callbackAction) : base(root)
{
callback = callbackAction;
goArrow = FindObj("Image_ChapterBG/Triangle");
recycleView = GetComponent<RecycleView>("Image_ChapterBG/RecyScrollView");
scrollRect = recycleView.ScrollRect;
recycleView.Init(OnRefreshItem);
recycleView.ScrollRect.onValueChanged.AddListener(OnRefreshArrow);
IsScaleShow = false;
}
public override void SetInfo()
{
LevelManager.Instance.GetChapterInfosByType(ChapterType, ref listShowChapterInfo);
listShowChapterInfo.Sort((a, b) => { return a.ID.CompareTo(b.ID); });
recycleView.ShowList(listShowChapterInfo.Count);
OnRefreshArrow(Vector2.one);
IsScaleShow = true;
}
/// <summary>
/// 刷新列表项
/// </summary>
/// <param name="cell"></param>
/// <param name="index"></param>
private void OnRefreshItem(GameObject cell, int index)
{
if (!dicChapterItem.TryGetValue(cell.GetInstanceID(), out ChapterItem item))
{
item = new ChapterItem(cell, callback);
dicChapterItem.Add(cell.GetInstanceID(), item);
}
if (index < 0 || index >= listShowChapterInfo.Count)
{
DebugUtil.LogError("索引错误");
return;
}
item.SetInfo(index, listShowChapterInfo[index]);
}
/// <summary>
/// 刷新列表箭头
/// </summary>
/// <param name="vector2"></param>
private void OnRefreshArrow(Vector2 vector2)
{
if (recycleView.IsShowOnePage)
goArrow.IsScaleShow(false);
else
goArrow.IsScaleShow(vector2.y > 0f);
}
}
/// <summary>
/// 关卡选择面板
/// </summary>
private class LevelChoosePanel : BaseChoosePanel
{
private class LevelItem : UIGameObjectWrapper
{
#region UI
/// <summary>
/// 关卡编号
/// </summary>
private TMP_Text textLevelNum;
/// <summary>
/// 关卡名
/// </summary>
private TMP_Text Text_LevelName;
private TMP_Text textDayOrNight;
private TMP_Text textWeatherAndLand01;
private TMP_Text textweatherAndLand02;
private GameObject goStar1;
private GameObject goStar2;
private GameObject goStar3;
private GameObject goMapDetail;
private GameObject goTarget;
private Image imageEnvironment;
private Image imageWeather;
private Image imageDaynight;
private RedPointUIController redPointUIController;
private Button button;
#endregion
private readonly Action<LevelInfo> callback;
private LevelInfo info;
public LevelItem(GameObject root, Action<LevelInfo> callbackAction) : base(root)
{
callback = callbackAction;
textLevelNum = GetComponent<TMP_Text>("Text_LevelNum");
Text_LevelName = GetComponent<TMP_Text>("Text_LevelName");
textDayOrNight = GetComponent<TMP_Text>("MapDetail/Image_DayOrNight/Text_DayOrNight");
textWeatherAndLand01 = GetComponent<TMP_Text>("MapDetail/Image_weather/Text_WeatherAndLand01");
textweatherAndLand02 = GetComponent<TMP_Text>("MapDetail/Image_environment/Text_WeatherAndLand02");
goStar1 = FindObj("Target/Text_01/Image_Yellow");
goStar2 = FindObj("Target/Text_02/Image_Yellow");
goStar3 = FindObj("Target/Text_03/Image_Yellow");
goMapDetail = FindObj("MapDetail");
goTarget = FindObj("Target");
imageEnvironment = GetComponent<Image>("MapDetail/Image_environment");
imageWeather = GetComponent<Image>("MapDetail/Image_weather");
imageDaynight = GetComponent<Image>("MapDetail/Image_DayOrNight");
redPointUIController = GetComponent<RedPointUIController>("UI_RedPoint");
button = GoRoot.GetComponent<Button>();
button.onClick.AddListener(OnClick);
}
public async void SetInfo(LevelInfo levelInfo)
{
info = levelInfo;
textLevelNum.text = $"{info.ChapterIndex:00}-{info.LevelIndex:00}";
Text_LevelName.text = info.Name;
if (info.IsStory)
{
goMapDetail.IsScaleShow(false);
goTarget.IsScaleShow(false);
}
else
{
bool[] StarResult = info.StarResult;
goStar1.IsScaleShow(StarResult[0]);
goStar2.IsScaleShow(StarResult[1]);
goStar3.IsScaleShow(StarResult[2]);
await AssetManager.Instance.WaitAllPreloads();
DataEnviorment environmentConfig = CommonUtils.GetEnvironmentConfig(levelInfo.EnvironmentType);
imageEnvironment.sprite = AssetManager.Instance.GetPreLoadResult<Sprite>(environmentConfig.Icon);
textweatherAndLand02.text = CommonUtils.GetLocalizeText(environmentConfig.NameLocal);
DataEnWeather weatherConfig = CommonUtils.GetWeatherConfig(levelInfo.WeatherType);
imageWeather.sprite = AssetManager.Instance.GetPreLoadResult<Sprite>(weatherConfig.Icon);
textWeatherAndLand01.text = CommonUtils.GetLocalizeText(weatherConfig.NameLocal);
DataDayNightProp dayNightConfig = CommonUtils.GetDayNightConfig(levelInfo.DayNightType);
imageDaynight.sprite = AssetManager.Instance.GetPreLoadResult<Sprite>(dayNightConfig.Icon);
textDayOrNight.text = CommonUtils.GetLocalizeText(dayNightConfig.NameLocal);
goMapDetail.IsScaleShow(true);
goTarget.IsScaleShow(true);
}
if (redPointUIController != null)
redPointUIController.NodeID = info.RedPointNode.ID;
IsScaleShow = true;
}
private void OnClick()
{
callback?.Invoke(info);
}
}
/// <summary>
/// 列表箭头
/// </summary>
private GameObject goArrow;
/// <summary>
/// 循环列表
/// </summary>
private RecycleView recycleView;
/// <summary>
/// 关卡进度
/// </summary>
private GameObject goProcess;
/// <summary>
/// 关卡模式
/// </summary>
private GameObject goMode;
/// <summary>
/// 关卡信息列表
/// </summary>
private readonly List<LevelInfo> listLevelInfo = new();
/// <summary>
/// 关卡字典
/// </summary>
private readonly Dictionary<int, LevelItem> dicLevelItem = new();
private readonly Action<LevelInfo> callback;
public bool IsShowMode
{
set
{
goProcess.IsScaleShow(value);
goMode.IsScaleShow(value);
}
}
public LevelChoosePanel(GameObject root, Action<LevelInfo> callbackAction) : base(root)
{
callback = callbackAction;
goArrow = FindObj("Triangle");
goProcess = FindObj("Image_ProcessBG");
goMode = FindObj("Image_ModeBG");
recycleView = GetComponent<RecycleView>("Image_LevelBG/Scroll View");
scrollRect = recycleView.ScrollRect;
recycleView.Init(OnRefreshItem);
recycleView.ScrollRect.onValueChanged.AddListener(OnRefreshArrow);
IsScaleShow = false;
}
public override void SetInfo()
{
listLevelInfo.Clear();
foreach (LevelInfo levelInfo in ChapterInfo)
{
if (!levelInfo.IsLock)
listLevelInfo.Add(levelInfo);
}
listLevelInfo.Sort((a, b) => a.ID.CompareTo(b.ID));
recycleView.ShowList(listLevelInfo.Count);
OnRefreshArrow(Vector2.one);
IsShowMode = ChapterType != LevelChapterType.Storyline;
IsScaleShow = true;
}
private void OnRefreshItem(GameObject cell, int index)
{
if (!dicLevelItem.TryGetValue(cell.GetInstanceID(), out LevelItem levelItem))
{
levelItem = new LevelItem(cell, callback);
dicLevelItem.Add(cell.GetInstanceID(), levelItem);
}
if (index < 0 || index >= listLevelInfo.Count)
{
DebugUtil.LogError($"索引错误 {index}");
return;
}
levelItem.SetInfo(listLevelInfo[index]);
}
/// <summary>
/// 刷新列表箭头
/// </summary>
/// <param name="vector2"></param>
private void OnRefreshArrow(Vector2 vector2)
{
if (recycleView.IsShowOnePage)
goArrow.IsScaleShow(false);
else
goArrow.IsScaleShow(vector2.y > 0f);
}
}
#endregion
/// <summary>
/// 页签类型
/// </summary>
private enum E_PageType
{
/// <summary>
/// 无效
/// </summary>
None = 0,
/// <summary>
/// 模式
/// </summary>
Mode = 1,
/// <summary>
/// 章节
/// </summary>
Chapter = 2,
/// <summary>
/// 关卡
/// </summary>
Level = 3,
}
#region UI
/// <summary>
/// 返回按钮
/// </summary>
private Button buttonBack;
/// <summary>
/// 主页按钮
/// </summary>
private Button buttonHome;
#endregion
private Animation animation;
private RectTransform _starRewardsParent;
private RedPointUIController easyLevelGroupRedPointUI;
private RedPointUIController hardLevelGroupRedPointUI;
/// <summary>
/// 进入动画名
/// </summary>
private const string IN_ANIMATION_NAME = "LS_MoveIn";
/// <summary>
/// 退出动画名
/// </summary>
private const string OUT_ANIMATION_NAME = "LS_MoveOut";
#region 私有变量
/// <summary>
/// 当前章节信息
/// </summary>
private ChapterInfo curChapterInfo;
/// <summary>
/// 当前简单关卡组信息
/// </summary>
private LevelGroupInfo curEasyLevelGroupInfo;
/// <summary>
/// 当前困难关卡组信息
/// </summary>
private LevelGroupInfo curHardLevelGroupInfo;
/// <summary>
/// 当前剧情关卡组信息
/// </summary>
private LevelGroupInfo curPlotLevelGroupInfo;
/// <summary>
/// 当前关卡组信息
/// </summary>
private LevelGroupInfo curLevelGroupInfo;
private float _progressmoveSpeed = 1f;
private CancellationTokenSource _cts;
/// <summary>
/// 电量
/// </summary>
private Batterie batterie;
/// <summary>
/// 网络信号
/// </summary>
private NetSignal netSignal;
/// <summary>
/// 刷新计时
/// </summary>
private float timer;
/// <summary>
/// 面板字典
/// </summary>
private readonly Dictionary<E_PageType, BaseChoosePanel> dicPanel = new();
/// <summary>
/// 当前页签
/// </summary>
private E_PageType curPage = E_PageType.None;
/// <summary>
/// 章节类型
/// </summary>
private LevelChapterType curChapterType;
/// <summary>
/// 货币栏
/// </summary>
private UI_CurrencyList currencyList;
#endregion
public override async void PreLoad(object data = null)
{
await CommonUtils.PreLoadOrUnloadEnvironmentWeatherDayNightIcon(true);
}
public override void OnInit()
{
UI_LevelSelectBinder.GetComponents(this);
buttonBack = GetComponent<Button>("Button_Back/Button_back");
buttonHome = GetComponent<Button>("Button_Back/Button_Home");
animation = GetComponent<Animation>();
currencyList = GetComponent<UI_CurrencyList>("UI_CurrencyList");
easyLevelGroupRedPointUI = Button_Easy.transform.Find("UI_RedPoint").GetComponent<RedPointUIController>();
hardLevelGroupRedPointUI = Button_Hard.transform.Find("UI_RedPoint").GetComponent<RedPointUIController>();
batterie = new Batterie(FindObj("UI_BattertSignal/BatteryRoot"));
netSignal = new NetSignal(FindObj("UI_BattertSignal/SignalRoot"));
dicPanel.Add(E_PageType.Mode, new ModeChoosePanel(FindObj("UI_ModeChoose"), OnMode, OnLevel));
dicPanel.Add(E_PageType.Chapter, new ChapterChoosePanel(FindObj("UI_LevelGroupChoose"), OnChapter));
dicPanel.Add(E_PageType.Level, new LevelChoosePanel(FindObj("UI_LevelChoose"), OnLevel));
//_currencyList = GetComponent<UI_CurrencyList>("UI_Topbtn/UI_CurrencyList");
_starRewardsParent = Image_ProcessBar.transform as RectTransform;
currencyList.SetData(GLConfig.Inst.data.GoldItemId, GLConfig.Inst.data.DiamondItemId, GLConfig.Inst.data.EnergyPointID);
BindButton(buttonBack, OnBack);
BindButton(buttonHome, OnHome);
BindButton(Button_Easy, OnEasy);
BindButton(Button_Hard, OnHard);
BindButton(Button_GetAll, OnStarReward);
EventManager.Instance.Register(EventManager.EventName.ChapterInfoChange, OnRefresh);
EventManager.Instance.Register(EventManager.EventName.LevelUnlock, OnRefresh);
EventManager.Instance.Register(EventManager.EventName.LevelInfoChanged, OnRefresh);
}
protected override void OnShowWindow(object data = null)
{
base.OnShowWindow(data);
SelectPage(E_PageType.Mode);
if (data is LevelInfo levelInfo)
{
OnMode(levelInfo.ChapterInfo.ChapterType);
OnChapter(levelInfo.ChapterInfo);
}
currencyList.Refresh();
}
protected override void OnReloadWindow(object data = null)
{
OnRefresh();
}
protected override void OnUpdate()
{
timer += Time.deltaTime;
if (timer >= 1f) // 每秒刷新电量和信号
{
batterie.SetInfo(DeviceHelper.GetBatteryLevel());
netSignal.SetInfo(DeviceHelper.GetNetworkSignal());
timer -= 1f;
}
}
public override async UniTask<bool> OnBack(object data = null)
{
OnBack();
await UniTask.Yield();
return true;
}
public override async void OnRelease()
{
EventManager.Instance.Unregister(EventManager.EventName.ChapterInfoChange, OnRefresh);
EventManager.Instance.Unregister(EventManager.EventName.LevelUnlock, OnRefresh);
EventManager.Instance.Unregister(EventManager.EventName.LevelInfoChanged, OnRefresh);
await CommonUtils.PreLoadOrUnloadEnvironmentWeatherDayNightIcon(false);
curPage = E_PageType.Mode;
_cts?.Cancel();
_cts?.Dispose();
base.OnRelease();
}
/// <summary>
/// 选择页签
/// </summary>
private void SelectPage(E_PageType pageType)
{
if (curPage == pageType)
return;
if (dicPanel.TryGetValue(curPage, out BaseChoosePanel baseChoosePanel))
baseChoosePanel.IsScaleShow = false;
curPage = pageType;
OnRefresh();
switch (curPage)
{
case E_PageType.Mode:
{
batterie.IsScaleShow = true;
netSignal.IsScaleShow = true;
}
break;
case E_PageType.Chapter:
{
batterie.IsScaleShow = true;
netSignal.IsScaleShow = true;
}
break;
case E_PageType.Level:
{
batterie.IsScaleShow = false;
netSignal.IsScaleShow = false;
}
break;
}
}
/// <summary>
/// 刷新面板
/// </summary>
private void OnRefresh()
{
if (dicPanel.TryGetValue(curPage, out BaseChoosePanel baseChoosePanel))
{
baseChoosePanel.ChapterType = curChapterType;
baseChoosePanel.ChapterInfo = curLevelGroupInfo;
baseChoosePanel.SetInfo();
}
}
/// <summary>
/// 初始化章节信息
/// </summary>
/// <returns></returns>
private LevelGroupInfo InitChapter()
{
curEasyLevelGroupInfo = curChapterInfo.EasyLevelGroup;
curHardLevelGroupInfo = curChapterInfo.HardLevelGroup;
curPlotLevelGroupInfo = curChapterInfo.PlotLevelGroup;
Button_Easy.interactable = IsChapterValid(curEasyLevelGroupInfo);
Button_Hard.interactable = IsChapterValid(curHardLevelGroupInfo);
easyLevelGroupRedPointUI.ResetToDefault();
hardLevelGroupRedPointUI.ResetToDefault();
if (curEasyLevelGroupInfo != null)
easyLevelGroupRedPointUI.NodeID = curEasyLevelGroupInfo.RedPointNode.ID;
if (curHardLevelGroupInfo != null)
hardLevelGroupRedPointUI.NodeID = curHardLevelGroupInfo.RedPointNode.ID;
LevelGroupInfo result = IsChapterValid(curEasyLevelGroupInfo) ? curEasyLevelGroupInfo :
IsChapterValid(curHardLevelGroupInfo) ? curHardLevelGroupInfo : curPlotLevelGroupInfo;
return result;
}
/// <summary>
/// 判断章节是否有效
/// </summary>
/// <param name="chapter"></param>
/// <returns></returns>
private bool IsChapterValid(LevelGroupInfo chapter)
{
return chapter != null && !chapter.IsLock;
}
private void ChangeLevelGroup(LevelGroupInfo levelGroupInfo)
{
/*if (curLevelGroupInfo == levelGroupInfo)
return;*/
LevelGroupInfo oldLevelGroupInfo = curLevelGroupInfo;
curLevelGroupInfo = levelGroupInfo;
SetLevelGroupButtonSelected(Button_Easy, levelGroupInfo == curEasyLevelGroupInfo);
SetLevelGroupButtonSelected(Button_Hard, levelGroupInfo == curHardLevelGroupInfo);
if (levelGroupInfo.LevelType != LevelType.Plot &&
(levelGroupInfo.StarList == null || levelGroupInfo.StarList.Length == 0))
{
DebugUtil.LogError($"levelGroup的星级奖励列表未配置!levelGroup ID:{levelGroupInfo.ID}");
return;
}
// 播放切换levelGroup动画
if (oldLevelGroupInfo != null)
{
if (oldLevelGroupInfo.LevelType == LevelType.Plot && levelGroupInfo.LevelType != LevelType.Plot)
animation.Play(IN_ANIMATION_NAME);
if (oldLevelGroupInfo.LevelType != LevelType.Plot && levelGroupInfo.LevelType == LevelType.Plot)
animation.Play(OUT_ANIMATION_NAME);
}
else
{
if (levelGroupInfo.LevelType != LevelType.Plot)
{
animation.Play(IN_ANIMATION_NAME);
var clip = animation[IN_ANIMATION_NAME];
clip.speed = 0f;
clip.time = clip.length;
animation.Sample();
animation.Stop(IN_ANIMATION_NAME);
clip.speed = 1f;
}
}
if (levelGroupInfo.LevelType != LevelType.Plot)
{
//Image_ProcessBG.gameObject.SetActive(true);
int maxTarget = levelGroupInfo.StarList[^1];
float progressLength = _starRewardsParent.rect.width;
var currStarCount = levelGroupInfo.StarCount;
var currRewardIndexMax = levelGroupInfo.OwnRewardMaxIndex;
// for (int i = 0; i < currLevelGroupInfo.StarList.Length; i++)
// {
// var target = currLevelGroupInfo.StarList[i];
//var starReward = await GetAStarReward();
//var button = starReward.GetComponent<Button>();
//button.onClick.RemoveAllListeners();
// var index = i + 1;
// if (_currLevelGroupInfo.CanGetReward(index))
// {
// button.enabled = true;
// button.onClick.AddListener(() => { OnClickStarReward(index); });
// }
// else
// button.enabled = false;
//
// _showStarReward.Add(starReward);
// var targetText = starReward.transform.Find("target_green").GetComponent<TMP_Text>();
// var targetWhiteText = starReward.transform.Find("target_white").GetComponent<TMP_Text>();
// targetText.text = target.ToString();
// targetWhiteText.text = target.ToString();
// var x = ((float)target / maxTarget) * progressLength;
// var rectTrans = starReward.transform as RectTransform;
// rectTrans.anchoredPosition = new Vector2(x, rectTrans.anchoredPosition.y);
// SetStarRewardEnable(starReward, false);
// }
float ratio = (float)currStarCount / maxTarget;
Text_StarNum.text = $"{currStarCount}/{maxTarget}";
_cts?.Cancel();
_cts?.Dispose();
_cts = new CancellationTokenSource();
PlayProgressAnimation(ratio, progressLength, _cts.Token);
}
OnRefresh();
}
private void SetLevelGroupButtonSelected(Button button, bool isSelected)
{
var selectedImage = button.transform.Find("selectedImage");
selectedImage.gameObject.SetActive(isSelected);
var selectedImage_1 = button.transform.Find("selectedImage_1");
selectedImage_1.gameObject.SetActive(isSelected);
var Image_pot = button.transform.Find("Image_pot");
Image_pot.gameObject.SetActive(!isSelected);
}
private async void PlayProgressAnimation(float ratio, float progressLength, CancellationToken token)
{
Image_ProcessBar.fillAmount = 0;
int maxStarCount = curLevelGroupInfo.StarList[^1];
float targetFillAmount = (float)curLevelGroupInfo.StarCount / maxStarCount;
while (Image_ProcessBar.fillAmount < targetFillAmount)
{
float fillAmount = Image_ProcessBar.fillAmount + Time.deltaTime * _progressmoveSpeed;
fillAmount = Mathf.Min(fillAmount, targetFillAmount);
Image_ProcessBar.fillAmount = fillAmount;
bool isCanceled = await UniTask.DelayFrame(1, PlayerLoopTiming.Update, token).SuppressCancellationThrow();
if (isCanceled)
return;
}
}
#region 回调方法
/// <summary>
/// 点击模式
/// </summary>
/// <param name="levelChapterType"></param>
private void OnMode(LevelChapterType levelChapterType)
{
curChapterType = levelChapterType;
SelectPage(E_PageType.Chapter);
}
/// <summary>
/// 点击章节
/// </summary>
private void OnChapter(ChapterInfo chapterInfo)
{
curChapterInfo = chapterInfo;
Text_ChapterName.text = curChapterInfo.Name;
Text_ChapterNum.text = $"{curChapterInfo.Index:00}";
LevelGroupInfo defaultLevelGroup = InitChapter();
if (defaultLevelGroup != null)
ChangeLevelGroup(defaultLevelGroup);
SelectPage(E_PageType.Level);
}
/// <summary>
/// 点击关卡
/// </summary>
private async void OnLevel(LevelInfo levelInfo)
{
if (levelInfo == null)
return;
if (levelInfo.IsStory)
LevelManager.Instance.TryEnterLevel(levelInfo.ID);
else
await UI_LevelDetailController.Open(levelInfo);
}
/// <summary>
/// 返回
/// </summary>
private void OnBack()
{
switch (curPage)
{
case E_PageType.Mode:
{
OnHome();
}
break;
case E_PageType.Chapter:
{
SelectPage(E_PageType.Mode);
}
break;
case E_PageType.Level:
{
SelectPage(E_PageType.Chapter);
}
break;
}
}
/// <summary>
/// 主页
/// </summary>
private void OnHome()
{
CommonUtils.ChangeUIScene(Constants.MAIN_SCENE_PATH);
CloseWindow();
UIManager.Instance.ShowAllUI();
}
/// <summary>
/// 点击简单
/// </summary>
private void OnEasy()
{
if (curEasyLevelGroupInfo != null)
ChangeLevelGroup(curEasyLevelGroupInfo);
}
/// <summary>
/// 点击困难
/// </summary>
private void OnHard()
{
if (curHardLevelGroupInfo != null)
ChangeLevelGroup(curHardLevelGroupInfo);
}
/// <summary>
/// 点击剧情
/// </summary>
private void OnPlot()
{
if (curPlotLevelGroupInfo != null)
ChangeLevelGroup(curPlotLevelGroupInfo);
}
private void OnStarReward()
{
int index = curLevelGroupInfo.OwnRewardMaxIndex + 1;
if (curLevelGroupInfo.CanGetReward(index))
LevelManager.Instance.GetStarReward(curLevelGroupInfo.ID, index);
}
#endregion
}