using System; using System.Collections; using AibisDream.Framework; 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); } public void OnPlugOut(string moduleName) { _nodeHandler.OnPlugOut(moduleName); } public void StartGame() { Handle(); } 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(true); OnGameEnd = null; } } else { // TODO 进入失败结局 OnGameEnd?.Invoke(false); OnGameEnd = null; } } public static WhackMoleHandler Create(WhackMoleData data, MonoBehaviour mono) { var res = new WhackMoleHandler(mono); AbsWhackMoleNodeHandler lastHandler = null; foreach (var node in data.nodes) { var handler = res.CreateNodeHandler(node); res._nodeHandler ??= handler; if (lastHandler != null) { lastHandler.nextHandler = handler; } lastHandler = handler; } return res; } private 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 static WhackMoleSystem WhackMoleSystem => FixSystemCenter.SystemDic.Get(); protected WhackMoleNode node; public AbsWhackMoleNodeHandler nextHandler; public readonly UnityEvent onHandleEnd = new(); public void Init(WhackMoleNode nodeData) { node = nodeData; } public IEnumerator Handle() { EnumEventSystem.Global.Send(WhackMoleState.BeforePlug); yield return BeforePlug(); EnumEventSystem.Global.Send(WhackMoleState.WaitPlug, node.lightOnTime); yield return WaitPlug(); EnumEventSystem.Global.Send(WhackMoleState.AfterPlug); yield return AfterPlug(); } protected virtual IEnumerator BeforePlug() { WhackMoleSystem.StartAllFlicker(); yield return new WaitForSeconds(node.flickerTime); WhackMoleSystem.StopAllFlicker(); } protected abstract IEnumerator WaitPlug(); protected abstract IEnumerator AfterPlug(); public abstract void OnPlugIn(string moduleName); public abstract void OnPlugOut(string moduleName); } public class SingleModuleLightOnHandler : AbsWhackMoleNodeHandler { private bool _isPlugIn; protected override IEnumerator WaitPlug() { Debug.Log("进入等待"); // 先等待 yield return new WaitForSeconds(1f); _isPlugIn = false; WhackMoleSystem.LightOnModule(node.moduleName); // 进入循环等待插入事件,规定时间内未插入则进入失败结局 var waitTime = 0f; while (!_isPlugIn && waitTime < node.lightOnTime) { waitTime += Time.deltaTime; yield return null; EnumEventSystem.Global.Send(WhackMoleState.WaitPlug, node.lightOnTime - waitTime); } } protected override IEnumerator AfterPlug() { Debug.Log("进入后处理"); WhackMoleSystem.LightOffModule(node.moduleName); if (_isPlugIn) { // TODO 正常插入,触发效果并进入下一个关卡 yield return new WaitForSeconds(1); onHandleEnd?.Invoke(true); } else { // TODO 超时,触发失败结局 onHandleEnd?.Invoke(false); } } public override void OnPlugIn(string moduleName) { if (moduleName == node.moduleName) { _isPlugIn = true; } } public override void OnPlugOut(string moduleName) { if (moduleName == node.moduleName) { _isPlugIn = false; } } } 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 override void OnPlugOut(string moduleName) { throw new NotImplementedException(); } } 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 override void OnPlugOut(string moduleName) { throw new NotImplementedException(); } } public class MultipleModuleColorOnHandler : AbsWhackMoleNodeHandler { protected override IEnumerator WaitPlug() { throw new NotImplementedException(); } protected override IEnumerator AfterPlug() { throw new NotImplementedException(); } public override void OnPlugIn(string moduleName) { } public override void OnPlugOut(string moduleName) { throw new NotImplementedException(); } } public enum WhackMoleState { BeforePlug, WaitPlug, AfterPlug, } }