300 lines
12 KiB
C#
300 lines
12 KiB
C#
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<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
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 暂停时提前放置钉子
|
||
/// </summary>
|
||
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<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);
|
||
}
|
||
}
|
||
}
|
||
} |