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;
|
2024-08-07 18:51:02 +08:00
|
|
|
|
using Gameplay.ForestLevel;
|
2024-06-12 15:01:54 +08:00
|
|
|
|
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
|
|
|
|
|
{
|
2024-08-23 13:23:22 +08:00
|
|
|
|
PutThumbtack();
|
2024-06-12 15:01:54 +08:00
|
|
|
|
if (_isMoving)
|
|
|
|
|
{
|
2024-07-29 13:08:58 +08:00
|
|
|
|
_curThumbtack.Obj.layer = 13;
|
2024-06-12 15:01:54 +08:00
|
|
|
|
_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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-23 13:23:22 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 暂停时提前放置钉子
|
|
|
|
|
/// </summary>
|
2024-08-21 16:24:06 +08:00
|
|
|
|
private void PutThumbtack()
|
|
|
|
|
{
|
|
|
|
|
if ((LevelManager.Instance.IsPause || LevelManager.Instance.IsOver) && _curThumbtack != null)
|
|
|
|
|
{
|
2024-08-23 13:23:22 +08:00
|
|
|
|
_curThumbtack.Obj.transform.position = _target.position;
|
2024-08-21 16:24:06 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-12 15:01:54 +08:00
|
|
|
|
private void AddorRemoveHj2D()
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2024-07-29 13:08:58 +08:00
|
|
|
|
_curThumbtack.Obj.layer = 8;
|
2024-06-12 15:01:54 +08:00
|
|
|
|
_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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|