287 lines
8.8 KiB
C#
287 lines
8.8 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class SpellingBeeController : 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 GameObjects representing the letters
|
|
private GameObject[] letters;
|
|
|
|
// The Image component for displaying the appropriate sprite
|
|
public Image image;
|
|
|
|
// The input field for testing purposes
|
|
public TMP_InputField input;
|
|
|
|
// Current value of timer in seconds
|
|
private float timerValue;
|
|
|
|
// Timer display
|
|
public TMP_Text timerText;
|
|
|
|
// "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;
|
|
|
|
// Start is called before the first frame update
|
|
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());
|
|
|
|
themeList = ThemeLoader.loadJson();
|
|
currentTheme = FindThemeByName(PlayerPrefs.GetString("themeName"));
|
|
words = currentTheme.words;
|
|
ShuffleWords();
|
|
SetNextWord();
|
|
}
|
|
|
|
// Update is called once per frame
|
|
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
|
|
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
|
|
string temp = words[i];
|
|
words[i] = words[j];
|
|
words[j] = temp;
|
|
}
|
|
}
|
|
|
|
// Displays the game over panel and score values
|
|
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
|
|
void ActivateWin() {
|
|
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
|
|
void CheckChar(char letter) {
|
|
if (Char.ToUpper(letter) == Char.ToUpper(currentWord[letterIndex]) && input.text.Length == 1) {
|
|
letters[letterIndex].GetComponent<Image>().color = Color.green;
|
|
input.text = "";
|
|
spelledLetters++;
|
|
letterIndex++;
|
|
|
|
if (letterIndex >= currentWord.Length) {
|
|
DeleteWord();
|
|
StartCoroutine(Wait());
|
|
SetNextWord();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Delete all letter objects
|
|
void DeleteWord() {
|
|
for (int i = 0; i < currentWord.Length; i++) {
|
|
Destroy(letters[i]);
|
|
}
|
|
}
|
|
|
|
// Adds seconds to timer
|
|
void AddSeconds(int seconds) {
|
|
timerValue += (float) seconds;
|
|
}
|
|
|
|
// Find the chosen theme by its name
|
|
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
|
|
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
|
|
void DisplayWord(string word) {
|
|
int length = word.Length;
|
|
int canvasWidth = 1920;
|
|
int maxWidth = 1080;
|
|
int spacing = maxWidth / (length - 1);
|
|
|
|
letters = new GameObject[length];
|
|
int[] xvalues = new int[length];
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
xvalues[i] = (canvasWidth - maxWidth) / 2 + i * spacing;
|
|
}
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
GameObject colorBox = new GameObject("Letter box");
|
|
colorBox.transform.SetParent(gameObject.transform);
|
|
letters[i] = colorBox;
|
|
|
|
// Add an Image component to the new GameObject
|
|
Image background = colorBox.AddComponent<Image>();
|
|
background.color = Color.red;
|
|
background.sprite = UnityEditor.AssetDatabase.GetBuiltinExtraResource<Sprite>("UI/Skin/UISprite.psd");
|
|
|
|
// Create a new child GameObject to hold the Text component
|
|
GameObject letterObject = new GameObject("Text");
|
|
letterObject.transform.SetParent(colorBox.transform);
|
|
|
|
// Add a Text component to the new child GameObject
|
|
Text letterComponent = letterObject.AddComponent<Text>();
|
|
letterComponent.text = Char.ToString(Char.ToUpper(word[i]));
|
|
letterComponent.alignment = TextAnchor.MiddleCenter;
|
|
letterComponent.fontSize = 60;
|
|
|
|
// Set the font of the Text component
|
|
letterComponent.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
|
|
|
|
// Set the position of the parent GameObject
|
|
colorBox.transform.position = new Vector2(xvalues[i], 450);
|
|
}
|
|
}
|
|
|
|
// Change the image that is being displayed
|
|
void ChangeSprite(string spriteName) {
|
|
Image imageComponent = image.GetComponent<Image>();
|
|
|
|
// Load the new sprite from the Resources folder
|
|
Sprite sprite = Resources.Load<Sprite>("SpellingBee/images/" + spriteName);
|
|
|
|
// Set the new sprite as the Image component's source image
|
|
image.sprite = sprite;
|
|
}
|
|
|
|
IEnumerator Wait() {
|
|
yield return new WaitForSecondsRealtime(2);
|
|
}
|
|
}
|