318 lines
9.6 KiB
C#
318 lines
9.6 KiB
C#
using RuntimeData;
|
||
using TH1_Logic.Core;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace TH1_UI.View.Top
|
||
{
|
||
public class UITopTopBarView : Base.View
|
||
{
|
||
private const string TopBarAnimTimerMessage = "UITopTopBarView TopBarAnim";
|
||
private const float CoinSelfCheckInterval = 0.5f;
|
||
private int _topBarAnimVersion;
|
||
private bool _coinAnimActive;
|
||
private float _coinAnimEndTime;
|
||
private float _nextCoinSelfCheckTime;
|
||
|
||
//public Button closeButton;
|
||
public ViDelegateAssisstant.Dele OnBtnCloseClick;
|
||
|
||
public TextMeshProUGUI Faith;
|
||
public TextMeshProUGUI Turn;
|
||
public TextMeshProUGUI Coin;
|
||
public TextMeshProUGUI CoinPerTurn;
|
||
public Transform CoinTransform;
|
||
public Transform FaithTransform;
|
||
public TextMeshProUGUI Tech;
|
||
public TextMeshProUGUI TechPerTurn;
|
||
public Transform TechTransform;
|
||
public TextMeshProUGUI Culture;
|
||
public TextMeshProUGUI CulturePerTurn;
|
||
public Transform CultureTransform;
|
||
public RectTransform FatherPanel;
|
||
public GameObject PerfectTime;
|
||
|
||
public enum TopBarPanelType
|
||
{
|
||
Coin,
|
||
Faith,
|
||
Tech,
|
||
Culture
|
||
}
|
||
|
||
protected override void OnInit()
|
||
{
|
||
base.OnInit();
|
||
//closeButton.onClick.RemoveAllListeners();
|
||
//closeButton.onClick.AddListener(() => { OnBtnCloseClick.Invoke(); });
|
||
//CheckPanel.InitStart(RefreshStatus);
|
||
|
||
// 确保所有Transform初始时都是active的,等待数据显示逻辑来控制
|
||
// 这样可以防止Prefab中误设为inactive导致无法显示
|
||
if (CultureTransform != null)
|
||
CultureTransform.gameObject.SetActive(true);
|
||
if (TechTransform != null)
|
||
TechTransform.gameObject.SetActive(true);
|
||
|
||
}
|
||
|
||
|
||
//通常一局只会set一次,每次都是完全清空,然后绑定新的一个对局的按钮
|
||
public void SetContent()
|
||
{
|
||
UpdateAllInstant();
|
||
// 首次SetContent时强制重建布局,确保所有Panel的位置和大小正确
|
||
if (FatherPanel != null)
|
||
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
|
||
}
|
||
|
||
public void UpdateAllInstant()
|
||
{
|
||
//注意 开局首次调用本函数,所有city都是空,percoin和pertech perculture都是0,需要controller里的每个update函数来刷新的
|
||
|
||
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
|
||
CancelTopBarAnim();
|
||
|
||
// PerfectTime:仅在Perfect模式下显示
|
||
if (PerfectTime != null)
|
||
PerfectTime.SetActive(Main.MapData.MapConfig.GameMode == GameMode.PERFECT);
|
||
Turn.text = (Main.MapData.PlayerMap.SelfPlayerData.Turn + 1).ToString();
|
||
Faith.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerScore.ToString();
|
||
Coin.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin.ToString();
|
||
CoinPerTurn.text =
|
||
"<color=yellow>" +
|
||
Main.PlayerLogic.GetPlayerCoinPerTurn(Main.MapData,Main.MapData.PlayerMap.SelfPlayerData.Id)
|
||
+ "</color>";
|
||
|
||
var techPerTurn =
|
||
Main.PlayerLogic.GetPlayerTechPointPerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerData.Id);
|
||
|
||
// 强制根据数据显示/隐藏Tech模块
|
||
bool techNeedShow = (techPerTurn > 0 || Main.MapData.PlayerMap.SelfPlayerData.PlayerTechPoint > 0);
|
||
|
||
if (TechTransform != null)
|
||
{
|
||
bool wasActive = TechTransform.gameObject.activeSelf;
|
||
TechTransform.gameObject.SetActive(techNeedShow);
|
||
if (wasActive != techNeedShow)
|
||
{
|
||
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
|
||
}
|
||
|
||
if (techNeedShow)
|
||
{
|
||
Tech.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerTechPoint.ToString();
|
||
TechPerTurn.text = "<color=lightblue>" + techPerTurn + "</color>";
|
||
}
|
||
}
|
||
|
||
var culturePerTurn =
|
||
Main.PlayerLogic.GetPlayerCulturePointPerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerData.Id);
|
||
|
||
// 强制根据数据显示/隐藏Culture模块
|
||
bool cultureNeedShow = (culturePerTurn > 0 || Main.MapData.PlayerMap.SelfPlayerData.PlayerCultureInfo.PlayerCulture > 0);
|
||
//cultureNeedShow = true;
|
||
|
||
if (CultureTransform != null)
|
||
{
|
||
bool wasActive = CultureTransform.gameObject.activeSelf;
|
||
CultureTransform.gameObject.SetActive(cultureNeedShow);
|
||
if (wasActive != cultureNeedShow)
|
||
{
|
||
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
|
||
}
|
||
|
||
if (cultureNeedShow)
|
||
{
|
||
Culture.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerCultureInfo.PlayerCulture.ToString();
|
||
CulturePerTurn.text = "<color=#B343C2>" + culturePerTurn + "</color>";
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
public void CloseView()
|
||
{
|
||
//AudioManager.Instance.StopMusic();
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
if (Time.time < _nextCoinSelfCheckTime) return;
|
||
_nextCoinSelfCheckTime = Time.time + CoinSelfCheckInterval;
|
||
SelfCheckCoinText();
|
||
}
|
||
|
||
|
||
public void UpdateTurn()
|
||
{
|
||
Turn.text = (Main.MapData.PlayerMap.SelfPlayerData.Turn + 1).ToString();
|
||
}
|
||
|
||
public void UpdateCoin()
|
||
{
|
||
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
|
||
CancelTopBarAnim();
|
||
if (!int.TryParse(Coin.text, out var old))
|
||
old = Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin;
|
||
float delay = Table.Instance.AnimDataAssets.ProjectileCoinMoveTime;
|
||
if (old > Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin) delay = 0f;
|
||
TopBarAnim(Coin,old,Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin,delay,TopBarPanelType.Coin);
|
||
}
|
||
|
||
public void UpdateTech()
|
||
{
|
||
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
|
||
var techPerTurn =
|
||
Main.PlayerLogic.GetPlayerTechPointPerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerData.Id);
|
||
|
||
|
||
//如果techTransform应该显示的状态和实际状态不一致,更新其显示状态
|
||
bool needShow = (techPerTurn > 0 || Main.MapData.PlayerMap.SelfPlayerData.PlayerTechPoint > 0);
|
||
if (needShow != TechTransform.gameObject.activeSelf)
|
||
{
|
||
TechTransform.gameObject.SetActive(techPerTurn > 0);
|
||
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
|
||
}
|
||
|
||
if (needShow)
|
||
{
|
||
Tech.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerTechPoint.ToString();
|
||
TechPerTurn.text = "<color=lightblue>" + techPerTurn + "</color>";
|
||
}
|
||
}
|
||
|
||
public void UpdateCulture()
|
||
{
|
||
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
|
||
var culturePerTurn =
|
||
Main.PlayerLogic.GetPlayerCulturePointPerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerData.Id);
|
||
|
||
// 强制根据数据显示/隐藏Culture模块
|
||
bool needShow = (culturePerTurn > 0 || Main.MapData.PlayerMap.SelfPlayerData.PlayerCultureInfo.PlayerCulture > 0);
|
||
|
||
if (CultureTransform != null)
|
||
{
|
||
bool wasActive = CultureTransform.gameObject.activeSelf;
|
||
CultureTransform.gameObject.SetActive(needShow);
|
||
if (wasActive != needShow)
|
||
{
|
||
LayoutRebuilder.ForceRebuildLayoutImmediate(FatherPanel);
|
||
}
|
||
|
||
if (needShow)
|
||
{
|
||
Culture.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerCultureInfo.PlayerCulture.ToString();
|
||
CulturePerTurn.text = "<color=#B343C2>" + culturePerTurn + "</color>";
|
||
}
|
||
}
|
||
}
|
||
|
||
public void UpdateFaith()
|
||
{
|
||
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
|
||
if (!int.TryParse(Faith.text, out var old)) return;
|
||
//不允许脱离action逻辑修改mapData
|
||
//Main.PlayerLogic.CalcAllPlayerScore(Main.MapData);
|
||
Faith.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerScore.ToString();
|
||
|
||
/*float delay = Table.Instance.AnimDataAssets.ProjectileCoinMoveTime;
|
||
if (old > Main.MapData.PlayerMap.SelfPlayerData.PlayerScore) delay = 0f;
|
||
TopBarAnim(Faith,old,Main.MapData.PlayerMap.SelfPlayerData.PlayerScore,delay);
|
||
*/
|
||
|
||
}
|
||
|
||
private void TopBarAnim(TextMeshProUGUI targetText, int oldValue,int targetValue,float startDelay,TopBarPanelType panelType)
|
||
{
|
||
var animVersion = _topBarAnimVersion;
|
||
int maxTime = 100;
|
||
int now = oldValue;
|
||
int time = Mathf.Abs(targetValue - oldValue);
|
||
int step = targetValue > oldValue ? 1 : -1;
|
||
|
||
if (time > maxTime)
|
||
{
|
||
time = maxTime;
|
||
step = (targetValue - oldValue) / time;
|
||
}
|
||
if (time == 0)
|
||
{
|
||
targetText.text = targetValue.ToString();
|
||
return;
|
||
}
|
||
if (panelType == TopBarPanelType.Coin)
|
||
{
|
||
_coinAnimActive = true;
|
||
_coinAnimEndTime = Time.time + Mathf.Max(0f, startDelay) + (time - 1) * 0.03f + 0.1f;
|
||
}
|
||
|
||
for (int s = 0; s < time; s++)
|
||
{
|
||
now += step;
|
||
//如果时长太长,直接跳到结果
|
||
|
||
//final Check用来在最后一帧强制对其真实数值coin 或者faith
|
||
bool finalCheck = false;
|
||
|
||
if (s == time - 1)
|
||
{
|
||
now = targetValue;
|
||
finalCheck = true;
|
||
}
|
||
|
||
var panel = panelType;
|
||
var text = targetText;
|
||
var tmp = now;
|
||
var tmps = Mathf.Min(s,200);
|
||
Timer.Instance.TimerRegister(this, () =>
|
||
{
|
||
if (animVersion != _topBarAnimVersion) return;
|
||
text.text = tmp.ToString();
|
||
if (finalCheck)
|
||
{
|
||
if(panel == TopBarPanelType.Coin && Main.MapData != null)
|
||
{
|
||
text.text = Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin.ToString();
|
||
_coinAnimActive = false;
|
||
}
|
||
}
|
||
},tmps * 0.03f + startDelay , TopBarAnimTimerMessage);
|
||
}
|
||
|
||
}
|
||
|
||
private void CancelTopBarAnim()
|
||
{
|
||
_topBarAnimVersion++;
|
||
_coinAnimActive = false;
|
||
Timer.Instance?.CancelByMessage(TopBarAnimTimerMessage);
|
||
}
|
||
|
||
private void SelfCheckCoinText()
|
||
{
|
||
if (Main.MapData?.PlayerMap?.SelfPlayerData == null || Coin == null) return;
|
||
if (_coinAnimActive)
|
||
{
|
||
if (Time.time <= _coinAnimEndTime) return;
|
||
CancelTopBarAnim();
|
||
}
|
||
|
||
var realCoin = Main.MapData.PlayerMap.SelfPlayerData.PlayerCoin;
|
||
if (int.TryParse(Coin.text, out var showCoin) && showCoin == realCoin) return;
|
||
CancelTopBarAnim();
|
||
Coin.text = realCoin.ToString();
|
||
}
|
||
|
||
public void UpdateCoinPerTurn()
|
||
{
|
||
if (Main.MapData?.PlayerMap?.SelfPlayerData == null) return;
|
||
CoinPerTurn.text = "<color=yellow>" + Main.PlayerLogic.GetPlayerCoinPerTurn(Main.MapData,Main.MapData.PlayerMap.SelfPlayerData.Id) + "</color>";
|
||
}
|
||
|
||
|
||
}
|
||
|
||
}
|