221 lines
7.0 KiB
C#
221 lines
7.0 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
|
|
public class Leaderboard : MonoBehaviour
|
|
{
|
|
GameManager gm;
|
|
|
|
[SerializeField] Transform headerRow;
|
|
[SerializeField] List<Transform> Rows;
|
|
[SerializeField] Transform rankedRow;
|
|
|
|
[SerializeField] Transform specialPanel;
|
|
[SerializeField] Transform rankedPanel;
|
|
[SerializeField] GameObject instruction;
|
|
|
|
[SerializeField] Vector2 specialPanelLocal, rankedPanelLocal, rankedPanelLocalOnly;
|
|
|
|
[SerializeField] GameObject tgQr, whatsQr;
|
|
|
|
[Header("Маркировка бот/игрок")]
|
|
[SerializeField] List<Color> playerColors;
|
|
[SerializeField] List<Color> botColors;
|
|
|
|
List<PlayerStatsRecord> topRecords;
|
|
|
|
[SerializeField] GameObject RowPrefab;
|
|
[SerializeField] GameObject RowPrefabRanked;
|
|
[SerializeField] int MaxRows = 100;
|
|
[SerializeField] Transform RowsRoot;
|
|
[SerializeField] Vector2 RowOffset = new Vector2(0, -90);
|
|
[SerializeField] Vector2 startAnchoredPosition = new Vector2(0, 45);
|
|
|
|
public float accelerationY = 5;
|
|
public float speedY = 0;
|
|
public float maxSpeedY = 300;
|
|
|
|
Coroutine slideCoroutine;
|
|
|
|
private string dateFormat = "dd.MM.yy HH:mm";
|
|
|
|
|
|
private void OnDisable()
|
|
{
|
|
foreach (var row in Rows)
|
|
{
|
|
Destroy(row.gameObject);
|
|
}
|
|
Rows.Clear();
|
|
|
|
if (slideCoroutine != null)
|
|
StopCoroutine(slideCoroutine);
|
|
}
|
|
|
|
public void Initialize(bool showContacts)
|
|
{
|
|
bool specialPrize = true;
|
|
specialPrize = specialPrize & showContacts;
|
|
gm = GameManager.instance;
|
|
|
|
//Инициализация лэйаута
|
|
specialPanel.gameObject.SetActive(specialPrize);
|
|
if (specialPrize)
|
|
{
|
|
specialPanel.localPosition = specialPanelLocal;
|
|
rankedPanel.localPosition = rankedPanelLocal;
|
|
|
|
tgQr.SetActive(PlayerPrefs.HasKey("Telegram"));
|
|
whatsQr.SetActive(PlayerPrefs.HasKey("Number"));
|
|
instruction.SetActive(false);
|
|
}
|
|
else
|
|
{
|
|
rankedPanel.localPosition = rankedPanelLocalOnly;
|
|
instruction.SetActive(true);
|
|
}
|
|
|
|
|
|
|
|
int totalRecords = gm.StatsService.GetTotalRecordsCount();
|
|
int total = Mathf.Min(MaxRows, totalRecords);
|
|
|
|
topRecords = gm.StatsService.GetTopPlayers(total);
|
|
|
|
|
|
//тут надо спавить Ряды
|
|
SpawnRows(total);
|
|
|
|
|
|
ClearRowsText();
|
|
for (int i = 0; i < total; i++)
|
|
{
|
|
FillRow(i, topRecords[i]);
|
|
}
|
|
|
|
//rankedRow.gameObject.SetActive(false);
|
|
FillRow(rankedRow, gm.StatsService.GetLatestRecord());
|
|
rankedRow.gameObject.SetActive(true);
|
|
|
|
if (!showContacts)
|
|
{
|
|
slideCoroutine = StartCoroutine(SlideCoroutine());
|
|
}
|
|
speedY = 0;
|
|
|
|
|
|
}
|
|
IEnumerator SlideCoroutine()
|
|
{//надо еще максимальный слайд рассчитать
|
|
float minY = startAnchoredPosition.y;
|
|
float maxY = startAnchoredPosition.y - RowOffset.y *Rows.Count + (RowOffset.y*3);
|
|
|
|
float calculatedOffsetY = minY;
|
|
|
|
List<RectTransform> cachedRects = new List<RectTransform>();
|
|
foreach (Transform row in Rows)
|
|
{
|
|
cachedRects.Add(row.GetComponent<RectTransform>());
|
|
}
|
|
while (true)
|
|
{
|
|
speedY += accelerationY * Time.deltaTime;
|
|
speedY = Mathf.Clamp(speedY, -maxSpeedY, maxSpeedY);
|
|
|
|
calculatedOffsetY += speedY*Time.deltaTime;
|
|
calculatedOffsetY = Mathf.Clamp(calculatedOffsetY, minY, maxY);
|
|
|
|
|
|
//применить циклом смещение ко всем рядам
|
|
for (int i = 0; i < Rows.Count; i++)
|
|
{
|
|
cachedRects[i].anchoredPosition = startAnchoredPosition + RowOffset * i + Vector2.up * calculatedOffsetY;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
|
|
}
|
|
void SpawnRows(int amount)
|
|
{
|
|
Rows = new List<Transform>();
|
|
int latestRecordIndex = gm.StatsService.GetRecordRank(gm.StatsService.GetLatestRecord()) - 1;
|
|
|
|
for (int i = 0; i < amount; i++)
|
|
{
|
|
GameObject prefab = i == latestRecordIndex ? RowPrefabRanked : RowPrefab;
|
|
GameObject go = Instantiate(prefab, RowsRoot);
|
|
RectTransform rect = go.GetComponent<RectTransform>();
|
|
rect.anchoredPosition = startAnchoredPosition + RowOffset * i;
|
|
|
|
Rows.Add(rect);
|
|
}
|
|
}
|
|
|
|
|
|
public void ClearRowsText()
|
|
{
|
|
for (int i = 0; i < Rows.Count; i++)
|
|
{
|
|
for (int j = 0; j < 5; j++)
|
|
{
|
|
Rows[i].GetChild(j).GetComponentInChildren<TextMeshProUGUI>().text = "—";
|
|
}
|
|
}
|
|
for (int j = 0; j < 5; j++)
|
|
{
|
|
rankedRow.GetChild(j).GetComponentInChildren<TextMeshProUGUI>().text = "—";
|
|
}
|
|
}
|
|
private void FillRow(int rowIndex, PlayerStatsRecord record)
|
|
{
|
|
Transform row = Rows[rowIndex];
|
|
|
|
row.GetChild(0).GetComponentInChildren<TextMeshProUGUI>().text = (rowIndex + 1).ToString();
|
|
row.GetChild(1).GetComponentInChildren<TextMeshProUGUI>().text = GetMarkedName(record.PlayerName, record.IsBot);
|
|
row.GetChild(2).GetComponentInChildren<TextMeshProUGUI>().text = secondsToMinutes((int)record.CompletionTimeSec);
|
|
row.GetChild(3).GetComponentInChildren<TextMeshProUGUI>().text = record.MovesCount.ToString();
|
|
row.GetChild(4).GetComponentInChildren<TextMeshProUGUI>().text = record.CompletedAt.ToString(dateFormat);
|
|
}
|
|
|
|
private void FillRow(Transform row, PlayerStatsRecord record)
|
|
{
|
|
int rank = gm.StatsService.GetRecordRank(record);
|
|
|
|
row.GetChild(0).GetComponentInChildren<TextMeshProUGUI>().text = rank.ToString();
|
|
row.GetChild(1).GetComponentInChildren<TextMeshProUGUI>().text = GetMarkedName(record.PlayerName, record.IsBot);
|
|
row.GetChild(2).GetComponentInChildren<TextMeshProUGUI>().text = secondsToMinutes((int)record.CompletionTimeSec);
|
|
row.GetChild(3).GetComponentInChildren<TextMeshProUGUI>().text = record.MovesCount.ToString();
|
|
row.GetChild(4).GetComponentInChildren<TextMeshProUGUI>().text = record.CompletedAt.ToString(dateFormat);
|
|
}
|
|
|
|
public void DisplayCurrentPlayer(PlayerStatsRecord record)
|
|
{
|
|
rankedRow.gameObject.SetActive(true);
|
|
FillRow(rankedRow, record);
|
|
}
|
|
|
|
string secondsToMinutes(int seconds)
|
|
{
|
|
int minutes = seconds / 60;
|
|
int remainingSeconds = seconds % 60;
|
|
return $"{minutes:D2}:{remainingSeconds:D2}";
|
|
}
|
|
|
|
|
|
//маркируем цветами ботовские рекорды и рекорды игрока.
|
|
string GetMarkedName(string name, bool isBot)
|
|
{
|
|
List<Color> colors = isBot ? botColors : playerColors;
|
|
if (colors == null || colors.Count == 0) return name;
|
|
|
|
int rand = Random.Range(0, colors.Count);
|
|
string hex = ColorUtility.ToHtmlStringRGB(colors[rand]);
|
|
|
|
return $"{name}<color=#{hex}>*</color>";
|
|
}
|
|
|
|
}
|