Commit 7df88fa9 authored by saad's avatar saad

standardize ui for all games

parent 0652cde1
...@@ -36,7 +36,7 @@ RectTransform: ...@@ -36,7 +36,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 22.572838, y: -25.96685} m_AnchoredPosition: {x: 22.572838, y: -25.96685}
m_SizeDelta: {x: 51.9337, y: 51.9337} m_SizeDelta: {x: 0, y: 51.9337}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &9055497536415541340 --- !u!222 &9055497536415541340
CanvasRenderer: CanvasRenderer:
...@@ -871,7 +871,7 @@ RectTransform: ...@@ -871,7 +871,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 144.8642, y: -25.96685} m_AnchoredPosition: {x: 144.8642, y: -25.96685}
m_SizeDelta: {x: 51.9337, y: 51.9337} m_SizeDelta: {x: 0, y: 51.9337}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6316850651786239132 --- !u!222 &6316850651786239132
CanvasRenderer: CanvasRenderer:
...@@ -1213,7 +1213,7 @@ RectTransform: ...@@ -1213,7 +1213,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 83.71851, y: -25.96685} m_AnchoredPosition: {x: 83.71851, y: -25.96685}
m_SizeDelta: {x: 51.9337, y: 51.9337} m_SizeDelta: {x: 0, y: 51.9337}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6319844450247911941 --- !u!222 &6319844450247911941
CanvasRenderer: CanvasRenderer:
...@@ -1412,7 +1412,7 @@ GameObject: ...@@ -1412,7 +1412,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &810524042309484015 --- !u!224 &810524042309484015
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -1523,8 +1523,8 @@ RectTransform: ...@@ -1523,8 +1523,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 16, y: 25.967} m_AnchoredPosition: {x: 20, y: 25.967}
m_SizeDelta: {x: 76.011, y: 51.934} m_SizeDelta: {x: 118.7, y: 51.934}
m_Pivot: {x: 0.5, y: 1} m_Pivot: {x: 0.5, y: 1}
--- !u!222 &8147257740575675822 --- !u!222 &8147257740575675822
CanvasRenderer: CanvasRenderer:
...@@ -1599,7 +1599,7 @@ GameObject: ...@@ -1599,7 +1599,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 0 m_IsActive: 1
--- !u!224 &5824509147393400757 --- !u!224 &5824509147393400757
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -2198,7 +2198,7 @@ RectTransform: ...@@ -2198,7 +2198,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 206.00986, y: -25.96685} m_AnchoredPosition: {x: 206.00986, y: -25.96685}
m_SizeDelta: {x: 51.9337, y: 51.9337} m_SizeDelta: {x: 0, y: 51.9337}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3778932895135096301 --- !u!222 &3778932895135096301
CanvasRenderer: CanvasRenderer:
...@@ -2395,6 +2395,9 @@ MonoBehaviour: ...@@ -2395,6 +2395,9 @@ MonoBehaviour:
_timerFill: {fileID: 2112913333798308398} _timerFill: {fileID: 2112913333798308398}
_timerText: {fileID: 0} _timerText: {fileID: 0}
_maxTime: 30 _maxTime: 30
_pointsContainer: {fileID: 5824509147393400757}
_activePointColor: {r: 0.99607843, g: 0.8431373, b: 0, a: 1}
_inactivePointColor: {r: 0.99607843, g: 0.8431373, b: 0, a: 0.5411765}
onRestartClicked: onRestartClicked:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
...@@ -2626,7 +2629,7 @@ GameObject: ...@@ -2626,7 +2629,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &5776870742342999693 --- !u!224 &5776870742342999693
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -2828,7 +2831,7 @@ RectTransform: ...@@ -2828,7 +2831,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1} m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 267.15555, y: -25.96685} m_AnchoredPosition: {x: 267.15555, y: -25.96685}
m_SizeDelta: {x: 51.9337, y: 51.9337} m_SizeDelta: {x: 0, y: 51.9337}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &1293769170803587111 --- !u!222 &1293769170803587111
CanvasRenderer: CanvasRenderer:
...@@ -3108,7 +3111,7 @@ GameObject: ...@@ -3108,7 +3111,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &7626717906572486054 --- !u!224 &7626717906572486054
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
...@@ -3347,7 +3350,7 @@ GameObject: ...@@ -3347,7 +3350,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &4797898653388170541 --- !u!224 &4797898653388170541
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
......
...@@ -94,7 +94,6 @@ namespace com.al_arcade.tf ...@@ -94,7 +94,6 @@ namespace com.al_arcade.tf
protected override void BeginGameplay() protected override void BeginGameplay()
{ {
_progress = 0; _progress = 0;
// Reset base counters
_currentIndex = _score = _streak = _correctCount = _wrongCount = _totalAsked = 0; _currentIndex = _score = _streak = _correctCount = _wrongCount = _totalAsked = 0;
_state = TfGameState.Playing; _state = TfGameState.Playing;
...@@ -102,6 +101,8 @@ namespace com.al_arcade.tf ...@@ -102,6 +101,8 @@ namespace com.al_arcade.tf
{ {
uiManager.ShowGameUI(); uiManager.ShowGameUI();
uiManager.SetProgress(0, stepsToWin); uiManager.SetProgress(0, stepsToWin);
// ✅ NEW: reset points dots
uiManager.TickPoints(0);
uiManager.EnableScore(IsChallengeMode); uiManager.EnableScore(IsChallengeMode);
if (IsChallengeMode && ChallengeManager.Instance != null) if (IsChallengeMode && ChallengeManager.Instance != null)
{ {
...@@ -133,7 +134,7 @@ namespace com.al_arcade.tf ...@@ -133,7 +134,7 @@ namespace com.al_arcade.tf
public void ResetGame() public void ResetGame()
{ {
ResetBaseState(); // clears shared counters + stops coroutines ResetBaseState();
_state = TfGameState.Idle; _state = TfGameState.Idle;
_progress = 0; _progress = 0;
_questions = null; _questions = null;
...@@ -147,7 +148,6 @@ namespace com.al_arcade.tf ...@@ -147,7 +148,6 @@ namespace com.al_arcade.tf
} }
// ─── Timer feedback override ────────────────────────────────────────── // ─── Timer feedback override ──────────────────────────────────────────
// TF adjusts time on correct/wrong, so it needs direct access
public float GetTimeLeft() => _timeLeft; public float GetTimeLeft() => _timeLeft;
// ─── Game loop ──────────────────────────────────────────────────────── // ─── Game loop ────────────────────────────────────────────────────────
...@@ -186,7 +186,7 @@ namespace com.al_arcade.tf ...@@ -186,7 +186,7 @@ namespace com.al_arcade.tf
_correctCount++; _correctCount++;
_streak++; _streak++;
_progress++; _progress++;
_score += CalculateStreakScore(); // shared helper _score += CalculateStreakScore();
if (handController != null) handController.PlayCorrectFeedback(playerSaidTrue); if (handController != null) handController.PlayCorrectFeedback(playerSaidTrue);
if (productionLine != null) yield return productionLine.MoveForward(stepDistance); if (productionLine != null) yield return productionLine.MoveForward(stepDistance);
...@@ -200,7 +200,7 @@ namespace com.al_arcade.tf ...@@ -200,7 +200,7 @@ namespace com.al_arcade.tf
if (particles != null) if (particles != null)
particles.PlayCorrectBurst(new Vector3(-2, 6f, 13)); particles.PlayCorrectBurst(new Vector3(-2, 6f, 13));
UpdateTimerBy(4f); // shared helper UpdateTimerBy(4f);
uiManager?.UpdateTimer(_timeLeft, true); uiManager?.UpdateTimer(_timeLeft, true);
} }
else else
...@@ -224,7 +224,7 @@ namespace com.al_arcade.tf ...@@ -224,7 +224,7 @@ namespace com.al_arcade.tf
.SetEase(Ease.OutQuad).SetId("camShake"); .SetEase(Ease.OutQuad).SetId("camShake");
} }
UpdateTimerBy(-2f); // shared helper UpdateTimerBy(-2f);
uiManager?.UpdateTimer(_timeLeft, false); uiManager?.UpdateTimer(_timeLeft, false);
} }
...@@ -235,6 +235,8 @@ namespace com.al_arcade.tf ...@@ -235,6 +235,8 @@ namespace com.al_arcade.tf
{ {
uiManager.SetProgress(_progress, stepsToWin); uiManager.SetProgress(_progress, stepsToWin);
uiManager.SetStreak(_streak); uiManager.SetStreak(_streak);
// ✅ NEW: update points dots
uiManager.TickPoints(_progress);
} }
yield return new WaitForSeconds(feedbackDuration); yield return new WaitForSeconds(feedbackDuration);
...@@ -288,7 +290,6 @@ namespace com.al_arcade.tf ...@@ -288,7 +290,6 @@ namespace com.al_arcade.tf
protected override IEnumerator NoChallengeVictorySequence() protected override IEnumerator NoChallengeVictorySequence()
{ {
yield return new WaitForSeconds(1.5f); yield return new WaitForSeconds(1.5f);
uiManager?.ShowResults(_score, _correctCount, _wrongCount, true); uiManager?.ShowResults(_score, _correctCount, _wrongCount, true);
onGameComplete?.Invoke(); onGameComplete?.Invoke();
} }
......
...@@ -8,6 +8,7 @@ namespace com.al_arcade.tf ...@@ -8,6 +8,7 @@ namespace com.al_arcade.tf
{ {
using LightSide; using LightSide;
using shared; using shared;
using System.Collections.Generic;
using Unity.VisualScripting; using Unity.VisualScripting;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
...@@ -15,38 +16,60 @@ namespace com.al_arcade.tf ...@@ -15,38 +16,60 @@ namespace com.al_arcade.tf
{ {
[SerializeField] private Canvas _canvas; [SerializeField] private Canvas _canvas;
[SerializeField] private CanvasGroup _gameUI, _loadingUI, _errorUI, _resultsUI; [SerializeField] private CanvasGroup _gameUI, _loadingUI, _errorUI, _resultsUI;
[SerializeField] private UniText _scoreText, _streakText , _scoreLbl; [SerializeField] private UniText _scoreText, _streakText, _scoreLbl;
[SerializeField] private ArabicTextMeshProUGUI _loadingText, _errorText; [SerializeField] private ArabicTextMeshProUGUI _loadingText, _errorText;
[SerializeField] private UniText _progressLabel; [SerializeField] private UniText _progressLabel;
[SerializeField] private UniText _resultTitle, _resultScore, _resultStats; [SerializeField] private UniText _resultTitle, _resultScore, _resultStats;
[SerializeField] private Button _restartButton; [SerializeField] private Button _restartButton;
[SerializeField] protected Button _returnToHomeButton; [SerializeField] protected Button _returnToHomeButton;
[Header("Timer UI")]
[SerializeField] private Slider _timerSlider; [SerializeField] private Slider _timerSlider;
[SerializeField] private Image _timerFill; [SerializeField] private Image _timerFill;
[SerializeField] private UniText _timerText; [SerializeField] private UniText _timerText;
[SerializeField] private float _maxTime = 30; [SerializeField] private float _maxTime = 30;
private bool _isTweening; // ✅ NEW: CS-style points dots
private Color _timerDefaultColor; [Header("Points UI")]
[SerializeField] private Transform _pointsContainer;
[SerializeField] private Color _activePointColor;
[SerializeField] private Color _inactivePointColor;
[Header("Events")] [Header("Events")]
public UnityEvent onRestartClicked; public UnityEvent onRestartClicked;
private bool _isTweening;
private Color _timerDefaultColor;
// ✅ NEW: cached point images
private List<Image> _pointImages = new();
private void Start() private void Start()
{ {
_restartButton.onClick.AddListener(RestartButton); _restartButton.onClick.AddListener(RestartButton);
if (_timerFill != null) if (_timerFill != null)
_timerDefaultColor = _timerFill.color; _timerDefaultColor = _timerFill.color;
_returnToHomeButton.onClick.AddListener(() => _returnToHomeButton.onClick.AddListener(() =>
{ {
SceneManager.LoadScene("MainMenu"); SceneManager.LoadScene("MainMenu");
}); });
// ✅ NEW: build points images list from container children
if (_pointsContainer != null)
{
_pointImages.Clear();
foreach (Transform child in _pointsContainer)
{
var img = child.GetComponent<Image>();
if (img != null) _pointImages.Add(img);
}
}
} }
// --- ADDED: Basic timer update (called every frame from GameManager) ---
// ─── Timer UI ─────────────────────────────────────────────────────────
public void SetTimer(float time) public void SetTimer(float time)
{ {
if (_isTweening) return; if (_isTweening) return;
...@@ -62,7 +85,7 @@ namespace com.al_arcade.tf ...@@ -62,7 +85,7 @@ namespace com.al_arcade.tf
? _timerDefaultColor ? _timerDefaultColor
: SSColorPalette.Danger; : SSColorPalette.Danger;
} }
// --- ADDED: Animated timer feedback (bonus or penalty) ---
public void UpdateTimer(float time, bool positive) public void UpdateTimer(float time, bool positive)
{ {
if (_timerSlider == null || _timerFill == null) return; if (_timerSlider == null || _timerFill == null) return;
...@@ -73,13 +96,12 @@ namespace com.al_arcade.tf ...@@ -73,13 +96,12 @@ namespace com.al_arcade.tf
_timerSlider.transform.DOPunchScale(Vector3.one * 0.1f, 0.3f, 8, 0.3f); _timerSlider.transform.DOPunchScale(Vector3.one * 0.1f, 0.3f, 8, 0.3f);
// Color tween owns the _isTweening flag — NOT the slider
_timerFill _timerFill
.DOColor(flashColor, 0.2f) .DOColor(flashColor, 0.2f)
.OnComplete(() => .OnComplete(() =>
{ {
_timerFill.DOColor(_timerDefaultColor, 0.2f) _timerFill.DOColor(_timerDefaultColor, 0.2f)
.OnComplete(() => _isTweening = false); // ← moved here .OnComplete(() => _isTweening = false);
}); });
float targetTime = !positive ? time - 0.3f : time; float targetTime = !positive ? time - 0.3f : time;
...@@ -87,41 +109,157 @@ namespace com.al_arcade.tf ...@@ -87,41 +109,157 @@ namespace com.al_arcade.tf
_timerSlider _timerSlider
.DOValue(Mathf.Min(targetTime / _maxTime, _maxTime), 0.3f) .DOValue(Mathf.Min(targetTime / _maxTime, _maxTime), 0.3f)
.SetEase(Ease.OutQuad); .SetEase(Ease.OutQuad);
// ← removed OnComplete here
} }
void RestartButton()
// ─── Points dots UI ───────────────────────────────────────────────────
// ✅ NEW: fill dots based on current _progress value
public void TickPoints(int count)
{ {
TfGameManager.Instance.ResetGame(); for (int i = 0; i < _pointImages.Count; i++)
TfGameManager.Instance.StartGame(); {
var img = _pointImages[i];
if (i < count)
{
img.color = _activePointColor;
img.transform.DOPunchScale(Vector3.one * 0.4f, 0.4f)
.SetEase(Ease.OutElastic)
.SetDelay(0.1f * i);
}
else
{
img.color = SSColorPalette.WithAlpha(_inactivePointColor, 0.3f);
img.transform.localScale = Vector3.one;
}
}
} }
public void BuildUI() // ─── Game UI ──────────────────────────────────────────────────────────
public void BuildUI() { }
public void ShowGameUI()
{ {
var co = new GameObject("TfCanvas"); _gameUI.gameObject.SetActive(true);
co.transform.SetParent(transform); _gameUI.DOFade(1, 0.3f);
}
_canvas = co.AddComponent<Canvas>(); public void SetScore(int s)
_canvas.renderMode = RenderMode.ScreenSpaceOverlay; {
_canvas.sortingOrder = 100; if (_scoreText == null) return;
_scoreText.Text = s.ToString("N0");
DOTween.Kill(_scoreText.transform, "sp");
_scoreText.transform
.DOPunchScale(Vector3.one * 0.12f, 0.2f, 4, 0.2f)
.SetId("sp");
}
var sc = co.AddComponent<CanvasScaler>(); public void EnableScore(bool value)
sc.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; {
sc.referenceResolution = new Vector2(1920, 1080); _scoreText.enabled = value;
sc.matchWidthOrHeight = 0.5f; _scoreLbl.enabled = value;
_scoreLbl.Text = value ? "الوقت الموفر" : "النقاط";
}
co.AddComponent<GraphicRaycaster>(); public void SetStreak(int s)
{
if (_streakText == null) return;
_streakText.Text = s > 1 ? "🔥 × " + s : "";
if (s > 1)
{
DOTween.Kill(_streakText.transform, "sk");
_streakText.transform.localScale = Vector3.one * 1.4f;
_streakText.transform
.DOScale(1f, 0.35f)
.SetEase(Ease.OutElastic)
.SetId("sk");
}
}
BuildGameHUD(co.transform); public void SetProgress(int cur, int total)
BuildLoadingPanel(co.transform); {
BuildErrorPanel(co.transform); if (_progressLabel != null)
BuildResultsPanel(co.transform); _progressLabel.Text = $"{cur} / {total}";
}
// ─── Loading / Error ──────────────────────────────────────────────────
public void ShowLoading(string m)
{
_loadingUI.gameObject.SetActive(true);
if (_loadingText != null) _loadingText.arabicText = m;
_loadingUI.DOFade(1, 0.3f);
}
_gameUI.alpha = 0; _gameUI.gameObject.SetActive(false); public void HideLoading()
_loadingUI.alpha = 0; _loadingUI.gameObject.SetActive(false); {
_errorUI.alpha = 0; _errorUI.gameObject.SetActive(false); _loadingUI.DOFade(0, 0.3f)
_resultsUI.alpha = 0; _resultsUI.gameObject.SetActive(false); .OnComplete(() => _loadingUI.gameObject.SetActive(false));
} }
public void ShowError(string m)
{
_errorUI.gameObject.SetActive(true);
if (_errorText != null) _errorText.arabicText = m;
_errorUI.DOFade(1, 0.3f);
}
// ─── Results ──────────────────────────────────────────────────────────
public void ShowResults(int score, int correct, int wrong, bool won)
{
_resultsUI.gameObject.SetActive(true);
_resultsUI.alpha = 0;
if (_resultTitle != null) _resultTitle.Text = won ? "نجحت المهمة" : "حاول مجدداً";
if (_resultScore != null) _resultScore.Text = score.ToString("N0");
if (_resultStats != null) _resultStats.Text = $"صح: {correct} | خطأ: {wrong}";
var seq = DOTween.Sequence();
seq.Append(_resultsUI.DOFade(1, 0.4f));
}
public void HideResults()
{
_resultsUI.DOFade(0f, 0.3f)
.OnComplete(() => _resultsUI.gameObject.SetActive(false));
}
// ─── Reset ────────────────────────────────────────────────────────────
public void ResetUI()
{
if (_gameUI != null) _gameUI.gameObject.SetActive(false);
if (_loadingUI != null) _loadingUI.gameObject.SetActive(false);
if (_errorUI != null) _errorUI.gameObject.SetActive(false);
if (_resultsUI != null) _resultsUI.gameObject.SetActive(false);
if (_timerSlider != null) _timerSlider.value = 1f;
if (_timerFill != null) _timerFill.color = _timerDefaultColor;
// ✅ NEW: reset all dots to inactive
TickPoints(0);
_isTweening = false;
SetStreak(0);
_scoreLbl.enabled = false;
}
// ─── Button functions ─────────────────────────────────────────────────
void RestartButton()
{
TfGameManager.Instance.ResetGame();
TfGameManager.Instance.StartGame();
}
public void BackToMenuButtonFunction()
{
SceneManager.LoadScene("MainMenu");
}
// ─── Builder (procedural UI) ──────────────────────────────────────────
private void BuildGameHUD(Transform parent) private void BuildGameHUD(Transform parent)
{ {
var go = MkPanel(parent, "GameUI"); var go = MkPanel(parent, "GameUI");
...@@ -141,42 +279,11 @@ namespace com.al_arcade.tf ...@@ -141,42 +279,11 @@ namespace com.al_arcade.tf
SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.82f); SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.82f);
var scoreLbl = MkTxt( var scoreLbl = MkTxt(
topBarObj.transform, topBarObj.transform, "ScoreLbl", "نقاط", 14,
"ScoreLbl", new Vector2(0, 0.5f), new Vector2(36, -20), new Vector2(100, 22));
"نقاط",
14,
new Vector2(0, 0.5f),
new Vector2(36, -20),
new Vector2(100, 22)
);
scoreLbl.color = SSColorPalette.WithAlpha(Color.white, 0.5f); scoreLbl.color = SSColorPalette.WithAlpha(Color.white, 0.5f);
scoreLbl.alignment = TMPro.TextAlignmentOptions.MidlineLeft; scoreLbl.alignment = TMPro.TextAlignmentOptions.MidlineLeft;
var progBg = new GameObject("ProgressBg");
progBg.transform.SetParent(go.transform, false);
var pr = progBg.AddComponent<RectTransform>();
pr.anchorMin = new Vector2(0.28f, 1);
pr.anchorMax = new Vector2(0.72f, 1);
pr.pivot = new Vector2(0.5f, 1);
pr.anchoredPosition = new Vector2(0, -78);
pr.sizeDelta = new Vector2(0, 14);
progBg.AddComponent<Image>().color =
SSColorPalette.WithAlpha(Color.white, 0.08f);
var fill = new GameObject("Fill");
fill.transform.SetParent(progBg.transform, false);
var fr = fill.AddComponent<RectTransform>();
fr.anchorMin = Vector2.zero;
fr.anchorMax = new Vector2(0, 1);
fr.pivot = new Vector2(0, 0.5f);
fr.offsetMin = Vector2.zero;
fr.offsetMax = Vector2.zero;
var hintObj = new GameObject("HintBg"); var hintObj = new GameObject("HintBg");
hintObj.transform.SetParent(go.transform, false); hintObj.transform.SetParent(go.transform, false);
...@@ -191,15 +298,8 @@ namespace com.al_arcade.tf ...@@ -191,15 +298,8 @@ namespace com.al_arcade.tf
SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.6f); SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.6f);
var hint = MkTxt( var hint = MkTxt(
hintObj.transform, hintObj.transform, "Hint", "يسار | يمين", 18,
"Hint", new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(480, 36));
"يسار | يمين",
18,
new Vector2(0.5f, 0.5f),
Vector2.zero,
new Vector2(480, 36)
);
hint.alignment = TMPro.TextAlignmentOptions.Center; hint.alignment = TMPro.TextAlignmentOptions.Center;
hint.color = SSColorPalette.WithAlpha(Color.white, 0.5f); hint.color = SSColorPalette.WithAlpha(Color.white, 0.5f);
} }
...@@ -208,55 +308,24 @@ namespace com.al_arcade.tf ...@@ -208,55 +308,24 @@ namespace com.al_arcade.tf
{ {
var go = MkPanel(parent, "LoadingUI"); var go = MkPanel(parent, "LoadingUI");
_loadingUI = go.AddComponent<CanvasGroup>(); _loadingUI = go.AddComponent<CanvasGroup>();
go.AddComponent<Image>().color = go.AddComponent<Image>().color =
SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.9f); SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.9f);
_loadingText = MkTxt( _loadingText = MkTxt(go.transform, "Txt", "جار التحميل...", 28,
go.transform, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(500, 50));
"Txt",
"جار التحميل...",
28,
new Vector2(0.5f, 0.5f),
Vector2.zero,
new Vector2(500, 50)
);
_loadingText.alignment = TMPro.TextAlignmentOptions.Center; _loadingText.alignment = TMPro.TextAlignmentOptions.Center;
_loadingText.color = Color.white; _loadingText.color = Color.white;
var dots = MkTxt(
go.transform,
"Dots",
". . .",
18,
new Vector2(0.5f, 0.5f),
new Vector2(0, -36),
new Vector2(200, 30)
);
dots.alignment = TMPro.TextAlignmentOptions.Center;
dots.color = SSColorPalette.Accent;
} }
private void BuildErrorPanel(Transform parent) private void BuildErrorPanel(Transform parent)
{ {
var go = MkPanel(parent, "ErrorUI"); var go = MkPanel(parent, "ErrorUI");
_errorUI = go.AddComponent<CanvasGroup>(); _errorUI = go.AddComponent<CanvasGroup>();
go.AddComponent<Image>().color = go.AddComponent<Image>().color =
SSColorPalette.WithAlpha(SSColorPalette.Danger, 0.9f); SSColorPalette.WithAlpha(SSColorPalette.Danger, 0.9f);
_errorText = MkTxt( _errorText = MkTxt(go.transform, "Txt", "خطأ", 24,
go.transform, new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(600, 90));
"Txt",
"خطأ",
24,
new Vector2(0.5f, 0.5f),
Vector2.zero,
new Vector2(600, 90)
);
_errorText.alignment = TMPro.TextAlignmentOptions.Center; _errorText.alignment = TMPro.TextAlignmentOptions.Center;
_errorText.color = Color.white; _errorText.color = Color.white;
_errorText.enableWordWrapping = true; _errorText.enableWordWrapping = true;
...@@ -266,9 +335,8 @@ namespace com.al_arcade.tf ...@@ -266,9 +335,8 @@ namespace com.al_arcade.tf
{ {
var go = MkPanel(parent, "ResultsUI"); var go = MkPanel(parent, "ResultsUI");
_resultsUI = go.AddComponent<CanvasGroup>(); _resultsUI = go.AddComponent<CanvasGroup>();
go.AddComponent<Image>().color =
var bg = go.AddComponent<Image>(); SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.94f);
bg.color = SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.94f);
var card = new GameObject("Card"); var card = new GameObject("Card");
card.transform.SetParent(go.transform, false); card.transform.SetParent(go.transform, false);
...@@ -298,20 +366,11 @@ namespace com.al_arcade.tf ...@@ -298,20 +366,11 @@ namespace com.al_arcade.tf
{ {
_resultsUI.DOFade(0, 0.3f) _resultsUI.DOFade(0, 0.3f)
.OnComplete(() => _resultsUI.gameObject.SetActive(false)); .OnComplete(() => _resultsUI.gameObject.SetActive(false));
onRestartClicked?.Invoke(); onRestartClicked?.Invoke();
}); });
var btnTxt = MkTxt( var btnTxt = MkTxt(btnObj.transform, "BtnTxt", "إعادة البداية", 22,
btnObj.transform, Vector2.zero, Vector2.zero, Vector2.zero);
"BtnTxt",
"إعادة البداية",
22,
Vector2.zero,
Vector2.zero,
Vector2.zero
);
btnTxt.rectTransform.anchorMin = Vector2.zero; btnTxt.rectTransform.anchorMin = Vector2.zero;
btnTxt.rectTransform.anchorMax = Vector2.one; btnTxt.rectTransform.anchorMax = Vector2.one;
btnTxt.rectTransform.offsetMin = btnTxt.rectTransform.offsetMax = Vector2.zero; btnTxt.rectTransform.offsetMin = btnTxt.rectTransform.offsetMax = Vector2.zero;
...@@ -320,163 +379,33 @@ namespace com.al_arcade.tf ...@@ -320,163 +379,33 @@ namespace com.al_arcade.tf
btnTxt.fontStyle = TMPro.FontStyles.Bold; btnTxt.fontStyle = TMPro.FontStyles.Bold;
} }
public void ShowGameUI()
{
_gameUI.gameObject.SetActive(true);
_gameUI.DOFade(1, 0.3f);
}
public void SetScore(int s)
{
if (_scoreText == null) return;
_scoreText.Text = s.ToString("N0");
DOTween.Kill(_scoreText.transform, "sp");
_scoreText.transform
.DOPunchScale(Vector3.one * 0.12f, 0.2f, 4, 0.2f)
.SetId("sp");
}
public void EnableScore(bool value)
{
_scoreText.enabled = value;
_scoreLbl.enabled = value;
if (value)
{
_scoreLbl.Text = "الوقت الموفر";
}
else
{
_scoreLbl.Text = "النقاط";
}
}
public void SetStreak(int s)
{
if (_streakText == null) return;
_streakText.Text = s > 1 ? "🔥 × " + s : "";
if (s > 1)
{
DOTween.Kill(_streakText.transform, "sk");
_streakText.transform.localScale = Vector3.one * 1.4f;
_streakText.transform
.DOScale(1f, 0.35f)
.SetEase(Ease.OutElastic)
.SetId("sk");
}
}
public void SetProgress(int cur, int total)
{
if (_progressLabel != null)
_progressLabel.Text = $"{cur} / {total}";
}
public void ShowLoading(string m)
{
_loadingUI.gameObject.SetActive(true);
if (_loadingText != null)
_loadingText.arabicText = m;
_loadingUI.DOFade(1, 0.3f);
}
public void HideLoading()
{
_loadingUI.DOFade(0, 0.3f)
.OnComplete(() => _loadingUI.gameObject.SetActive(false));
}
public void ShowError(string m)
{
_errorUI.gameObject.SetActive(true);
if (_errorText != null)
_errorText.arabicText = m;
_errorUI.DOFade(1, 0.3f);
}
public void ShowResults(int score, int correct, int wrong, bool won)
{
_resultsUI.gameObject.SetActive(true);
_resultsUI.alpha = 0;
if (_resultTitle != null)
_resultTitle.Text = won ? "نجحت المهمة" : "حاول مجدداً";
if (_resultScore != null)
_resultScore.Text = score.ToString("N0");
if (_resultStats != null)
_resultStats.Text = $"صح: {correct} | خطأ: {wrong}";
var seq = DOTween.Sequence();
seq.Append(_resultsUI.DOFade(1, 0.4f));
}
public void ResetUI()
{
if (_gameUI != null) _gameUI.gameObject.SetActive(false);
if (_loadingUI != null) _loadingUI.gameObject.SetActive(false);
if (_errorUI != null) _errorUI.gameObject.SetActive(false);
if (_resultsUI != null) _resultsUI.gameObject.SetActive(false);
// --- ADDED: Reset timer UI ---
if (_timerSlider != null)
_timerSlider.value = 1f;
if (_timerFill != null)
_timerFill.color = _timerDefaultColor;
_isTweening = false;
_scoreLbl.enabled = false;
}
private GameObject MkPanel(Transform p, string n) private GameObject MkPanel(Transform p, string n)
{ {
var go = new GameObject(n); var go = new GameObject(n);
go.transform.SetParent(p, false); go.transform.SetParent(p, false);
var r = go.AddComponent<RectTransform>(); var r = go.AddComponent<RectTransform>();
r.anchorMin = Vector2.zero; r.anchorMin = Vector2.zero;
r.anchorMax = Vector2.one; r.anchorMax = Vector2.one;
r.sizeDelta = Vector2.zero; r.sizeDelta = Vector2.zero;
return go; return go;
} }
private ArabicTextMeshProUGUI MkTxt( private ArabicTextMeshProUGUI MkTxt(
Transform p, Transform p, string n, string text, float size,
string n, Vector2 anchor, Vector2 pos, Vector2 sz)
string text,
float size,
Vector2 anchor,
Vector2 pos,
Vector2 sz)
{ {
var go = new GameObject(n); var go = new GameObject(n);
go.transform.SetParent(p, false); go.transform.SetParent(p, false);
var r = go.AddComponent<RectTransform>(); var r = go.AddComponent<RectTransform>();
r.anchorMin = r.anchorMax = anchor; r.anchorMin = r.anchorMax = anchor;
r.pivot = anchor; r.pivot = anchor;
r.anchoredPosition = pos; r.anchoredPosition = pos;
r.sizeDelta = sz; r.sizeDelta = sz;
var t = go.AddComponent<ArabicTextMeshProUGUI>(); var t = go.AddComponent<ArabicTextMeshProUGUI>();
t.arabicText = text; t.arabicText = text;
t.fontSize = size; t.fontSize = size;
t.enableWordWrapping = true; t.enableWordWrapping = true;
SSFontManager.Apply(t); SSFontManager.Apply(t);
return t; return t;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment