starOfWords/Assets/Scripts/2.0/LLGameScene.cs
portakal ecb1c9edea Initial commit: Star of Words Unity project
Snapshot of the existing Unity 6 language-learning word game before any
refactoring. Adds Unity .gitignore and .gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 15:31:20 +03:00

1134 lines
No EOL
31 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using System.Collections;
public class LLGameScene : MonoBehaviour
{
[Header("━━━ 20 LEVEL TXT DOSYALARI ━━━━━━━━━━━━")]
public TextAsset[] wordFiles = new TextAsset[20];
[Header("━━━ UI ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public TMP_Text questionText;
public Button[] answerButtons;
public TMP_Text[] answerTexts;
public TMP_Text feedbackText;
public Button submitButton;
public TMP_Text scoreText;
public TMP_Text comboText;
public TMP_Text timerText;
[Header("━━━ EXTRA BUTONLAR ━━━━━━━━━━━━━━━━━━━━")]
public Button extraTimeButton;
public Button extraHintButton;
public Button extraSkipButton;
public TMP_Text extraTimeCooldownText;
public TMP_Text extraHintCooldownText;
public TMP_Text extraSkipCooldownText;
[Header("━━━ BACK BUTONU ━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "ModSec 2";
[Header("━━━ RESULT SAHNESİ ━━━━━━━━━━━━━━━━━━━━")]
public string resultSceneName = "ResultSceneLL";
[Header("━━━ GAME SETTINGS ━━━━━━━━━━━━━━━━━━━━━")]
public float startTime = 60f;
public int basePoints = 50;
public int wrongPenalty = 50;
public float correctTimeBonus = 2f;
[Header("━━━ COMBO ÇARPANLARI ━━━━━━━━━━━━━━━━━")]
public float mult_1to2 = 1f;
public float mult_3to4 = 1.15f;
public float mult_5to7 = 1.3f;
public float mult_8plus = 1.5f;
[Header("━━━ RENK AYARLARI ━━━━━━━━━━━━━━━━━━━━━")]
public Color normalButtonColor = new Color32(120, 70, 220, 255);
public Color selectedButtonColor = new Color32(155, 105, 255, 255);
public Color correctButtonColor = new Color32(70, 240, 130, 255);
public Color wrongButtonColor = new Color32(255, 80, 95, 255);
public Color disabledButtonColor = new Color32(90, 75, 120, 255);
[Header("━━━ BUTON TASARIM AYARI ━━━━━━━━━━━━━━")]
public bool butonRenginiKoru = true;
[Header("━━━ FEEDBACK YAZISI AYARLARI ━━━━━━━━━")]
public bool feedbackUsteAl = true;
public float feedbackTopY = 320f;
public float feedbackFontSize = 46f;
[Header("━━━ ANİMASYON AYARLARI ━━━━━━━━━━━━━━━━")]
[Range(0.80f, 1f)] public float selectedScale = 0.94f;
public float selectAnimTime = 0.10f;
public float enterAnimTime = 0.22f;
public float nextQuestionDelay = 1.15f;
float timeLeft;
bool gameOver = false;
bool waitingNextQuestion = false;
bool extraTimeReady = true;
bool extraHintReady = true;
bool extraSkipReady = true;
int correctAnswerIndex;
int selectedAnswer = -1;
int score = 0;
int combo = 0;
int correctCount = 0;
int wrongCount = 0;
readonly List<WordPair> wordPool = new List<WordPair>();
string questionLang;
string answerLang;
int wordIndex = 0;
Vector3[] originalButtonScales;
Vector3[] originalButtonPositions;
Coroutine[] buttonScaleCoroutines;
Coroutine[] buttonEnterCoroutines;
Color timerNormalColor = Color.white;
readonly Color timerWarnColor = new Color32(255, 80, 80, 255);
void Awake()
{
LoadWords();
}
void Start()
{
questionLang = PlayerPrefs.GetString("QuestionLangCode", "en");
answerLang = PlayerPrefs.GetString("AnswerLangCode", "tr");
timeLeft = PlayerPrefs.GetFloat("SelectedGameTime", startTime);
if (timeLeft <= 0) timeLeft = startTime;
if (wordPool.Count < 4)
{
Debug.LogError("LLGameScene kelime sayısı yetersiz! En az 4 kelime olmalı.");
return;
}
HideCooldownTexts();
CacheButtonData();
ForceButtonTransitionNone();
PrepareFeedbackText();
BindMainButtons();
Shuffle(wordPool);
UpdateScore();
UpdateCombo();
UpdateTimerUI();
NextQuestion();
}
void Update()
{
if (gameOver) return;
timeLeft -= Time.deltaTime;
if (timeLeft <= 0)
{
timeLeft = 0;
UpdateTimerUI();
GameOver();
return;
}
UpdateTimerUI();
}
void LoadWords()
{
wordPool.Clear();
int selectedLevel = PlayerPrefs.GetInt("SelectedLevel", 1);
selectedLevel = Mathf.Clamp(selectedLevel, 1, wordFiles.Length);
TextAsset file = wordFiles[selectedLevel - 1];
if (file == null)
{
Debug.LogError($"Level {selectedLevel} TXT atanmadı!");
return;
}
string[] lines = file.text.Split(new[] { '\n', '\r' }, System.StringSplitOptions.RemoveEmptyEntries);
foreach (string raw in lines)
{
string line = raw.Trim();
if (string.IsNullOrWhiteSpace(line)) continue;
string[] p = line.Split(',');
if (p.Length < 6)
{
Debug.LogWarning("Eksik kelime satırı atlandı: " + line);
continue;
}
wordPool.Add(new WordPair(
p[0].Trim(),
p[1].Trim(),
p[2].Trim(),
p[3].Trim(),
p[4].Trim(),
p[5].Trim()
));
}
Debug.Log($"Level {selectedLevel} yüklendi. Kelime: {wordPool.Count}");
}
void HideCooldownTexts()
{
if (extraTimeCooldownText != null) extraTimeCooldownText.gameObject.SetActive(false);
if (extraHintCooldownText != null) extraHintCooldownText.gameObject.SetActive(false);
if (extraSkipCooldownText != null) extraSkipCooldownText.gameObject.SetActive(false);
}
void BindMainButtons()
{
if (submitButton != null)
{
submitButton.onClick.RemoveAllListeners();
submitButton.onClick.AddListener(OnSubmit);
}
if (extraTimeButton != null)
{
extraTimeButton.onClick.RemoveAllListeners();
extraTimeButton.onClick.AddListener(OnExtraTime);
}
if (extraHintButton != null)
{
extraHintButton.onClick.RemoveAllListeners();
extraHintButton.onClick.AddListener(OnExtraHint);
}
if (extraSkipButton != null)
{
extraSkipButton.onClick.RemoveAllListeners();
extraSkipButton.onClick.AddListener(OnExtraSkip);
}
if (backButton != null)
{
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(() => SceneManager.LoadScene(backSceneName));
}
}
void CacheButtonData()
{
if (answerButtons == null) return;
originalButtonScales = new Vector3[answerButtons.Length];
originalButtonPositions = new Vector3[answerButtons.Length];
buttonScaleCoroutines = new Coroutine[answerButtons.Length];
buttonEnterCoroutines = new Coroutine[answerButtons.Length];
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
originalButtonScales[i] = answerButtons[i].transform.localScale;
originalButtonPositions[i] = answerButtons[i].transform.localPosition;
}
}
void ForceButtonTransitionNone()
{
if (answerButtons == null) return;
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
answerButtons[i].transition = Selectable.Transition.None;
Image img = answerButtons[i].image;
if (img != null)
img.color = FullAlpha(normalButtonColor);
CanvasGroup cg = answerButtons[i].GetComponent<CanvasGroup>();
if (cg != null)
{
cg.alpha = 1f;
cg.interactable = true;
cg.blocksRaycasts = true;
}
}
}
void PrepareFeedbackText()
{
if (feedbackText == null) return;
if (feedbackUsteAl)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
feedbackText.alignment = TextAlignmentOptions.Center;
feedbackText.fontSize = Mathf.Max(feedbackText.fontSize, feedbackFontSize);
feedbackText.text = "";
Color c = feedbackText.color;
c.a = 1f;
feedbackText.color = c;
}
void NextQuestion()
{
if (gameOver) return;
if (wordPool.Count < 4) return;
waitingNextQuestion = false;
selectedAnswer = -1;
ResetButtons();
if (wordIndex >= wordPool.Count)
{
wordIndex = 0;
Shuffle(wordPool);
}
WordPair chosen = wordPool[wordIndex++];
if (questionText != null)
{
questionText.text = chosen.GetByCode(questionLang);
StartCoroutine(FadeInText(questionText));
}
correctAnswerIndex = Random.Range(0, 4);
if (answerTexts == null || answerTexts.Length < 4)
{
Debug.LogError("answerTexts en az 4 eleman olmalı.");
return;
}
answerTexts[correctAnswerIndex].text = chosen.GetByCode(answerLang);
List<WordPair> wrongPool = new List<WordPair>(wordPool);
wrongPool.Remove(chosen);
Shuffle(wrongPool);
int wrongIndex = 0;
for (int i = 0; i < 4; i++)
{
if (i == correctAnswerIndex) continue;
if (wrongIndex < wrongPool.Count)
{
answerTexts[i].text = wrongPool[wrongIndex].GetByCode(answerLang);
wrongIndex++;
}
}
BindAnswerButtons();
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
if (buttonEnterCoroutines[i] != null)
StopCoroutine(buttonEnterCoroutines[i]);
buttonEnterCoroutines[i] = StartCoroutine(ButtonEnterAnim(answerButtons[i], i));
}
}
void BindAnswerButtons()
{
if (answerButtons == null) return;
for (int i = 0; i < answerButtons.Length; i++)
{
int index = i;
if (answerButtons[i] == null) continue;
answerButtons[i].onClick.RemoveAllListeners();
answerButtons[i].onClick.AddListener(() => SelectAnswer(index));
}
}
void ResetButtons()
{
if (answerButtons == null) return;
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
StopButtonCoroutines(i);
answerButtons[i].interactable = true;
answerButtons[i].transition = Selectable.Transition.None;
Image img = answerButtons[i].image;
if (img != null)
img.color = FullAlpha(normalButtonColor);
answerButtons[i].transform.localScale = originalButtonScales[i];
answerButtons[i].transform.localPosition = originalButtonPositions[i];
CanvasGroup cg = answerButtons[i].GetComponent<CanvasGroup>();
if (cg != null)
{
cg.alpha = 1f;
cg.interactable = true;
cg.blocksRaycasts = true;
}
}
if (feedbackText != null)
feedbackText.text = "";
if (submitButton != null)
submitButton.interactable = true;
}
void SelectAnswer(int index)
{
if (gameOver || waitingNextQuestion) return;
if (answerButtons == null) return;
if (index < 0 || index >= answerButtons.Length) return;
if (answerButtons[index] == null) return;
if (selectedAnswer == index)
return;
if (selectedAnswer >= 0 && selectedAnswer < answerButtons.Length)
{
Button oldButton = answerButtons[selectedAnswer];
if (oldButton != null)
{
Image oldImg = oldButton.image;
if (oldImg != null)
oldImg.color = FullAlpha(normalButtonColor);
StartScaleAnim(selectedAnswer, originalButtonScales[selectedAnswer]);
}
}
selectedAnswer = index;
Image img = answerButtons[index].image;
if (img != null)
img.color = FullAlpha(selectedButtonColor);
CanvasGroup cg = answerButtons[index].GetComponent<CanvasGroup>();
if (cg != null)
cg.alpha = 1f;
StartScaleAnim(index, originalButtonScales[index] * selectedScale);
}
void OnSubmit()
{
if (gameOver || waitingNextQuestion) return;
if (selectedAnswer == -1) return;
if (answerButtons == null) return;
waitingNextQuestion = true;
if (submitButton != null)
submitButton.interactable = false;
bool correct = selectedAnswer == correctAnswerIndex;
LockAnswerButtons();
if (correct)
HandleCorrectAnswer();
else
HandleWrongAnswer();
UpdateScore();
UpdateCombo();
StartCoroutine(DelayNext());
}
void LockAnswerButtons()
{
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
answerButtons[i].interactable = false;
CanvasGroup cg = answerButtons[i].GetComponent<CanvasGroup>();
if (cg != null)
cg.alpha = 1f;
if (i != selectedAnswer && i != correctAnswerIndex)
{
Image img = answerButtons[i].image;
if (img != null)
img.color = FullAlpha(normalButtonColor);
}
}
}
void HandleCorrectAnswer()
{
Button selectedButton = answerButtons[selectedAnswer];
if (selectedButton != null)
{
Image img = selectedButton.image;
if (img != null)
{
if (butonRenginiKoru)
img.color = FullAlpha(selectedButtonColor);
else
img.color = FullAlpha(correctButtonColor);
}
StartCoroutine(CorrectPulse(selectedButton, selectedAnswer));
}
combo++;
correctCount++;
int addScore = Mathf.RoundToInt(basePoints * GetComboMultiplier(combo));
score += addScore;
timeLeft += correctTimeBonus;
if (feedbackText != null)
{
feedbackText.color = FullAlpha(correctButtonColor);
feedbackText.text = combo >= 3 ? $"TRUE {combo}x COMBO!" : "TRUE ";
if (feedbackUsteAl)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
StartCoroutine(FeedbackAnim(feedbackText));
}
if (comboText != null) StartCoroutine(ComboAnim(comboText));
if (scoreText != null) StartCoroutine(ScorePopAnim(scoreText));
}
void HandleWrongAnswer()
{
Button selectedButton = answerButtons[selectedAnswer];
if (selectedButton != null)
{
Image selectedImg = selectedButton.image;
if (selectedImg != null)
{
if (butonRenginiKoru)
selectedImg.color = FullAlpha(selectedButtonColor);
else
selectedImg.color = FullAlpha(wrongButtonColor);
}
StartCoroutine(ShakeButton(selectedButton, selectedAnswer));
}
if (correctAnswerIndex >= 0 && correctAnswerIndex < answerButtons.Length)
{
Button correctButton = answerButtons[correctAnswerIndex];
if (correctButton != null)
{
Image correctImg = correctButton.image;
if (correctImg != null)
{
if (butonRenginiKoru)
correctImg.color = FullAlpha(normalButtonColor);
else
correctImg.color = FullAlpha(correctButtonColor);
}
StartScaleAnim(correctAnswerIndex, originalButtonScales[correctAnswerIndex] * 1.04f);
}
}
wrongCount++;
combo = 0;
score -= wrongPenalty;
if (score < 0) score = 0;
if (feedbackText != null)
{
feedbackText.color = FullAlpha(wrongButtonColor);
feedbackText.text = "FALSE";
if (feedbackUsteAl)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
StartCoroutine(FeedbackAnim(feedbackText));
}
}
IEnumerator DelayNext()
{
yield return new WaitForSeconds(nextQuestionDelay);
if (!gameOver)
NextQuestion();
}
void StartScaleAnim(int index, Vector3 targetScale)
{
if (index < 0 || index >= answerButtons.Length) return;
if (answerButtons[index] == null) return;
if (buttonScaleCoroutines[index] != null)
StopCoroutine(buttonScaleCoroutines[index]);
buttonScaleCoroutines[index] = StartCoroutine(ScaleButton(answerButtons[index], targetScale));
}
void StopButtonCoroutines(int index)
{
if (buttonScaleCoroutines != null && index < buttonScaleCoroutines.Length && buttonScaleCoroutines[index] != null)
{
StopCoroutine(buttonScaleCoroutines[index]);
buttonScaleCoroutines[index] = null;
}
if (buttonEnterCoroutines != null && index < buttonEnterCoroutines.Length && buttonEnterCoroutines[index] != null)
{
StopCoroutine(buttonEnterCoroutines[index]);
buttonEnterCoroutines[index] = null;
}
}
IEnumerator ScaleButton(Button btn, Vector3 targetScale)
{
if (btn == null) yield break;
Vector3 startScale = btn.transform.localScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, selectAnimTime);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = targetScale;
}
IEnumerator ButtonEnterAnim(Button btn, int delayIndex)
{
if (btn == null) yield break;
int idx = System.Array.IndexOf(answerButtons, btn);
if (idx < 0) yield break;
yield return new WaitForSeconds(delayIndex * 0.06f);
Vector3 targetPos = originalButtonPositions[idx];
Vector3 startPos = targetPos + Vector3.up * 35f;
Vector3 targetScale = originalButtonScales[idx];
Vector3 startScale = targetScale * 0.85f;
btn.transform.localPosition = startPos;
btn.transform.localScale = startScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, enterAnimTime);
float ease = EaseOutBack(t);
btn.transform.localPosition = Vector3.Lerp(startPos, targetPos, ease);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, ease);
yield return null;
}
btn.transform.localPosition = targetPos;
btn.transform.localScale = targetScale;
}
IEnumerator CorrectPulse(Button btn, int idx)
{
if (btn == null) yield break;
Vector3 normal = originalButtonScales[idx];
Vector3 big = normal * 1.12f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = normal;
}
IEnumerator ShakeButton(Button btn, int idx)
{
if (btn == null) yield break;
Vector3 origin = originalButtonPositions[idx];
float duration = 0.35f;
float magnitude = 12f;
float elapsed = 0f;
while (elapsed < duration)
{
float power = 1f - elapsed / duration;
float x = Random.Range(-1f, 1f) * magnitude * power;
btn.transform.localPosition = origin + new Vector3(x, 0f, 0f);
elapsed += Time.deltaTime;
yield return null;
}
btn.transform.localPosition = origin;
}
IEnumerator FeedbackAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 originalScale = txt.transform.localScale;
Vector3 bigScale = originalScale * 1.18f;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
Vector3 originalPos = txt.transform.localPosition;
Vector3 startPos = originalPos + Vector3.down * 18f;
txt.transform.localPosition = startPos;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.16f;
float ease = EaseOutBack(t);
txt.transform.localScale = Vector3.Lerp(originalScale, bigScale, ease);
txt.transform.localPosition = Vector3.Lerp(startPos, originalPos, ease);
c.a = Mathf.Clamp01(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
txt.transform.localPosition = originalPos;
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(bigScale, originalScale, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = originalScale;
}
IEnumerator ComboAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = txt.transform.localScale;
Vector3 big = original * 1.22f;
Color baseColor = FullAlpha(txt.color);
Color highlight = new Color32(255, 220, 50, 255);
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutBack(t));
txt.color = FullAlpha(Color.Lerp(baseColor, highlight, t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.14f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
txt.color = FullAlpha(Color.Lerp(highlight, baseColor, t));
yield return null;
}
txt.transform.localScale = original;
txt.color = baseColor;
}
IEnumerator ScorePopAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = txt.transform.localScale;
Vector3 big = original * 1.18f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.10f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = original;
}
IEnumerator FadeInText(TMP_Text txt)
{
if (txt == null) yield break;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.18f;
c.a = EaseOutQuad(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
}
void UpdateTimerUI()
{
if (timerText == null) return;
timerText.text = Mathf.Ceil(timeLeft).ToString();
if (timeLeft <= 10f)
{
timerText.color = FullAlpha(Color.Lerp(timerWarnColor, Color.white, Mathf.PingPong(Time.time * 3f, 1f)));
timerText.transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 10f) * 0.05f);
}
else
{
timerText.color = FullAlpha(timerNormalColor);
timerText.transform.localScale = Vector3.one;
}
}
void UpdateScore()
{
if (scoreText != null)
scoreText.text = score.ToString();
}
void UpdateCombo()
{
if (comboText != null)
comboText.text = combo + "x Combo";
}
float GetComboMultiplier(int c)
{
if (c >= 8) return mult_8plus;
if (c >= 5) return mult_5to7;
if (c >= 3) return mult_3to4;
return mult_1to2;
}
void OnExtraTime()
{
if (!extraTimeReady || gameOver) return;
timeLeft += 5f;
extraTimeReady = false;
if (extraTimeButton != null)
extraTimeButton.interactable = false;
if (extraTimeCooldownText != null)
{
extraTimeCooldownText.gameObject.SetActive(true);
StartCoroutine(Cooldown(extraTimeCooldownText, extraTimeButton, () => extraTimeReady = true));
}
else
{
StartCoroutine(SimpleCooldown(extraTimeButton, () => extraTimeReady = true));
}
}
void OnExtraHint()
{
if (!extraHintReady || gameOver || waitingNextQuestion) return;
int removed = 0;
for (int i = 0; i < answerButtons.Length && removed < 2; i++)
{
if (i == correctAnswerIndex || i == selectedAnswer) continue;
if (answerButtons[i] == null) continue;
answerButtons[i].interactable = false;
CanvasGroup cg = answerButtons[i].GetComponent<CanvasGroup>();
if (cg != null)
cg.alpha = 1f;
Image img = answerButtons[i].image;
if (img != null)
img.color = FullAlpha(disabledButtonColor);
if (answerTexts != null && i < answerTexts.Length && answerTexts[i] != null)
answerTexts[i].text = "—";
removed++;
}
extraHintReady = false;
if (extraHintButton != null)
extraHintButton.interactable = false;
if (extraHintCooldownText != null)
{
extraHintCooldownText.gameObject.SetActive(true);
StartCoroutine(Cooldown(extraHintCooldownText, extraHintButton, () => extraHintReady = true));
}
else
{
StartCoroutine(SimpleCooldown(extraHintButton, () => extraHintReady = true));
}
}
void OnExtraSkip()
{
if (!extraSkipReady || gameOver || waitingNextQuestion) return;
NextQuestion();
extraSkipReady = false;
if (extraSkipButton != null)
extraSkipButton.interactable = false;
if (extraSkipCooldownText != null)
{
extraSkipCooldownText.gameObject.SetActive(true);
StartCoroutine(Cooldown(extraSkipCooldownText, extraSkipButton, () => extraSkipReady = true));
}
else
{
StartCoroutine(SimpleCooldown(extraSkipButton, () => extraSkipReady = true));
}
}
IEnumerator Cooldown(TMP_Text label, Button button, System.Action done)
{
float t = 5f;
while (t > 0f)
{
if (label != null)
label.text = Mathf.Ceil(t).ToString();
t -= Time.deltaTime;
yield return null;
}
if (label != null)
{
label.text = "";
label.gameObject.SetActive(false);
}
if (button != null)
button.interactable = true;
done?.Invoke();
}
IEnumerator SimpleCooldown(Button button, System.Action done)
{
yield return new WaitForSeconds(5f);
if (button != null)
button.interactable = true;
done?.Invoke();
}
void GameOver()
{
if (gameOver) return;
gameOver = true;
PlayerPrefs.SetInt("Mod2Score", score);
PlayerPrefs.SetInt("Mod2Correct", correctCount);
PlayerPrefs.SetInt("Mod2Wrong", wrongCount);
int best = PlayerPrefs.GetInt("BestScore_Mod2", 0);
if (score > best)
PlayerPrefs.SetInt("BestScore_Mod2", score);
int bestCombo = PlayerPrefs.GetInt("BestCombo_Mod2", 0);
if (combo > bestCombo)
PlayerPrefs.SetInt("BestCombo_Mod2", combo);
PlayerPrefs.SetInt("TotalCorrect_Mod2", PlayerPrefs.GetInt("TotalCorrect_Mod2", 0) + correctCount);
PlayerPrefs.SetInt("TotalWrong_Mod2", PlayerPrefs.GetInt("TotalWrong_Mod2", 0) + wrongCount);
PlayerPrefs.SetInt("PlayCount_Mod2", PlayerPrefs.GetInt("PlayCount_Mod2", 0) + 1);
int total = PlayerPrefs.GetInt("TotalScore", 0) + score;
PlayerPrefs.SetInt("TotalScore", total);
PlayerPrefs.Save();
SceneManager.LoadScene(resultSceneName);
}
Color FullAlpha(Color c)
{
c.a = 1f;
return c;
}
void Shuffle<T>(List<T> list)
{
for (int i = 0; i < list.Count; i++)
{
int rnd = Random.Range(i, list.Count);
T temp = list[i];
list[i] = list[rnd];
list[rnd] = temp;
}
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
class WordPair
{
public string tr;
public string en;
public string es;
public string de;
public string fr;
public string pt;
public WordPair(string tr, string en, string es, string de, string fr, string pt)
{
this.tr = tr;
this.en = en;
this.es = es;
this.de = de;
this.fr = fr;
this.pt = pt;
}
public string GetByCode(string code)
{
switch (code)
{
case "tr": return tr;
case "en": return en;
case "es": return es;
case "de": return de;
case "fr": return fr;
case "pt": return pt;
default: return en;
}
}
}
}