unity_art_puzzle_playable_luna/APPlayableLuna/Assets/Scripts/UIGameView.cs

634 lines
22 KiB
C#
Raw Permalink 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 System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
using Sequence = DG.Tweening.Sequence;
namespace GuruClient
{
public class UIGameView : MonoBehaviour
{
public Transform patchesScrollView;
public Slider sldLevelProgress;
public Transform tipsFinger;
public GuruScrollRect sr;
public Text txtProgress;
public GameObject patchTemplate;
public Transform puzzleWhole;
public Transform puzzleBaseImg;
public Transform puzzleBaseImgLines;
public GameObject patchesPool;
public GameObject btnBack;
public GameObject btnTips;
public GameObject btnDebugDrag;
public Texture noiseTexture;
public GameObject objStageWinFx;
public GameObject objDotProgress;
private GameModel _gameModel;
private Sequence _myTipsSequence = null;
//已完成的拼图
private List<Patche> _completePatche = new List<Patche>();
private GameObject _roleTemplate;
//手指抬起时间
private double _fingerUpTime = 0f;
//第一关的自动提示
private int _autoTipsTimer;
private int _levelDurationTimer;
//自动游戏的Timer
private int _autoPlayTimer = 0;
private float _lastMatchTime;
private bool _hasGuide = false;
private bool _isFirstRefresh = true;
//是否已经开始下一关下载
private bool _hasStartDownloadNextLevel = false;
private void Awake()
{
}
// Start is called before the first frame update
void Start()
{
EventManager.AddListenner("UPDATE_PROGRESS", UpdateProgress);
EventManager.AddListenner("START_NEXT_LEVEL", OnNextLevel);
EventManager.AddListenner("UPDATE_PROGRESS_DOT", UpdateProgressDot);
btnTips.GetComponent<Button>().onClick.AddListener(() =>
{
ShowTips(true);
});
}
private void OnDestroy()
{
EventManager.RemoveListenner("UPDATE_PROGRESS", UpdateProgress);
EventManager.RemoveListenner("START_NEXT_LEVEL", OnNextLevel);
EventManager.RemoveListenner("UPDATE_PROGRESS_DOT", UpdateProgressDot);
}
public void StartGame()
{
_gameModel = GameManager.Instance.GetModel();
GameManager.Instance.PatchPool.OnInit(delegate(GameObject obj)
{
Patche patche = obj.GetComponent<Patche>();
if (patche != null)
{
patche.Init();
}
});
GameManager.Instance.StartStage();
OnNextLevel();
UpdateProgress();
}
public void AddCompletePatche(Patche patche)
{
_completePatche.Add(patche);
}
private string GetPsdID()
{
if (_gameModel != null)
{
ALevel aLevel = _gameModel.GetCurrentLevel();
if (aLevel != null)
{
return aLevel.psdID;
}
}
return "";
}
//给已经patched的进行排序
public void SortPatched()
{
if (_completePatche.Count > 1)
{
_completePatche[_completePatche.Count - 1].transform.SetSiblingIndex(_completePatche.Count);
for (int i = _completePatche.Count - 1; i >= 0 ; i--)
{
Patche cur = _completePatche[i];
Patche pre = null;
if (i - 1 >= 0)
{
pre = _completePatche[i - 1];
}
if (pre != null)
{
int preOrder = pre.GetOrder();
int curOrder = cur.GetOrder();
if (preOrder > curOrder)
{
Patche tmp = pre;
_completePatche[i - 1] = cur;
_completePatche[i] = tmp;
}else
{
break;
}
}
}
}
for (int i = 0; i < _completePatche.Count; i++)
{
_completePatche[i].transform.SetSiblingIndex(_completePatche[i].GetOrder());
}
}
/// <summary>
/// 移除patch对应的一条线
/// </summary>
/// <param name="aPatch">拼图文件数据</param>
public void RemoveLine(APatch aPatch)
{
if (_gameModel.IsHideLineWhenPatched() && aPatch.IsPatch())
{
string lineName = aPatch.name.Replace("patch", "line");
Transform tf = puzzleBaseImgLines.Find(lineName);
RemoveALine(tf);
}
}
public void OnNextLevel(IEventData data = null)
{
sldLevelProgress.maxValue = GameManager.Instance.GetCurrentStageData().Count;
sldLevelProgress.value = _gameModel.GetCurrentStep();
}
public void UpdateProgress(IEventData data = null)
{
txtProgress.text = _gameModel.GetCompletePatchCount() + "/" + _gameModel.GetTotalPatchCount();
sldLevelProgress.value = _gameModel.GetCurrentStep();
}
public void UpdateProgressDot(IEventData data = null)
{
//更新dot progress
Tuple<int, int> stagePro = _gameModel.GetStageProgress();
if (stagePro.Item2 <= 1)
{
return;
}
int childCount = objDotProgress.transform.childCount;
// Log.E(stagePro.Item1 - 1 +"/"+stagePro.Item2);
GameObject prefab = objDotProgress.transform.GetChild(0).gameObject;
for (int i = 0; i < stagePro.Item2; i++)
{
GameObject obj;
if (i < childCount)
{
obj = objDotProgress.transform.GetChild(i).gameObject;
}
else
{
obj = Instantiate(prefab, objDotProgress.transform);
}
obj.SetActive(true);
if (i < stagePro.Item1 - 1)
{
obj.transform.Find("Dot").gameObject.SetActive(true);
}
else
{
obj.transform.Find("Dot").gameObject.SetActive(false);
}
}
}
public void LoadAutoPatches(List<APatch> patches, bool isTexture = false, bool isRecover = false, Action callback = null)
{
for (int i = 0; i < patches.Count; i++)
{
APatch aPatch = patches[i];
// GameObject temp = Instantiate(patchTemplate, puzzleBaseImg);
GameObject temp = GameManager.Instance.PatchPool.GetObj(puzzleBaseImg);
Patche p = temp.GetComponent<Patche>();
string folder = isTexture ? "Texture" : "Atlas";
string patchImgPath = $"Levels/{GetPsdID()}/{folder}/{aPatch.name}";
p.SetData(this, aPatch, patchImgPath);
p.PositionedFinal(false);
if (i == 0)
{
p.ShowEffect(true, isRecover, null, 1.0f, callback);
}
else
{
p.ShowEffect(true, isRecover, null, 1.0f, null);
}
}
if (patches.Count == 0)
{
Timer.Instance.SetTimeout(0.05f, () => {
callback?.Invoke();
});
}
}
public void LoadBg(Action callback)
{
Debug.Log("加载背景 开始");
Dictionary<string, APatch> patchDB = _gameModel.GetPatchDB();
APatch aPatch = patchDB[$"base"];
// GameObject temp = Instantiate(patchTemplate, puzzleBaseImg);
Debug.Log("加载背景 step 1");
GameObject temp = GameManager.Instance.PatchPool.GetObj(puzzleBaseImg);
temp.transform.SetSiblingIndex(0);
Debug.Log("加载背景 step 2");
Patche p = temp.GetComponent<Patche>();
string patchImgPath = $"Levels/{GetPsdID()}/Texture/{aPatch.name}";
Debug.Log("加载背景 step 3");
p.SetData(this, aPatch, patchImgPath);
Debug.Log("加载背景 step 4");
p.PositionedFinal(false);
Debug.Log("加载背景 step 5");
p.ShowEffect(true, false, null, 1.0f, callback);
Debug.Log("加载背景 成功");
}
//加载人物
public void LoadRole(bool isRecover = false, bool isFinish = false, Action callback = null)
{
Dictionary<string, APatch> patchDB = _gameModel.GetPatchDB();
APatch aPatch = new APatch();
bool found = false;
//如果是恢复游戏,则找到上一个人物,并显示
if(isRecover)
{
for (int i = _gameModel.GetCurrentStage(); i >= 0; i--)
{
if (patchDB.TryGetValue($"role_{i - 1}", out aPatch))
{
found = true;
break;
}
}
}else //否则使用当前人物
{
if (patchDB.TryGetValue($"role_{_gameModel.GetCurrentStage() - 1}", out aPatch))
{
found = true;
}
}
if (found)
{
//移除以前的人物
if (_roleTemplate != null)
{
GameObject tmp = _roleTemplate;
ShowEffectInner(tmp, null);
}
// GameObject temp = Instantiate(patchTemplate, puzzleBaseImg);
GameObject temp = GameManager.Instance.PatchPool.GetObj(puzzleBaseImg);
_roleTemplate = temp;
Patche p = temp.GetComponent<Patche>();
temp.transform.SetSiblingIndex(aPatch.sub_stage);
string patchImgPath = $"Levels/{GetPsdID()}/Texture/{aPatch.name}_{aPatch.sub_stage}";
p.SetData(this, aPatch, patchImgPath);
p.PositionedFinal(false);
p.ShowFade(true, false, callback);
}
callback?.Invoke();
}
//新增协程
private void ShowEffectInner(GameObject go, Action callback)
{
go.GetComponent<Patche>().ShowFade(false, false, () =>
{
_completePatche.Remove(go.GetComponent<Patche>());
// DestroyImmediate(go);
GameManager.Instance.PatchPool.RecycleObj(go);
callback?.Invoke();
});
}
//加载线稿图
public void LoadLineTemplate(Action callback)
{
// GamePlayConfig gamePlayConfig = GameConfig.GetConfig<GamePlayConfig>();
// int hideLineLevel = gamePlayConfig.GetHideLineLevel(_gameModel.GetCurrentLevel().type);
bool isRemoveLineWhenPatched = true;
List<APatch> lines = GameManager.Instance.GetCurrentStageLineData();
foreach (APatch aPatch in lines)
{
Transform patchTrans = puzzleBaseImg.Find(aPatch.name.Replace("line", "patch"));
if ((isRemoveLineWhenPatched && patchTrans == null) || !isRemoveLineWhenPatched)
{
// APatch aPatch = patchDB[$"line_{_gameModel.GetCurrentStage()}"];
// GameObject temp = Instantiate(patchTemplate, puzzleBaseImgLines);
GameObject temp = GameManager.Instance.PatchPool.GetObj(puzzleBaseImgLines);
Patche p = temp.GetComponent<Patche>();
temp.transform.SetSiblingIndex(10000);
string patchImgPath = $"Levels/{GetPsdID()}/Lines/{aPatch.name}";
p.SetData(this, aPatch, patchImgPath);
p.PositionedFinal(false);
p.ShowEffect(true, false, null, 1.0f);
}
}
Timer.Instance.SetTimeoutAsync(1.0f, callback);
}
public void RemoveLineTemplate(Action callback)
{
if (puzzleBaseImgLines.childCount > 0)
{
for (int i = puzzleBaseImgLines.childCount - 1; i >= 0; i--)
{
RemoveALine(puzzleBaseImgLines.GetChild(i));
}
Timer.Instance.SetTimeout(2.0f , () =>
{
callback?.Invoke();
});
}else
{
callback?.Invoke();
}
}
private void RemoveALine(Transform line)
{
if (line != null)
{
RemoveALineInner(line, null);
}
}
private void RemoveALineInner(Transform line, Action callback)
{
line.GetComponent<Patche>().ShowEffect(false, false, null, 1.0f, callback);
DestroyImmediate(line.gameObject);
// GameManager.Instance.PatchPool.RecycleObj(line.gameObject);
}
//游戏结束
public void GameWin(bool isDrop)
{
StopTipsTimer();
// UIManager.Instance.Show(UIID.UIGameWin, new object[2]{_gameModel.GetCurrentLevel(), isDrop}, (uibase) => {
// CustomAssetBundle cab = GameManager.Instance.GetCustomAssetBundle();
// //避免资源被释放,主动添加引用
// cab.AddTag(uibase.GetUIConfig().prefab);
// GameManager.Instance.ExitGame();
// });
Debug.Log("拼图完成");
}
public void StopTipsTimer()
{
if (_autoTipsTimer != 0)
{
Timer.Instance.Stop(_autoTipsTimer);
_autoTipsTimer = 0;
}
if(_autoPlayTimer != 0)
{
Timer.Instance.Stop(_autoPlayTimer);
_autoPlayTimer = 0;
}
}
public void ShowTips(bool isFree)
{
string psdID = GetPsdID();
if (true)
{
APatch patch = GameManager.Instance.GetOneUnCompletePatch();
if (patch.isValid())
{
Transform tipsChild = null;
Transform poolTrans = patchesPool.transform;
int childCount = OriginPatchObjs.Count;
for (int i = 0; i < childCount; i++)
{
Transform child = OriginPatchObjs[i].transform;
APatch p = child.GetComponent<Patche>().GetData();
if(p.Equals(patch))
{
tipsChild = child;
break;
}
}
if(tipsChild != null)
{
sr.StopMovement();
float x = -tipsChild.localPosition.x + Screen.width/2;
x = Mathf.Min(x, 0);
if(poolTrans.parent.GetComponent<RectTransform>().sizeDelta.x > 0)
{
x = Mathf.Max(x, -poolTrans.parent.GetComponent<RectTransform>().sizeDelta.x);
}
poolTrans.parent.localPosition = new Vector3(x, poolTrans.parent.localPosition.y, poolTrans.parent.localPosition.z);
StopTips();
Patche patche = tipsChild.GetComponent<Patche>();
APatch p = patche.GetData();
Vector2 endPos = puzzleWhole.localPosition + patche.GetConvertedTargetPos();
//控制手指从A移动到B
tipsFinger.position = tipsChild.position;
tipsFinger.gameObject.SetActive(true);
_myTipsSequence = DOTween.Sequence();
_myTipsSequence.SetLoops(-1);
_myTipsSequence.Append(tipsFinger.GetComponent<Image>().DOFade(1, 0.5f));
_myTipsSequence.Append(tipsFinger.DOLocalMove(endPos, 1.0f).SetDelay( 0.5f));
_myTipsSequence.Append(tipsFinger.GetComponent<Image>().DOFade(0, 0.5f).SetDelay( 0.5f).OnComplete(() => {
}));
}
}
}
}
//停止引导动作
public void StopTips()
{
if (_myTipsSequence != null)
{
_myTipsSequence.Kill();
_myTipsSequence = null;
tipsFinger.localPosition = new Vector3(3000, 30000, 0);
tipsFinger.gameObject.SetActive(false);
}
}
/// <summary>
/// 初始化拼图
/// </summary>
/// <param name="stage">需要初始化的阶段,-1表示全部</param>
/// <param name="complete">完成后的回调</param>
/// <returns></returns>
public void InitPatches(int stage, Action complete)
{
List<APatch> patchDB = _gameModel.GetOperablePatch();
_patchObjs.Clear();
OriginPatchObjs.Clear();
List<APatch> tmpList = new List<APatch>();
int index = 1;
foreach (APatch item in patchDB)
{
if (((stage == -1 && item.stage >= _gameModel.GetCurrentStage()) || stage == item.stage) && !GameManager.Instance.IsCompletedPatch(item))
{
tmpList.Add(item);
CreatePatch(item, index);
index ++;
}
}
SetPatchIndex(tmpList);
SortPatches(true, complete, true, 0.05f);
}
private void SetPatchIndex(List<APatch> patchDB)
{
patchDB.Sort(delegate(APatch patch1, APatch patch2)
{
if (patch1.stage < patch2.stage)
{
return -1;
}
if (patch1.stage > patch2.stage)
{
return 1;
}
if (patch1.sub_stage < patch2.sub_stage)
{
return -1;
}
if (patch1.sub_stage > patch2.sub_stage)
{
return 1;
}
return 1;
});
for (int i = 0; i < patchDB.Count; i++)
{
if (_patchObjs.TryGetValue(patchDB[i].name, out var obj))
{
obj.transform.SetSiblingIndex(i);
}
else
{
Debug.Log("index不存在");
}
}
}
private void CreatePatch(APatch aPatch, int index)
{
// GameObject temp = Instantiate(patchTemplate, patchesPool.transform);
GameObject temp = GameManager.Instance.PatchPool.GetObj(patchesPool.transform);
// temp.AddComponent<KeepReverseWhenAdded>();
Patche p = temp.GetComponent<Patche>();
_patchObjs[aPatch.name] = temp;
OriginPatchObjs.Add(temp);
string patchImgPath = $"Levels/{GetPsdID()}/Atlas/{aPatch.name}";
p.SetData(this, aPatch, patchImgPath);
//1000为固定偏移之后sort的时候做入场效果
temp.transform.localPosition = new Vector3(GameDefine.Game.PATCH_PADDING + (GameDefine.Game.PATCH_SIZE_MAX.x + GameDefine.Game.PATCH_SPAN) * index + 1500, 0, 0);
}
private Dictionary<string, GameObject> _patchObjs = new Dictionary<string, GameObject>();
public List<GameObject> OriginPatchObjs { set; get; } = new List<GameObject>();
private float _moveTime = 0.5f;
public void SortPatches(bool hasAnimation = false, Action complete = null, bool isResize = true, float delay = 0)
{
int completeCount = 0;
// RectTransform rtf = patchesPool.GetComponent<RectTransform>();
if (isResize)
{
ResizePatchesPool();
}
float totalDelay = delay;
int childCount = OriginPatchObjs.Count;
for (int i = 0; i < childCount; i++)
{
Transform child = OriginPatchObjs[i].transform;
if (hasAnimation)
{
Tweener tw = child.DOLocalMove(
new Vector3(
GameDefine.Game.PATCH_PADDING +
(GameDefine.Game.PATCH_SIZE_MAX.x + GameDefine.Game.PATCH_SPAN) * i +
GameDefine.Game.PATCH_SIZE_MAX.x / 2, 0, 0), _moveTime)
.OnComplete(() =>
{
completeCount++;
if (completeCount == childCount)
{
complete?.Invoke();
}
}).SetRecyclable();
if (i <= 5)
{
tw.SetDelay(totalDelay);
totalDelay += delay;
}
}else
{
child.localPosition = new Vector3(GameDefine.Game.PATCH_PADDING + (GameDefine.Game.PATCH_SIZE_MAX.x + GameDefine.Game.PATCH_SPAN) * i + GameDefine.Game.PATCH_SIZE_MAX.x/2, 0, 0);
}
}
if (!hasAnimation)
{
complete?.Invoke();
}
}
public void ResizePatchesPool()
{
RectTransform rtf = patchesPool.GetComponent<RectTransform>();
rtf.sizeDelta = new Vector2(rtf.childCount * (GameDefine.Game.PATCH_SIZE_MAX.x + GameDefine.Game.PATCH_SPAN) + 2 * GameDefine.Game.PATCH_PADDING - GameDefine.Game.PATCH_SPAN, rtf.sizeDelta.y);
}
}
}