Forest_Client/Forest/Assets/Scripts/Gameplay/Level/LevelState.cs

286 lines
12 KiB
C#
Raw Normal View History

2024-06-12 15:01:54 +08:00
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 Object = UnityEngine.Object;
using Vector3 = UnityEngine.Vector3;
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<Plank> prePlankList;
private List<Plank> 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<SpriteRenderer>().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<SpriteRenderer>().color = _defaultColor;
_curThumbtack = hole.LevelThumbtack;
hole.ShowGfx();
AudioManager.Instance.PlaySound(AudioType.SOUND, "S_Thumbtack", new UnityAudio(false));
_curThumbtack.Obj.GetComponent<SpriteRenderer>().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<SpriteRenderer>().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<Vector3, Quaternion>(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
{
if (_isMoving)
{
_curThumbtack.Obj.layer = 8;
_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 AddorRemoveHj2D()
{
try
{
_curThumbtack.Obj.layer = 0;
_curThumbtack.Obj.GetComponent<SpriteRenderer>().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);
}
}
}
}