using System; using System.Collections; using UnityEngine; using UnityEngine.Events; namespace AibisDream.FixSystem { public class WhackMoleHandler { private readonly MonoBehaviour _mono; private AbsWhackMoleNodeHandler _nodeHandler; public event Action OnGameEnd; private WhackMoleHandler(MonoBehaviour mono) { _mono = mono; } public void OnPlugIn(string moduleName) { _nodeHandler.OnPlugIn(moduleName); } private void Handle() { _nodeHandler.onHandleEnd.AddListener(OnHandleEnd); _mono.StartCoroutine(_nodeHandler.Handle()); } private void OnHandleEnd(bool isSuccess) { if (isSuccess) { // TODO 进入下一关 _nodeHandler.onHandleEnd.RemoveAllListeners(); if (_nodeHandler.nextHandler != null) { _nodeHandler = _nodeHandler.nextHandler; Handle(); } else { OnGameEnd?.Invoke(); } } else { // TODO 进入失败结局 OnGameEnd?.Invoke(); } } public static WhackMoleHandler Create(WhackMoleData data, MonoBehaviour mono) { var res = new WhackMoleHandler(mono); AbsWhackMoleNodeHandler lastHandler = null; foreach (var node in data.nodes) { var handler = CreateNodeHandler(node); res._nodeHandler ??= handler; if (lastHandler != null) { lastHandler.nextHandler = handler; } lastHandler = handler; } return res; } private static AbsWhackMoleNodeHandler CreateNodeHandler(WhackMoleNode node) { AbsWhackMoleNodeHandler handler = node.command switch { WhackMoleCommand.SingleModuleLightOn => new SingleModuleLightOnHandler(), WhackMoleCommand.MultipleModuleLightOn => new MultipleModuleLightOnHandler(), WhackMoleCommand.SingleModuleColorOn => new SingleModuleColorOnHandler(), WhackMoleCommand.MultipleModuleColorOn => new MultipleModuleColorOnHandler(), _ => throw new ArgumentOutOfRangeException() }; handler.Init(node); return handler; } } public abstract class AbsWhackMoleNodeHandler { protected WhackMoleNode node; public AbsWhackMoleNodeHandler nextHandler; public readonly UnityEvent onHandleEnd = new(); public virtual void Init(WhackMoleNode nodeData) { node = nodeData; } public IEnumerator Handle() { yield return BeforePlug(); yield return WaitPlug(); yield return AfterPlug(); } protected virtual IEnumerator BeforePlug() { // TODO 全部模块闪烁3S yield return new WaitForSeconds(node.flickerTime); } protected abstract IEnumerator WaitPlug(); protected abstract IEnumerator AfterPlug(); public abstract void OnPlugIn(string moduleName); } public class SingleModuleLightOnHandler : AbsWhackMoleNodeHandler { private bool _isPlugIn; public override void Init(WhackMoleNode nodeData) { base.Init(nodeData); // 处理Random if (nodeData.moduleName.ToLowerInvariant() == "random") { // TODO 随机选择一个模块 node.moduleName = ""; } } protected override IEnumerator WaitPlug() { // TODO 高亮某个模块 // FixSystemCenter.SystemDic.Get().Highlight(node.moduleName); // 进入循环等待插入事件,2s内未插入则进入失败结局 var waitTime = 0f; while (!_isPlugIn && waitTime < node.lightOnTime) { waitTime += Time.deltaTime; yield return null; } } protected override IEnumerator AfterPlug() { if (_isPlugIn) { // TODO 正常插入,触发效果并进入下一个关卡 yield return null; onHandleEnd?.Invoke(true); } else { // TODO 超时,触发失败结局 onHandleEnd?.Invoke(false); } } public override void OnPlugIn(string moduleName) { if (moduleName == node.moduleName) { _isPlugIn = true; } } } public class MultipleModuleLightOnHandler : AbsWhackMoleNodeHandler { protected override IEnumerator WaitPlug() { // 等待插入 yield return new WaitUntil(() => false); } protected override IEnumerator AfterPlug() { throw new NotImplementedException(); } public override void OnPlugIn(string moduleName) { } } public class SingleModuleColorOnHandler : AbsWhackMoleNodeHandler { protected override IEnumerator WaitPlug() { throw new NotImplementedException(); } protected override IEnumerator AfterPlug() { throw new NotImplementedException(); } public override void OnPlugIn(string moduleName) { } } public class MultipleModuleColorOnHandler : AbsWhackMoleNodeHandler { protected override IEnumerator WaitPlug() { throw new NotImplementedException(); } protected override IEnumerator AfterPlug() { throw new NotImplementedException(); } public override void OnPlugIn(string moduleName) { } } }