using System; using PhxhSDK; using System.Linq; using UnityEngine; using Framework.BI; using Framework.Event; using Framework.State; using Gameplay.Manager; using Framework.Manager; using Framework.Constants; using Gameplay.LoadingExecutor; using System.Collections.Generic; using Gameplay.ForestLevel; using Object = UnityEngine.Object; using Vector3 = UnityEngine.Vector3; using NPOI.SS.Formula.Functions; namespace Gameplay.Level { public class LevelState : IState { private Thumbtack _curThumbtack; private string _levelID; private readonly Color _selectedColor = LevelUtils.GetRgbaColor(LevelConstants.SelectedColor); private readonly Color _defaultColor = Color.white; private bool _isMoving; private Transform _target; private List prePlankList; private List lastPlankList; public LevelState(string levelId) { _levelID = levelId; } public void OnEnter() { LevelManager.Instance.ReLoadLevelValue(); LoadingExecutorManager.Instance.ExecuteLoading(new LevelLoadingExecutor(_levelID)); InputManager.Instance.OnClick += _OnClick; } private void _OnClick(GameObject obj) { try { if (LevelManager.Instance.IsPause || LevelManager.Instance.IsOver) return; var hole = KongManager.Instance.GetHole(obj.name); if (hole != null && !_isMoving) { //拿起图钉 if (_curThumbtack == null && hole.LevelThumbtack != null) { _curThumbtack = hole.LevelThumbtack; hole.ShowGfx(); AudioManager.Instance.PlaySound(AudioType.SOUND, "S_Thumbtack", new UnityAudio(false)); _curThumbtack.Obj.GetComponent().color = _selectedColor; hole.LevelThumbtack = null; //记录拿起的Hole LevelManager.Instance.CurUndoState.PreModifiedKong = hole; } //替换图钉 else if (_curThumbtack != null && hole.LevelThumbtack != null) { LevelManager.Instance.CurUndoState.PreModifiedKong.LevelThumbtack = _curThumbtack; _curThumbtack.Obj.GetComponent().color = _defaultColor; _curThumbtack = hole.LevelThumbtack; hole.ShowGfx(); AudioManager.Instance.PlaySound(AudioType.SOUND, "S_Thumbtack", new UnityAudio(false)); _curThumbtack.Obj.GetComponent().color = _selectedColor; hole.LevelThumbtack = null; //记录拿起的Hole LevelManager.Instance.CurUndoState.PreModifiedKong = hole; } //放下图钉 else if (_curThumbtack != null && hole.LevelThumbtack == null) { bool canMove = false; //拿起位置和放下位置相同 if (LevelManager.Instance.CurUndoState.PreModifiedKong.Equals(hole)) { hole.ShowGfx(); AudioManager.Instance.PlaySound(AudioType.SOUND, "S_Thumbtack", new UnityAudio(false)); _curThumbtack.Obj.GetComponent().color = _defaultColor; hole.LevelThumbtack = _curThumbtack; _curThumbtack = null; return; } //记录放下的Hole LevelManager.Instance.CurUndoState.LastModifiedKong = hole; //没有木板遮挡洞口 if (!PlankManager.Instance.HasPlanksOverlapHole(hole)) { //得到Hole所受影响的木板列表 var lankList = PlankManager.Instance.FindAffectedPlanks(LevelManager.Instance.CurUndoState .LastModifiedKong); if (lankList.Count == 0) { /*DebugUtil.LogWarning("[{0}]空洞没有影响到的木板", LevelManager.Instance.CurUndoState.LastModifiedHole.Obj.name);*/ canMove = true; } else { //如果该没有木板遮挡该洞口则可以移动 canMove = lankList.All(plank => KongManager.Instance.IsOverlapHoleOfPlank( LevelManager.Instance.CurUndoState.LastModifiedKong, plank)); } } if (canMove) { hole.LevelThumbtack = _curThumbtack; //移动前记录变化前的木板 RecordPlankStatus(); //Undo操作记录 if (prePlankList != null) { foreach (var plank in prePlankList) { if (!plank.CurAffectedHoles.Values.Contains(LevelManager.Instance.CurUndoState .LastModifiedKong)) { var undoTransform = new KeyValuePair(plank.Obj.transform.position, plank.Obj.transform.rotation); LevelManager.Instance.CurUndoState.AffectPlanks?.Add(plank, undoTransform); } } } //开始移动 _isMoving = true; _target = hole.Obj.transform; } } NewbieGuide(); } } catch (Exception e) { DebugUtil.LogError("LevelState OnClick Error: {0}", e); } } public void OnUpdate(float deltaTime) { try { PutThumbtack(); if (_isMoving) { _curThumbtack.Obj.layer = 13; _curThumbtack.Obj.transform.position = Vector3.MoveTowards(_curThumbtack.Obj.transform.position, _target.position, LevelConstants.MoveSpeed * Time.deltaTime); if (_curThumbtack.Obj.transform.position == _target.position) { AudioManager.Instance.PlaySound(AudioType.SOUND, "S_Thumbtack", new UnityAudio(false)); BIManager.Instance.TrackEventLevel(cfg.BI.Event.level_step_move, LevelManager.Instance.CurUndoState.PreModifiedKong.Obj.name, LevelManager.Instance.CurUndoState.LastModifiedKong.Obj.name); _isMoving = false; AddorRemoveHj2D(); LevelManager.Instance.PushUndoState(); LevelManager.Instance.Step++; RecoverPlankStatus(); } } } catch (Exception e) { DebugUtil.LogError("LevelState OnUpdate Error: {0}", e); } } /// /// 暂停时提前放置钉子 /// private void PutThumbtack() { if ((LevelManager.Instance.IsPause || LevelManager.Instance.IsOver) && _isMoving && _curThumbtack != null) { _curThumbtack.Obj.transform.position = _target.position; } } private void AddorRemoveHj2D() { try { _curThumbtack.Obj.layer = 8; _curThumbtack.Obj.GetComponent().color = _defaultColor; //移除前记录位置 if (prePlankList != null) { foreach (var plank in prePlankList) { /*DebugUtil.LogError("LevelState检测前:检测{0}木板,最后的洞是{1}", plank.Obj.name, LevelManager.Instance.CurUndoState.LastModifiedHole.Obj.name);*/ if (!plank.CurAffectedHoles.Values.Contains(LevelManager.Instance.CurUndoState .LastModifiedKong)) { //DebugUtil.LogError("LevelState:{0}木板需要移除钉子{1}", plank.Obj.name, _curThumbtack.Obj.name); PlankManager.Instance.RemoveHingJoint2D(plank, _curThumbtack); } /*foreach (var affected in plank.CurAffectedHoles) { DebugUtil.LogError("木板{0}影响到的Hole有:{1}", plank.Obj.name, affected.Key); }*/ } } if (lastPlankList != null) { foreach (var plank in lastPlankList) { if (!plank.CurAffectedHoles.Values.Contains(LevelManager.Instance.CurUndoState.PreModifiedKong)) { LevelManager.Instance.CurUndoState.AddH2DjPlanks.Add(plank); PlankManager.Instance.AddHingJoint2D(plank, LevelManager.Instance.CurUndoState.LastModifiedKong.LevelThumbtack); } else { LevelManager.Instance.CurUndoState.ReplacePlanks.Add(plank); PlankManager.Instance.ReplaceAnchor(plank, LevelManager.Instance.CurUndoState.LastModifiedKong.LevelThumbtack); } } } _curThumbtack = null; } catch (Exception e) { DebugUtil.LogError("LevelState AddorRemoveHj2D Error: {0}", e); } } private void RecordPlankStatus() { try { prePlankList = PlankManager.Instance.FindAffectedPlanks(LevelManager.Instance.CurUndoState .PreModifiedKong, true); lastPlankList = PlankManager.Instance.FindAffectedPlanks( LevelManager.Instance.CurUndoState.LastModifiedKong, true); } catch (Exception e) { DebugUtil.LogError("LevelState RecordPlankStatus Error: {0}", e); } } private void RecoverPlankStatus() { PlankManager.Instance.ResumeDetection(); prePlankList.Clear(); lastPlankList.Clear(); } private void NewbieGuide() { if (LevelManager.Instance.IsNewbieGuide && LevelManager.Instance.CurUndoState.PreModifiedKong != null) { EventManager.Instance.Send(EventManager.EventName.NewBieGuideNext); } } public void OnExit() { try { InputManager.Instance.OnClick -= _OnClick; if (_curThumbtack != null) { Object.DestroyImmediate(_curThumbtack.Obj); _curThumbtack = null; } LevelManager.Instance.Release(); } catch (Exception e) { DebugUtil.LogError("LevelState OnExit Error: {0}", e); } } } }