Files
unity-application/Assets/JustSign/Scripts/JustSignController.cs
2023-03-16 19:03:39 +01:00

223 lines
6.7 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// Contains all game logic for the JustSign game
/// </summary>
public class JustSignController : MonoBehaviour
{
/// <summary>
/// The canvas containing all components
/// </summary>
public Canvas canvas;
/// <summary>
/// The input field where the user can type his or her answer
/// </summary>
public TMP_InputField answerField;
/// <summary>
/// The feedback on the timing
/// </summary>
public TMP_Text feedBack;
/// <summary>
/// The zone that the player should be hitting with his or her inputs
/// </summary>
public GameObject hitZone;
/// <summary>
/// All of the words that can be used in this session
/// </summary>
private string[] words;
/// <summary>
/// All of the available themes
/// </summary>
private ThemeList themeList;
/// <summary>
/// The theme we are currently using
/// </summary>
private Theme currentTheme;
/// <summary>
/// List of strings representing all words on the track
/// </summary>
private List<string> activeWords = new List<string>();
/// <summary>
/// List of objects representing all symbols on the track
/// </summary>
private List<GameObject> activeSymbols = new List<GameObject>();
/// <summary>
/// The current score
/// </summary>
private int score;
/// <summary>
/// Width and height of the symbols
/// </summary>
private int symbolSize = 280;
/// <summary>
/// Controls movement speed of symbols (higher -> faster)
/// </summary>
private int moveSpeed = 200;
/// <summary>
/// Starting X-coordinate of a symbol = (-1920 - symbolsize) / 2
/// </summary>
private int trackX = -1100;
/// <summary>
/// Starting Y-coordinate of a symbol
/// </summary>
private int trackY = -200;
/// <summary>
/// Max distance from hit zone to get perfect score
/// </summary>
private int perfectBoundary = 10;
/// <summary>
/// Max distance from hit zone to get good score
/// </summary>
private int goodBoundary = 120;
/// <summary>
/// Max distance from hit zone to get meh score
/// </summary>
private int mehBoundary = 200;
/// <summary>
/// Time at which the last symbol was spawned
/// </summary>
private float lastSpawn;
/// <summary>
/// Determines every how many seconds a symbol should spawn (will become music-dependent later on)
/// </summary>
private float spawnPeriod = 3.0f;
/// <summary>
/// Start is called before the first frame update
/// </summary>
void Start()
{
themeList = ThemeLoader.LoadJson();
currentTheme = FindThemeByName(PlayerPrefs.GetString("themeName"));
words = currentTheme.words;
lastSpawn = Time.time;
Debug.Log(hitZone.transform.position.x);
Debug.Log(hitZone.transform.position.y);
SpawnNewSymbol();
}
/// <summary>
/// Update is called once per frame
/// </summary>
void Update()
{ /*
Debug.Log("X");
Debug.Log(activeSymbols[0].transform.position.x);
Debug.Log("Y");
Debug.Log(activeSymbols[0].transform.position.y);
*/
// Destroy the oldest symbol if the current input matches it
if (answerField.text.ToLower() == activeWords[0]) {
int difference = Math.Abs((int) (activeSymbols[0].transform.position.x - hitZone.transform.position.x));
if (difference < perfectBoundary) {
feedBack.text = "Perfect!";
} else if (difference < goodBoundary) {
feedBack.text = "Good!";
} else if (difference < mehBoundary) {
feedBack.text = "Meh...";
} else {
feedBack.text = "Terrible!";
}
DestroyRightmostSymbol();
answerField.text = "";
}
// Destroy the oldest symbol if it leaves the screen
if (activeSymbols[0].GetComponent<RectTransform>().localPosition.x > -trackX) {
DestroyRightmostSymbol();
}
// Spawn new symbol every spawn period
float currentTime = Time.time;
if (currentTime - lastSpawn > spawnPeriod) {
lastSpawn = currentTime;
SpawnNewSymbol();
}
// Move all active symbols to the right
foreach (GameObject symbol in activeSymbols) {
RectTransform rectTransform = symbol.GetComponent<RectTransform>();
rectTransform.localPosition = new Vector3(rectTransform.localPosition.x + Time.deltaTime * moveSpeed, trackY, 0);
}
}
/// <summary>
/// Destroy the oldest symbol on the track
/// </summary>
void DestroyRightmostSymbol() {
activeWords.RemoveAt(0);
GameObject symbol = activeSymbols[0];
activeSymbols.RemoveAt(0);
Destroy(symbol);
}
/// <summary>
/// Find the chosen theme by its name
/// </summary>
/// <param name="themeName">The name of the theme to find</param>
/// <returns>The requested theme</returns>
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;
}
/// <summary>
/// Create a new symbol at the start of the track
/// </summary>
void SpawnNewSymbol() {
string nextSymbol = words[UnityEngine.Random.Range(0, words.Length)];
GameObject newSymbolObject = new GameObject("Symbol");
Image newImage = newSymbolObject.AddComponent<Image>();
RectTransform rectTransform = newSymbolObject.GetComponent<RectTransform>();
rectTransform.SetParent(canvas.transform, false); // Set the parent to the Canvas
rectTransform.localPosition = new Vector3(trackX, trackY, 0);
rectTransform.sizeDelta = new Vector2(symbolSize, symbolSize);
Sprite sprite = Resources.Load<Sprite>("Common/Images/" + nextSymbol);
// Set the new sprite as the Image component's source image
newImage.sprite = sprite;
activeWords.Add(nextSymbol);
activeSymbols.Add(newSymbolObject);
}
}