using System.Collections; using UnityEngine; using UI.LuckyBox; using System.Collections.Generic; using FairyGUI; using System.Threading; using System.Threading.Tasks; using System; using cfg.GfgCfg; using Random = UnityEngine.Random; namespace GFGGame { public class LuckyBoxStarView : BaseWindow { private UI_LuckyBoxStarUI _ui; private List comStars = new List(); private List clickComStars = new List(); private List notClickComStars = new List(); private List dicEffect = new List(); private List effObj = new List(); private EffectUI _effectUI1; private EffectUI _effectUI2; private EffectUI _effectUI3; private EffectUI _effectUI4; private GObject curComStar; //当前选中的星星 private Vector2 lastPos; //鼠标的上一个位置,每颗星星初始时默认为Vector2.right; private List _rewardList; private bool _allEffectsLoaded = false; private const int checkDistance = 40; //鼠标靠近星星周围加减40都算选中星星 private const int imgLineWidth = 10; //线的原始长度 private bool _isLuckyBox = true; //是抽奖(true),是限时主题活动(false) private bool showGuide = false; public override void Dispose() { EffectUIPool.Recycle(_effectUI1); _effectUI1 = null; EffectUIPool.Recycle(_effectUI2); _effectUI2 = null; EffectUIPool.Recycle(_effectUI3); _effectUI3 = null; EffectUIPool.Recycle(_effectUI4); _effectUI4 = null; if (_ui != null) { _ui.Dispose(); _ui = null; } ClearAllEffects(); base.Dispose(); } private void ClearAllEffects() { for (int i = 0; i < dicEffect.Count; i++) { EffectUIPool.Recycle(dicEffect[i]); dicEffect[i] = null; } for (int i = 0; i < effObj.Count; i++) { EffectUIPool.Recycle(effObj[i]); effObj[i] = null; } dicEffect.Clear(); effObj.Clear(); } protected override void OnHide() { base.OnHide(); ClearAllEffects(); int index = 0; GObject star = _ui.target.GetChild(string.Format("comStar{0}_{1}_{2}", _ui.m_ctrlBuyType.selectedIndex, _ui.m_ctrlRewardsType.selectedIndex, index)); while (star != null && star.visible == true) { UI_ComStar comStar = UI_ComStar.Proxy(star); for (int i = comStar.target.numChildren - 1; i >= 0; i--) { if (comStar.target.GetChildAt(i).name == "comLine") continue; var starchild = comStar.target.RemoveChildAt(i); starchild.Dispose(); } index++; star = _ui.target.GetChild(string.Format("comStar{0}_{1}_{2}", _ui.m_ctrlBuyType.selectedIndex, _ui.m_ctrlRewardsType.selectedIndex, index)); UI_ComStar.ProxyEnd(); } notClickComStars.Clear(); clickComStars.Clear(); Timers.inst.Remove(CheckGuide); Debug.Log("OnHide LuckyBoxStarView"); } protected override void OnInit() { base.OnInit(); _ui = UI_LuckyBoxStarUI.Create(); this.viewCom = _ui.target; isfullScreen = true; _ui.m_btnBack.visible = false; _ui.m_btnBack.onClick.Add(OnClickBtnBack); } protected override void OnShown() { base.OnShown(); Debug.Log("OnShown: LuckyBoxStarView"); _allEffectsLoaded = false; _ui.m_star.visible = true; _ui.m_effEnd.visible = false; _rewardList = LuckyBoxDataManager.Instance.RewardList; _ui.m_ctrlBuyType.selectedIndex = _rewardList != null && _rewardList.Count > 1 ? 1 : 0; _isLuckyBox = LuckyBoxDataManager.Instance.luckyBoxIds.IndexOf(LuckyBoxDataManager.Instance.currentBoxId) >= 0; _ui.m_ctrlRewardsType.selectedIndex = LuckyBoxDataManager.Instance.luckyBoxIndex; _ui.m_loaBg.url = ResPathUtil.GetBgImgPath("zx_bg"); // 异步加载所有特效 Timers.inst.StartCoroutine(LoadAllEffects(() => { _allEffectsLoaded = true; SetupViewAfterEffectsLoaded(); })); } private IEnumerator LoadAllEffects(Action onComplete) { // 加载背景特效 EffectUIPool.CreateEffectUI(_ui.m_holder_star, "ui_LuckyBox", "bg_liuxing", onComplete: (effect) => { if (effect != null) { _effectUI1 = effect; } }); EffectUIPool.CreateEffectUI(_ui.m_holder_bg, "ui_LuckyBox", "bg_thing", onComplete: (effect) => { if (effect != null) { _effectUI2 = effect; } }); EffectUIPool.CreateEffectUI(_ui.m_holder_cloud, "ui_LuckyBox", "bg_cloud", onComplete: (effect) => { if (effect != null) { _effectUI3 = effect; } }); EffectUIPool.CreateEffectUI(_ui.m_holder_star_sky, "ui_LuckyBox", "Bg_Sky_lizi", onComplete: (effect) => { if (effect != null) { _effectUI4 = effect; } }); // 等待所有背景特效加载完成 while (_effectUI1.GetObj() == null || _effectUI2.GetObj() == null || _effectUI3.GetObj() == null || _effectUI4.GetObj() == null) { yield return null; } onComplete?.Invoke(); } private void SetupViewAfterEffectsLoaded() { if (!_allEffectsLoaded) return; // 设置触摸事件 _ui.target.onTouchBegin.Add(OnClickUIBegin); _ui.target.onTouchMove.Add(OnClickUIMove); _ui.target.onTouchEnd.Add(OnClickUIEnd); showGuide = GuideDataManager.IsGuideFinish(ConstGuideId.LUCKY_BOX_LINE) <= 0; ResetStartView(); Timers.inst.AddUpdate(CheckGuide); } private void ResetStartView() { curComStar = null; comStars.Clear(); int index = 0; GObject star = _ui.target.GetChild(string.Format("comStar{0}_{1}_{2}", _ui.m_ctrlBuyType.selectedIndex, _ui.m_ctrlRewardsType.selectedIndex, index)); while (star != null && star.visible == true) { UI_ComStar comStar = UI_ComStar.Proxy(star); comStar.m_comLine.target.visible = true; comStar.m_c1.selectedIndex = 0; comStar.m_comLine.target.width = imgLineWidth; comStar.m_comLine.target.rotation = 0; float scale = Random.Range(0.5f, 1f); float rotation = Random.Range(0, 360); // 创建星星特效 CreateStarEffect(comStar, scale, rotation); star.data = new Vector2(comStar.target.x, comStar.target.y); comStars.Add(star); index++; star = _ui.target.GetChild(string.Format("comStar{0}_{1}_{2}", _ui.m_ctrlBuyType.selectedIndex, _ui.m_ctrlRewardsType.selectedIndex, index)); UI_ComStar.ProxyEnd(); } } private void CreateStarEffect(UI_ComStar comStar, float scale, float rotation) { // 创建准备状态的星星 GComponent gcom = CreateEffect(comStar, 1, _isLuckyBox ? "STAR_Ready_Bule" : "STAR_Ready"); gcom.visible = true; comStar.target.AddChildAt(gcom, 1); gcom.scale = new Vector2(scale, scale); gcom.rotation = rotation; // 创建激活状态的星星 GComponent gcom1 = CreateEffect(comStar, 2, _isLuckyBox ? "STAR_Bule" : "STAR"); gcom1.visible = false; comStar.target.AddChildAt(gcom1, 2); gcom1.scale = new Vector2(scale, scale); gcom1.rotation = rotation; } private GComponent CreateEffect(UI_ComStar comStar, int index, string name) { GComponent gcom; if (comStar.target.numChildren > index) { gcom = comStar.target.GetChildAt(index).asCom; } else { gcom = UIPackage.CreateObject("LuckyBox", "ComHolder").asCom; EffectUIPool.CreateEffectUI(gcom.GetChild("holder").asGraph, "ui_LuckyBox", name, 120, onComplete: (effect) => { if (effect != null) { dicEffect.Add(effect); } }); } return gcom; } private void OnClickUIBegin(EventContext context) { if (!_allEffectsLoaded) return; context.CaptureTouch(); InputEvent inputEvent = (InputEvent)context.data; Vector2 mousePos = this.viewCom.GlobalToLocal(new Vector2(inputEvent.x, inputEvent.y)); CheckNearbyPos(mousePos); } private void OnClickUIMove(EventContext context) { if (!_allEffectsLoaded) return; InputEvent inputEvent = (InputEvent)context.data; Vector2 mousePos = this.viewCom.GlobalToLocal(new Vector2(inputEvent.x, inputEvent.y)); CheckNearbyPos(mousePos); if (comStars.Count == 0) //所有星星都点亮了主动结束 { this.OnClickUIEnd(); } } //检测鼠标附近的星星 private void CheckNearbyPos(Vector2 mousePos) { for (int i = comStars.Count - 1; i >= 0; i--) { Vector2 comStarPos = (Vector2)comStars[i].data; if (IsSamePos(mousePos, comStarPos)) { if (curComStar != null) { SetCurComStarTransfrom(comStarPos); } UI_ComStar comStar = UI_ComStar.Proxy(comStars[i]); comStar.target.GetChildAt(2).asCom.visible = true; string resPath = _isLuckyBox ? "LINE_Bule" : "LINE"; EffectUIPool.CreateEffectUI(comStar.m_comLine.m_holder, "ui_LuckyBox", resPath, 120, onComplete: (effect) => { if (effect != null) { effObj.Add(effect); } }); UI_ComStar.ProxyEnd(); curComStar = comStars[i]; lastPos = Vector2.right; clickComStars.Add(comStars[i]); comStars.RemoveAt(i); } else { if (curComStar != null) { Vector2 curPos = mousePos - (Vector2)curComStar.data; SetCurComStarTransfrom(mousePos); lastPos = curPos; } } } } private void SetCurComStarTransfrom(Vector2 targetPos) { Vector2 curPos = targetPos - (Vector2)curComStar.data; float angle = Vector3.Angle(lastPos, curPos); //求出两向量之间的夹角 Vector3 normal = Vector3.Cross(lastPos, curPos); //叉乘求出法线向量 angle *= Mathf.Sign(Vector3.Dot(normal, Vector3.forward)); //Mathf.Sign()求符号,Vector3.Dot()求方向,求法线向量与物体上方向向量点乘,结果为1或-1,修正旋转方向 UI_ComStar comStar = UI_ComStar.Proxy(curComStar); comStar.m_comLine.target.rotation += angle; comStar.m_comLine.target.width = Vector2.Distance(targetPos, (Vector2)curComStar.data); UI_ComStar.ProxyEnd(); } private void OnClickUIEnd() { if (!_allEffectsLoaded || clickComStars.Count <= 0) return; UI_ComStar comStar = UI_ComStar.Proxy(clickComStars[clickComStars.Count - 1]); comStar.m_comLine.target.visible = false; UI_ComStar.ProxyEnd(); if (showGuide && clickComStars.Count < 2) { ResetStartView(); } else { RemoveListener(); Timers.inst.Add(0.5f, 1, SetEndEffect); } } private void SetEndEffect(object param) { _ui.m_t0.Play(() => { ClickUIEnd(null); }); TryCompleteGuide(); } private void ClickUIEnd(object param) { if (curComStar != null) { RemoveListener(); this.Hide(); //LuckyBoxVideoView.Instance.Show(_rewardList); ViewManager.Show(_rewardList); } } private bool IsSamePos(Vector2 mousePos, Vector2 comStarPos) { return (mousePos.x < comStarPos.x + checkDistance) && (mousePos.x > comStarPos.x - checkDistance) && (mousePos.y < comStarPos.y + checkDistance) && (mousePos.y > comStarPos.y - checkDistance); } private void RemoveListener() { _ui.target.onTouchBegin.Remove(OnClickUIBegin); _ui.target.onTouchMove.Remove(OnClickUIMove); _ui.target.onTouchEnd.Remove(OnClickUIEnd); } private void OnClickBtnBack() { this.Hide(); RemoveListener(); ViewManager.Show(); } private void CheckGuide(object param) { if (!_allEffectsLoaded) return; if (GuideDataManager.IsGuideFinish(ConstGuideId.LUCKY_BOX_LINE) <= 0) { UpdateToCheckGuide(null); } else { Timers.inst.Remove(CheckGuide); } } protected override void UpdateToCheckGuide(object param) { if (!_allEffectsLoaded || !ViewManager.CheckIsTopView(this.viewCom)) return; GuideController.TryGuide(null, ConstGuideId.LUCKY_BOX_LINE, 1, "点击将星连接在一起。", -1, true, (int)(this.viewCom.height - 200), true); TryCompleteGuide(); } protected override void TryCompleteGuide() { if (!_allEffectsLoaded) return; if (clickComStars.Count >= 2) { GuideController.TryCompleteGuideIndex(ConstGuideId.LUCKY_BOX_LINE, 1); GuideController.TryCompleteGuide(ConstGuideId.LUCKY_BOX_LINE, 1); } else { GuideDataManager.SetGuideIndexState(GuideDataManager.currentGuideId, GuideDataManager.currentGuideIdIndex, 0); GuideDataManager.currentGuideIdIndex = 3; } } } }