//捲軸旋轉(協程) //[param] spinModeList = 旋轉模式 , linkTime = 牽動等待時間 , isTest = 測試與否 private IEnumerator Cor_BeginSpin(List <SpinMode> spinModeList, float linkTime, bool isTest) { if (!isTest) //測試的狀況跳過 { if (spinModeList.Count != scrollCount && spinModeList.Count != 1) { throw new System.Exception("[ERROR]輸入的旋轉模式設定有誤!"); } //旋轉前準備 if (MoneyManager.Instance.nowMoney < BetController.Instance.nowBetMoney) { AudioManagerScript.Instance.PlayAudioClip("SE取消"); Coroutine moneyNotEnough = StartCoroutine(MoneyManager.Instance.Cor_MoneyNotEnough()); //錢不夠提示 yield return(moneyNotEnough); GameController.Instance.SetOperationState(true); //操作狀態設為允許 yield break; } leverAnim.Play("lever_spin", 0, 0); //撥放動畫 AudioManagerScript.Instance.PlayAudioClip("SE拉桿"); StartCoroutine(MoneyManager.Instance.Cor_SetMoney(MoneyManager.Instance.nowMoney - BetController.Instance.nowBetMoney, false)); //扣除賭金 StopAllElementAnimation(); //停止所有圖格動畫 } //預估旋轉結果 List <List <ElementImageType> > spinResult = BuildResultScroll(); //旋轉結果 List <SensorInfo> blocksResult = new List <SensorInfo>(); //將旋轉結果的圖格列表形式轉換成捲軸偵測器形式 for (int i = 0; i < posSensorArray.Count; i++) { SensorInfo _info = new SensorInfo(); //建立偵測器 _info.coordinate = posSensorArray[i].coordinate; _info.elementType = spinResult[(int)posSensorArray[i].coordinate.x][i % visibleElementCount]; blocksResult.Add(_info); //加入列表 } //Debug.Log("BlocksResult Test -------------"); //for (int i = 0; i < blocksResult.Count; i++) //{ // Debug.Log(string.Format("({0}, {1}) = {2}", blocksResult[i].coordinate.x, blocksResult[i].coordinate.y, blocksResult[i].elementType)); //} List <PrizeLineInfo> prizeLineDistribution = new List <PrizeLineInfo>(); //中獎資訊列表 int prizeTotal = 0; //總獎金 List <LineDrawer> _workingLineList = LotteryLineManager.Instance.GetWorkingLines(); //取得有效線段 List <Vector2> _drawedPosList = new List <Vector2>(); //中獎圖格座標列表 for (int i = 0; i < _workingLineList.Count; i++) //遍歷所有線段是否中獎 { PrizeLineInfo _pInfo = _workingLineList[i].RewardJudgement(blocksResult, PrizeTableManager.Instance.prizeTable.m_data); //判斷該線段中獎資訊, 並將其儲存 _drawedPosList.AddRange(_pInfo.drawedPosList); //加入中獎圖格座標列表 if (_pInfo.sumPrize > 0) //有中獎時 { prizeTotal += _pInfo.sumPrize; //總獎金累計 } prizeLineDistribution.Add(_pInfo); } //Debug.Log("總計中獎獎金 = " + prizeTotal); //for (int i = 0; i < prizeLineDistribution.Count; i++) //{ // Debug.Log(string.Format("等級 {0} 合計中獎獎金 = {1}", prizeLineDistribution[i].lineLevel, prizeLineDistribution[i].sumPrize)); //} #if UNITY_EDITOR if (isTest) //測試的狀況 { TestPanelManager.Instance.FeedbackSimulateResult(prizeLineDistribution); //儲存模擬結果 yield break; } #endif _drawedPosList = ListExtensibleScript <Vector2> .RepetitionFilter(_drawedPosList); //篩掉列表中的重複元素 //捲軸旋轉狀態 bool[] _stateArr = new bool[scrollCount]; for (int i = 0; i < _stateArr.Length; i++) { _stateArr[i] = false; } ScrollBehavior.s_scrollRollingStates = _stateArr; //初始化旋轉狀態 GameController.Instance.leverCanSnap = true; //可手動中斷捲軸 //捲軸旋轉動畫 //float _delayTime = 0; //捲軸煞停延遲時間 for (int i = 0; i < scrollCount; i++) //逐個捲軸執行旋轉動作 { int _index = 0; if (spinModeList.Count > 1) { _index = i; //若為統一旋轉模式則List索引固定為0, 若個別指定則索引值隨迴圈變動 } bool _dir = spinModeList[_index].direction; //旋轉方向 float _speed = spinModeList[_index].elementSpeed; //旋轉速度 float _time = spinModeList[_index].spinTime; //旋轉時間 float _sliderSpeed = ((_dir ? _speed : -_speed) / (scrollGroup[i].elementChain.Count - visibleElementCount)) * Time.fixedDeltaTime; //換算速度(圖格速度 ➡ 拉條速度) StartCoroutine(scrollGroup[i].Cor_ScrollSpin(_sliderSpeed, _time, spinResult[i], scrollStartingCurve)); if (i == scrollCount - 1) //最後一個捲軸動作時, 紀錄煞停延遲時間 { //_delayTime = ( (float)( visibleElementCount + 1 ) / ( scrollGroup[i].elementChain.Count - visibleElementCount ) ) / ( Mathf.Abs(_sliderSpeed) * ( 1f / Time.fixedDeltaTime ) ); //Debug.Log("SliderSpeed(/s) = " + ( ( Mathf.Abs(_sliderSpeed) * ( 1f / Time.fixedDeltaTime ) ) )); //Debug.Log("Vc = " + visibleElementCount); //Debug.Log("t - Vc = " + ( scrollGroup[i].elementChain.Count - visibleElementCount )); //Debug.Log("Vc / (t - Vc) = " + ( (float)visibleElementCount / ( scrollGroup[i].elementChain.Count - visibleElementCount ) )); //Debug.Log("DelayTime = " + _delayTime); break; } yield return(new WaitForSeconds(linkTime)); } for (int i = 0; i < scrollCount; i++) //等待所有捲軸旋轉完畢 { yield return(new WaitWhile(() => scrollGroup[i].isRolling)); } yield return(new WaitForSeconds(brakeBufferTime)); GameController.Instance.leverCanSnap = false; //禁止手動中斷捲軸 PositionSensorEventArgs eventArgs = new PositionSensorEventArgs(visibleElementCount * scrollCount); if (SpinJudged != null) { SpinJudged.Invoke(this, eventArgs); } yield return(new WaitUntil(() => (eventArgs.overNumber == 0))); //等待所有圖格位置偵測器觸發結束 //for (int i = 0; i < eventArgs.SpinResultList.Count; i++) //{ // Debug.Log(string.Format("[{0}] ({1}, {2}) : {3}", i, eventArgs.SpinResultList[i].coordinate.x, eventArgs.SpinResultList[i].coordinate.y, eventArgs.SpinResultList[i].elementType)); //} //旋轉結果 previousSpinResult = eventArgs.SpinResultList; //記錄拉霸結果 PlayElementAnimation(ElementAnimationType.中獎, _drawedPosList, true); //中獎圖格特效 yield return(StartCoroutine(MoneyManager.Instance.Cor_GetPrize(prizeTotal, prizeLineDistribution))); //獲得獎金 GameController.Instance.SetOperationState(true); //操作狀態設為允許 }
//中獎判定 //[output] List<PrizeInfo> = 中獎資訊列表 //[param] sensorInfo = 位置偵測器資訊(各座標上對應的圖格類型) , prizeTable = 支付表設定 public PrizeLineInfo RewardJudgement(List <SensorInfo> sensorInfo, List <PrizeCombination> prizeTableSource) { PrizeLineInfo _resultList = new PrizeLineInfo(); if (level == 0 || !isWorking) { return(null); //中獎線等級為0 或 線段未啟用 則不計算中獎 } List <ElementImageType> _imageLine = new List <ElementImageType>(); //線上的圖格類型 for (int i = 0; i < coordinates.Count; i++) //遍歷線上所有點的座標 { for (int j = 0; j < sensorInfo.Count; j++) //遍歷所有圖格資訊 { if (sensorInfo[j].coordinate == coordinates[i]) //取得指定位置上的圖格 { _imageLine.Add(sensorInfo[j].elementType); continue; } } } if (_imageLine.Count != coordinates.Count) { throw new System.Exception("[ERROR]線段各點座標與圖格位置座標不完全一致"); } //for (int i = 0; i < _imageLine.Count; i++) //{ // Debug.Log(string.Format("({0}, {1}) : {2}", coordinates[i].x, coordinates[i].y, _imageLine[i])); //} List <PrizeCombination> prizeTable = new List <PrizeCombination>(); prizeTable.AddRange(prizeTableSource); //排序支付表組合(組合長度多排到少) prizeTable.Sort((PrizeCombination x, PrizeCombination y) => { if (x.combinations.Count > y.combinations.Count) { return(-1); } if (x.combinations.Count < y.combinations.Count) { return(1); } return(0); }); List <PrizeCombination> _drawedCombs = new List <PrizeCombination>(); //判定成功(有中獎)的支付表組合 //Debug.Log("[ 線段 " + this.gameObject.name + " 開始判斷]"); for (int i = 0; i < prizeTable.Count; i++) //逐一檢查支付表所有組合 { bool _isMatch = false; //任一項有符合(淺層判斷) bool _matchPass = false; //跳過淺層判斷 for (int j = 0; j < _imageLine.Count; j++) //若線上有任一狂野符號, 直接進入深層判斷(中獎判斷) { if (ScrollManager.Instance.Dict_wildSymbol[_imageLine[j]]) { _matchPass = true; _isMatch = true; break; } } if (!_matchPass) //沒有狂野符號時, 檢測線上所有圖格是否有任意一項與支付表組合圖格相符(淺層判斷) { if (prizeTable[i].PureTest()) //若組合為純元素構成(只輸入一個圖格類型, 節省遍歷時間) { _isMatch = ElementListMatchTest(_imageLine, new List <ElementImageType>() { prizeTable[i].combinations[0] }); } else //若組合為混和元素構成 { _isMatch = ElementListMatchTest(_imageLine, prizeTable[i].combinations); } } if (_isMatch) //若有任意一項圖格相符時, 深入判斷中獎與否 { int _prize = 0; //中獎獎金 for (int j = 0; j < _drawedCombs.Count; j++) //判斷中獎的組合是否包含此組合 { _prize += prizeTable[i].Comparison(_drawedCombs[j].combinations).prizeMoney; } if (_prize == 0) //已經中獎的組合如果有包含此組合, 則跳過此組合的判斷, 避免重複中獎 { CombinationPrizeInfo _cbInfo = prizeTable[i].Comparison(_imageLine); //取得中獎資訊 if (_cbInfo.prizeMoney > 0) //若獎金大於0(有中獎) { _drawedCombs.Add(prizeTable[i]); //加入判定成功組合列表 for (int j = 0; j < _cbInfo.matchedPosList.Count; j++) //對照索引值紀錄相應的座標 { _resultList.drawedPosList.Add(coordinates[_cbInfo.matchedPosList[j]]); } _resultList.AddCombinationItem(_cbInfo); } } } } _resultList.lineLevel = level; //設定中獎線等級 _resultList.drawedPosList = ListExtensibleScript <Vector2> .RepetitionFilter(_resultList.drawedPosList); //篩掉列表中的重複元素 return(_resultList); }