using System.Collections; using System.Collections.Generic; using UnityEngine; using UI.ActivityHuaRongDao; using FairyGUI; using System.Threading.Tasks; using System.Threading; using System; namespace GFGGame { public class ActivityHuaRongDaoView : BaseWindow { private UI_ActivityHuaRongDaoUI _ui; /// /// 格子类 /// public class Grid { public Vector2 pos; // UI坐标 public int num; } /// /// 格子的行列信息 /// public class GridInfo { public int col; public int row; public int num; } private int _activityID; // 行/列 格子数 private readonly int _gridNum = 3; private bool _gameStart; private Grid[,] _gridArr; private List _items; private HuarongRoadGame _cfg; // 异步函数的取消控制 private CancellationTokenSource _cancellationTokenSource; // 胜利后自动补齐的格子 private GObject _blankItem; public override void Dispose() { if (_ui != null) { _ui.Dispose(); _ui = null; } base.Dispose(); } protected override void OnInit() { base.OnInit(); packageName = UI_ActivityHuaRongDaoUI.PACKAGE_NAME; _ui = UI_ActivityHuaRongDaoUI.Create(); viewCom = _ui.target; isfullScreen = true; _ui.m_loaBg.url = ResPathUtil.GetBgImgPath("gf_pjxq_bj"); isReturnView = true; _ui.m_item.target.visible = false; _ui.m_btnBack.onClick.Add(OnBtnBackClick); _ui.m_state.onChanged.Add(OnChangeLookOriginState); _ui.m_btnRefresh.onClick.Add(OnClickBtnRefresh); InitGridInfo(); CreateItems(); // 初始化空白处格子实体 if (_blankItem == null) { _blankItem = UIPackage.CreateObject("ActivityHuaRongDao", "item"); _ui.target.AddChild(_blankItem); } _ui.m_maskTouch.onTouchBegin.Add(TouchBegin); _ui.m_maskTouch.onTouchEnd.Add(TouchEnd); } protected override void OnShown() { base.OnShown(); object[] arr = viewData as object[]; _cfg = (HuarongRoadGame)arr[0]; _activityID = (int)arr[1]; RefreshData(); _cancellationTokenSource = new CancellationTokenSource(); Task task = StartAnimation(_cancellationTokenSource.Token); } protected override void OnHide() { base.OnHide(); StopMyAsyncFunction(); } /// /// 初始化所有格子的信息 /// private void InitGridInfo() { _gridArr = new Grid[_gridNum, _gridNum]; _items = new List(); for (int i = 0; i < _gridNum; i++) { for (int j = 0; j < _gridNum; j++) { _gridArr[i, j] = new Grid(); } } } private void SetGridInfo(List numList) { //List numList = GetRandomArr(1, 8); Vector2 originPos = _ui.m_item.target.position; for (int i = 0; i < _gridNum; i++) { for (int j = 0; j < _gridNum; j++) { _gridArr[i, j].num = numList[i * _gridNum + j]; _gridArr[i, j].pos = originPos + new Vector2(j * _ui.m_item.target.width, i * _ui.m_item.target.height); } } } /// /// 检测是否是连续数组 /// /// /// private bool CheckListCorrect(List numList) { for (int i = 0; i < numList.Count - 1; i++) { if (numList[i + 1] != numList[i] + 1) { return false; } } return true; } private List CreateIncreaseArr() { List list = new List(); list.Add(0); for (int i = 1; i <= 8; i++) { list.Add(i); } return list; } /// /// 根据配置步数打乱数组 /// /// /// private List GetArrByConfigStep(int configStep) { List list = CreateIncreaseArr(); int num = 0; Vector2 zeroPos = new Vector2(0, 0); Vector2[] dirArr = { new Vector2(-1, 0), new Vector2(1, 0), new Vector2(0, -1), new Vector2(0, 1) }; Vector2 lastPos = zeroPos; while (num < configStep) { int n = UnityEngine.Random.Range(0, 4); Vector2 tempPos = zeroPos + dirArr[n]; if (tempPos != lastPos && tempPos.x >= 0 && tempPos.y >= 0 && tempPos.x < _gridNum && tempPos.y < _gridNum) { list[(int)zeroPos.x * _gridNum + (int)zeroPos.y] = list[(int)tempPos.x * _gridNum + (int)tempPos.y]; list[(int)tempPos.x * _gridNum + (int)tempPos.y] = 0; lastPos = zeroPos; zeroPos = tempPos; ++num; } } return list; } private void InitItems() { int itemIndex = 0; for (int i = 0; i < _gridNum; i++) { for (int j = 0; j < _gridNum; j++) { // 空格不用放item if (_gridArr[i, j].num == 0) { continue; } _items[itemIndex].position = _gridArr[i, j].pos; UI_item item = UI_item.Proxy(_items[itemIndex]); item.m_index.text = _gridArr[i, j].num.ToString(); int groupID = _cfg.resArr[0]; item.m_icon.url = GetPicRes(HuarongRoadCfgArray.Instance.GetCfgsByid(groupID)[_gridArr[i, j].num].resName); _items[itemIndex].data = _gridArr[i, j].num; UI_item.ProxyEnd(); ++itemIndex; } } } /// /// 创建可移动的实体 /// private void CreateItems() { for (int i = 1; i <= _gridNum * _gridNum - 1; i++) { GObject gObject = UIPackage.CreateObject("ActivityHuaRongDao", "item"); gObject.name = "item" + i; _ui.m_items.target.AddChild(gObject); _items.Add(gObject); } } private void ControlMenuItemVisual(bool show = true) { _ui.m_btnBack.visible = show; _ui.m_btnLookPic.visible = show; _ui.m_btnHidePic.visible = show; _ui.m_btnRefresh.visible = show; } private Vector2 inputPos = new Vector2(); private void TouchBegin(EventContext context) { inputPos.x = context.inputEvent.x; inputPos.y = context.inputEvent.y; } private void TouchEnd(EventContext context) { GridInfo numGrid = null; GridInfo nullGrid = new GridInfo(); // 找到空格子 for (int i = 0; i < _gridNum; i++) { for (int j = 0; j < _gridNum; j++) { if (_gridArr[i, j].num == 0) { nullGrid.row = i; nullGrid.col = j; break; } } } // 左 if ((context.inputEvent.x - inputPos.x) < 0 && Mathf.Abs(context.inputEvent.x - inputPos.x) > Mathf.Abs(context.inputEvent.y - inputPos.y)) { numGrid = CheckHaveNumGrid(nullGrid.row, nullGrid.col + 1); } // 右 if ((context.inputEvent.x - inputPos.x) > 0 && Mathf.Abs(context.inputEvent.x - inputPos.x) > Mathf.Abs(context.inputEvent.y - inputPos.y)) { numGrid = CheckHaveNumGrid(nullGrid.row, nullGrid.col - 1); } // 上 if ((context.inputEvent.y - inputPos.y) < 0 && Mathf.Abs(context.inputEvent.y - inputPos.y) > Mathf.Abs(context.inputEvent.x - inputPos.x)) { numGrid = CheckHaveNumGrid(nullGrid.row + 1, nullGrid.col); } // 下 if ((context.inputEvent.y - inputPos.y) > 0 && Mathf.Abs(context.inputEvent.y - inputPos.y) > Mathf.Abs(context.inputEvent.x - inputPos.x)) { numGrid = CheckHaveNumGrid(nullGrid.row - 1, nullGrid.col); } if (numGrid != null) { int num = numGrid.num; Grid grid = UpdateGridInfo(numGrid, nullGrid); MoveItem(grid, num); } } private void MoveItem(Grid newGrid, int changeNum) { for (int i = 0; i < _items.Count; i++) { GObject obj = _items[i]; int num = (int)obj.data; if (num == changeNum) { _ui.m_maskGlobal.visible = true; obj.TweenMove(newGrid.pos, 0.1f).OnComplete(() => { _ui.m_maskGlobal.visible = false; if (CheckWin()) { ControlMenuItemVisual(false); Win(_cancellationTokenSource.Token); } }); return; } } } /// /// 查看空白格附近是否存在数字格 /// /// /// /// private GridInfo CheckHaveNumGrid(int indexX, int indexY) { if (indexX >= 0 && indexX < _gridNum) { if (indexY >= 0 && indexY < _gridNum) { GridInfo grid = new GridInfo(); grid.row = indexX; grid.col = indexY; grid.num = _gridArr[indexX, indexY].num; return grid; } } return null; } /// /// 交换数字格和空白格的数据 /// /// /// /// private Grid UpdateGridInfo(GridInfo numGrid, GridInfo nullGrid) { _gridArr[numGrid.row, numGrid.col].num = 0; _gridArr[nullGrid.row, nullGrid.col].num = numGrid.num; return _gridArr[nullGrid.row, nullGrid.col]; } private bool CheckWin() { int num = 0; for (int i = 0; i < _gridNum; i++) { for (int j = 0; j < _gridNum; j++) { if (i == 0 && j == 0) { num = _gridArr[i, j].num; if (num != 0) { return false; } } else { // 不连续 没有胜利 if (_gridArr[i, j].num != num + 1) { return false; } // 继续检测 else { ++num; // 胜利 if (num == _gridNum * _gridNum - 1) { return true; } } } } } return false; } private async Task Win(CancellationToken cancellationToken) { // 请求游戏结束协议 await MiniGameProxy.ReqMiniGameEnd(_cfg.id, _cfg.type, 0, true, _activityID, false); // 成功动画 _ui.m_showMask.Play(async () => { _ui.m_hideMask.Play(); _gameStart = true; await Task.Delay(400, cancellationToken); // 刷新华容道入口界面UI EventAgent.DispatchEvent(ConstMessage.ACTIVITY_HUARONGDAO_UPDATE); // 弹出成功界面 ViewManager.Show(_cfg); }); await Task.Delay(200, cancellationToken); _blankItem.visible = true; _blankItem.position = _gridArr[0, 0].pos; UI_item item = UI_item.Proxy(_blankItem); int groupID = _cfg.resArr[0]; item.m_icon.url = GetPicRes(HuarongRoadCfgArray.Instance.GetCfgsByid(groupID)[0].resName); UI_item.ProxyEnd(); } private void OnBtnBackClick() { if (_gameStart) { AlertUI.Show("退出游戏不保存进度,不扣除任何次数和道具,是否退出?") .SetLeftButton(true, "返回游戏") .SetRightButton(true, "仍要退出", (obj) => { Hide(); }); } else { Hide(); } } private async Task StartAnimation(CancellationToken cancellationToken) { try { _ui.m_hideMask.Play(); _ui.m_maskGlobal.visible = true; List numList = CreateIncreaseArr(); SetGridInfo(numList); InitItems(); CreateOriginPic(); // 隐藏所有 UI_item item; for (int i = 0; i < _items.Count; i++) { item = UI_item.Proxy(_items[i]); item.m_hide.Play(); } // 入场 for (int i = 0; i < _items.Count; i++) { item = UI_item.Proxy(_items[i]); item.m_show.Play(); await Task.Delay(100, cancellationToken); } UI_item.ProxyEnd(); // 出现白色遮罩,刷新数组 await Task.Delay(900, cancellationToken); _ui.m_showMask.Play(() => { _ui.m_maskGlobal.visible = false; _ui.m_hideMask.Play(); _gameStart = true; }); await Task.Delay(200, cancellationToken); numList = GetArrByConfigStep(_cfg.step); while (CheckListCorrect(numList)) { numList = GetArrByConfigStep(_cfg.step); } SetGridInfo(numList); InitItems(); } catch (TaskCanceledException) { //Debug.Log("异步函数被停止"); } } private void RefreshData() { _blankItem.visible = false; _gameStart = false; _ui.m_state.selectedIndex = 0; ControlMenuItemVisual(); } // 取消异步函数 public void StopMyAsyncFunction() { if (_cancellationTokenSource != null) { _cancellationTokenSource.Cancel(); _cancellationTokenSource.Dispose(); _cancellationTokenSource = null; } } /// /// 创建原图 /// private void CreateOriginPic() { List items = new List(); for (int i = 1; i <= _gridNum * _gridNum; i++) { GObject gObject = UIPackage.CreateObject("ActivityHuaRongDao", "item"); _ui.m_itemsOrigin.target.AddChild(gObject); items.Add(gObject); } int itemIndex = 0; for (int i = 0; i < _gridNum; i++) { for (int j = 0; j < _gridNum; j++) { items[itemIndex].position = _gridArr[i, j].pos; UI_item item = UI_item.Proxy(items[itemIndex]); item.m_index.text = _gridArr[i, j].num.ToString(); //item.m_icon.url = string.Format("ui://ActivityHuaRongDao/hrd_1-{0}", _gridArr[i, j].num + 1); int groupID = _cfg.resArr[0]; item.m_icon.url = GetPicRes(HuarongRoadCfgArray.Instance.GetCfgsByid(groupID)[_gridArr[i, j].num].resName); UI_item.ProxyEnd(); ++itemIndex; } } } private void OnChangeLookOriginState() { bool look = (_ui.m_state.selectedIndex == 1); _ui.m_maskTouch.touchable = !look; _ui.m_items.target.visible = !look; _ui.m_itemsOrigin.target.visible = look; } private void OnClickBtnRefresh() { _ui.m_state.selectedIndex = 0; StartAnimation(_cancellationTokenSource.Token); } private string GetPicRes(string res) { return ResPathUtil.GetHUARONGDAOPicPath(res); } } }