180 lines
5.4 KiB
C#
180 lines
5.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using AibisDream.Framework;
|
|
using AibisDream.Kit;
|
|
using UnityEngine;
|
|
using Random = UnityEngine.Random;
|
|
|
|
namespace AibisDream.FixSystem
|
|
{
|
|
public class WhackMoleHandler
|
|
{
|
|
private static readonly WhackMoleSystem WhackMoleSystem = FixSystemCenter.SystemDic.Get<WhackMoleSystem>();
|
|
|
|
private readonly WhackMoleData _data;
|
|
|
|
private IActionController _controller;
|
|
|
|
#region 功能参数
|
|
|
|
private int _batchIdx;
|
|
private readonly Dictionary<string, MoleModule> _moleModules;
|
|
private readonly List<WhackMoleBatchHandler> _batchHandlers;
|
|
|
|
public WhackMoleRes res;
|
|
public event Action OnGameEnd;
|
|
public event Action OnBatchEnd;
|
|
|
|
#endregion
|
|
|
|
public WhackMoleHandler(WhackMoleData data)
|
|
{
|
|
res = new WhackMoleRes();
|
|
_data = data;
|
|
_batchIdx = 0;
|
|
_moleModules = WhackMoleSystem.MoleModules;
|
|
// 生成batch序列并链接
|
|
_batchHandlers = CreateBatchHandler(data);
|
|
// 统计一些基本数据
|
|
CalcBaseData();
|
|
}
|
|
|
|
private void CalcBaseData()
|
|
{
|
|
res.totalMoleBatch = _data.totalBatchNum;
|
|
for (int i = 0; i < _data.totalBatchNum; i++)
|
|
{
|
|
res.totalMoleNum += _data.GetBatch(i).moleNum;
|
|
}
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
foreach (var mole in _moleModules.Values)
|
|
{
|
|
mole.isInMoleGame = true;
|
|
}
|
|
|
|
WhackMoleSystem.StartAllFlicker();
|
|
_controller = ActionKit.Coroutine(_batchHandlers[_batchIdx].StartBatch).StartGlobal();
|
|
}
|
|
|
|
private List<WhackMoleBatchHandler> CreateBatchHandler(WhackMoleData data)
|
|
{
|
|
List<WhackMoleBatchHandler> handlers = new();
|
|
for (int i = 0; i < data.totalBatchNum; i++)
|
|
{
|
|
var curHandler = new WhackMoleBatchHandler(_moleModules.Values, data, i);
|
|
curHandler.OnBatchEnd += HandleBatch;
|
|
handlers.Add(curHandler);
|
|
}
|
|
|
|
return handlers;
|
|
}
|
|
|
|
private void HandleBatch(int hitMoleNum)
|
|
{
|
|
_batchIdx++;
|
|
res.hitMoleNum += hitMoleNum;
|
|
res.passBatchNum++;
|
|
if (_batchIdx >= _data.totalBatchNum && _data.totalBatchNum > 0)
|
|
{
|
|
OnGameEnd?.Invoke();
|
|
return;
|
|
}
|
|
|
|
OnBatchEnd?.Invoke();
|
|
// 继续下一个批次,如果有中间状态就在这里处理
|
|
_controller = ActionKit.Sequence().Delay(_data.GetBatchGap()).Coroutine(_batchHandlers[_batchIdx].StartBatch)
|
|
.StartGlobal();
|
|
}
|
|
|
|
public void EndWhackGame()
|
|
{
|
|
WhackMoleSystem.StopAllFlicker();
|
|
_controller.Reset();
|
|
_controller = null;
|
|
}
|
|
}
|
|
|
|
public class WhackMoleBatchHandler
|
|
{
|
|
private readonly WhackMoleData _globalData;
|
|
|
|
private readonly ISelector<MoleModule> _moleSelector;
|
|
private readonly List<float> _lightGaps = new();
|
|
private readonly List<MoleModule> _lightingMoles = new();
|
|
|
|
private bool _isBatchEnd;
|
|
private int _hitMoleNum;
|
|
|
|
public event Action<int> OnBatchEnd;
|
|
|
|
public WhackMoleBatchHandler(IEnumerable<MoleModule> molesModules, WhackMoleData data, int index)
|
|
{
|
|
_globalData = data;
|
|
var batchData = data.GetBatch(index);
|
|
// 创建选择器
|
|
_moleSelector = new LimitedSelector<MoleModule>(molesModules);
|
|
// 设置亮起时间间隔
|
|
for (var i = 0; i < batchData.moleNum; i++)
|
|
{
|
|
var gap = Random.Range(batchData.durationRange.x, batchData.durationRange.y);
|
|
_lightGaps.Add(gap);
|
|
}
|
|
|
|
_lightGaps.Sort();
|
|
}
|
|
|
|
public IEnumerator StartBatch()
|
|
{
|
|
// 利用协程记时
|
|
float batchTime = 0f;
|
|
while (!_isBatchEnd)
|
|
{
|
|
OnUpdate(batchTime);
|
|
batchTime += Time.deltaTime;
|
|
yield return null;
|
|
}
|
|
|
|
OnBatchEnd?.Invoke(_hitMoleNum);
|
|
OnBatchEnd = null;
|
|
}
|
|
|
|
private void OnUpdate(float batchTime)
|
|
{
|
|
// 点亮一些模块,其他的继续闪烁
|
|
while (_lightGaps.Count > 0 && _lightGaps[0] <= batchTime)
|
|
{
|
|
var lightOnMole = _moleSelector.Select();
|
|
lightOnMole.LightOn(_globalData.moleExistTime);
|
|
lightOnMole.OnLightMoleEnd += OnLightMoleEnd;
|
|
// 最后同步其他容器
|
|
_lightGaps.RemoveAt(0);
|
|
_lightingMoles.Add(lightOnMole);
|
|
}
|
|
}
|
|
|
|
private void OnLightMoleEnd(MoleModule mole, bool isPlugin)
|
|
{
|
|
// 从亮起列表中移除
|
|
_lightingMoles.Remove(mole);
|
|
if (isPlugin) _hitMoleNum++;
|
|
// 当所有模块都熄灭的时候,游戏结束
|
|
if (_lightingMoles.Count <= 0 && _lightGaps.Count <= 0)
|
|
{
|
|
_isBatchEnd = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public struct WhackMoleRes
|
|
{
|
|
public int totalMoleBatch;
|
|
public int failBatchNum;
|
|
public int passBatchNum;
|
|
public int totalMoleNum;
|
|
public int hitMoleNum;
|
|
}
|
|
} |