using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class GameController : MonoBehaviour { // All of the words that can be used in this session private string[] words; // Where we currently are in the word private int letterIndex; // Where we currently are in the word list private int wordIndex; // The word that is currently being spelled private string currentWord; // All of the available themes private ThemeList themeList; // The theme we are currently using private Theme currentTheme; // The input field for testing purposes public TMP_InputField input; // Current value of timer in seconds private float timerValue; // "Game over" or "You win!" public TMP_Text endText; // First score display public TMP_Text correctWordsText; // Second score display public TMP_Text correctLettersText; // The game over panel public GameObject gameEndedPanel; // Button for restarting the game public Button replayButton; // Indicates if the game is still going private bool gameEnded; // Amount of seconds user gets per letter of the current word // Set to 1 for testing; should be increased later private int secondsPerLetter = 1; // Counter that keeps track of how many words have been spelled correctly private int spelledLetters; // Counter that keeps track of how many letters have been spelled correctly private int spelledWords; [Header("User")] // Reference to the user list to access the current user public UserList userList; // Reference to the current user private User user; // Reference to the minigame progress of the current user private Progress progress = null; [Header("Minigame")] // Reference to the minigame ScriptableObject public Minigame minigame; [Header("Letter prefab")] // Letter prefab public GameObject letterPrefab; [Header("UI References")] // Reference to letter prefab public Transform letterContainer; // The Image component for displaying the appropriate sprite public Image wordImage; // Timer display public TMP_Text timerText; [Header("Private Variables")] // The GameObjects representing the letters private List letters = new List(); // Start is called before the first frame update public void Start() { spelledLetters = 0; // We use -1 instead of 0 so SetNextWord can simply increment it each time spelledWords = -1; gameEnded = false; wordIndex = 0; input.text = ""; timerValue = 0.0f; gameEndedPanel.SetActive(false); replayButton.onClick.AddListener(Start); // Create entry in current user for keeping track of progress user = userList.GetCurrentUser(); progress = user.minigames.Find((p) => p != null && p.Get("minigameIndex") == minigame.index); if (progress == null) { progress = new Progress(); progress.AddOrUpdate("minigameIndex", MinigameIndex.SPELLING_BEE); // TODO: add progress we want to keep track off // (for example 'highscore') progress.AddOrUpdate("highscore", 0); user.minigames.Add(progress); } userList.Save(); DeleteWord(); // TODO: change to ScriptableObject themeList = ThemeLoader.LoadJson(); currentTheme = FindThemeByName(PlayerPrefs.GetString("themeName")); words = currentTheme.words; ShuffleWords(); SetNextWord(); } // Update is called once per frame public void Update() { if (!gameEnded) { if (input.text.Length > 0) { CheckChar(input.text[0]); } timerValue -= Time.deltaTime; if (timerValue <= 0.0f) { timerValue = 0.0f; ActivateGameOver(); } int minutes = Mathf.FloorToInt(timerValue / 60.0f); int seconds = Mathf.FloorToInt(timerValue % 60.0f); timerText.text = string.Format("{0:00}:{1:00}", minutes, seconds); } } // Randomly shuffle the list of words private void ShuffleWords() { for (int i = words.Length - 1; i > 0; i--) { // Generate a random index between 0 and i (inclusive) int j = UnityEngine.Random.Range(0, i + 1); // Swap the values at indices i and j (words[j], words[i]) = (words[i], words[j]); } } // Displays the game over panel and score values private void ActivateGameOver() { DeleteWord(); endText.text = "GAME OVER"; correctLettersText.text = "Correctly spelled letters: " + spelledLetters.ToString(); correctWordsText.text = "Correctly spelled words: " + spelledWords.ToString(); gameEndedPanel.SetActive(true); gameEndedPanel.transform.SetAsLastSibling(); gameEnded = true; } // Display win screen private void ActivateWin() { int score = words.Length; // Update progress // TODO: update all tracked progress int highscore = progress.Get("highscore"); if (score < highscore) { progress.AddOrUpdate("highsscore", score); userList.Save(); } // @lukas stuff DeleteWord(); endText.text = "YOU WIN!"; correctLettersText.text = "Your time: " + spelledLetters.ToString(); int totalWordsDuration = 0; foreach (string word in words) { totalWordsDuration += word.Length * secondsPerLetter + 1; } // How much time was spent by the player int spentTime = totalWordsDuration - (int)timerValue; int seconds = spentTime % 60; int minutes = spentTime / 60; if (minutes == 0) { correctLettersText.text = "Your time: " + seconds + " seconds"; } else { correctLettersText.text = "Your time: " + minutes + " minutes and " + seconds + " seconds"; } correctWordsText.text = ""; gameEndedPanel.SetActive(true); gameEndedPanel.transform.SetAsLastSibling(); gameEnded = true; } // Check if the correct char has been given as input private void CheckChar(char letter) { if (Char.ToUpper(letter) == Char.ToUpper(currentWord[letterIndex]) && input.text.Length == 1) { letters[letterIndex].GetComponent().color = Color.green; input.text = ""; spelledLetters++; letterIndex++; if (letterIndex >= currentWord.Length) { DeleteWord(); StartCoroutine(Wait()); SetNextWord(); } } } // Delete all letter objects private void DeleteWord() { for (int i = 0; i < letters.Count; i++) { Destroy(letters[i]); } letters.Clear(); } // Adds seconds to timer private void AddSeconds(int seconds) { timerValue += (float)seconds; } // Find the chosen theme by its name private Theme FindThemeByName(string themeName) { int themeIndex = 0; while (themeIndex < themeList.themes.Length) { Theme theme = themeList.themes[themeIndex]; if (theme.name == themeName) { return theme; } themeIndex++; } Debug.Log("Requested theme not found"); return null; } // Display next word in the series private void SetNextWord() { spelledWords++; if (wordIndex < words.Length) { currentWord = words[wordIndex]; ChangeSprite(currentWord); DisplayWord(currentWord); AddSeconds(currentWord.Length * secondsPerLetter + 1); letterIndex = 0; wordIndex++; } else { ActivateWin(); } } // Displays the word that needs to be spelled private void DisplayWord(string word) { for (int i = 0; i < word.Length; i++) { // Create instance of prefab GameObject instance = GameObject.Instantiate(letterPrefab, letterContainer); letters.Add(instance); // Dynamically load appearance Image background = instance.GetComponent(); background.color = Color.red; TMP_Text txt = instance.GetComponentInChildren(); txt.text = Char.ToString(Char.ToUpper(word[i])); } } // Change the image that is being displayed private void ChangeSprite(string spriteName) { // Load the new sprite from the Resources folder Sprite sprite = Resources.Load("SpellingBee/images/" + spriteName); // Set the new sprite as the Image component's source image wordImage.sprite = sprite; } private IEnumerator Wait() { yield return new WaitForSecondsRealtime(2); } }