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

299 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
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);
}
}
}
}