163 lines
No EOL
4.5 KiB
C#
163 lines
No EOL
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
using Random = System.Random;
|
|
|
|
/// <summary>
|
|
/// gameplay behaviour class
|
|
/// </summary>
|
|
public class Gameplay
|
|
{
|
|
/// <summary>
|
|
/// singleton instance of the gameplay class
|
|
/// </summary>
|
|
public const int RoundsPerGame = 5;
|
|
|
|
/// <summary>
|
|
/// seconds per round
|
|
/// </summary>
|
|
// ReSharper disable once MemberCanBePrivate.Global
|
|
public const double SecondsPerRound = 12d;
|
|
|
|
/// <summary>
|
|
/// countdown text label for showing the countdown
|
|
/// </summary>
|
|
private readonly Label _countdownText;
|
|
|
|
/// <summary>
|
|
/// list of played rounds
|
|
/// </summary>
|
|
private readonly List<RoundInfo> _playedRounds = new(5);
|
|
|
|
/// <summary>
|
|
/// response colour for the player to match
|
|
/// </summary>
|
|
private readonly VisualElement _responseColour;
|
|
|
|
/// <summary>
|
|
/// round text label for showing the current round
|
|
/// </summary>
|
|
private readonly Label _roundText;
|
|
|
|
/// <summary>
|
|
/// template colour for the player to match
|
|
/// </summary>
|
|
private readonly VisualElement _templateColour;
|
|
|
|
/// <summary>
|
|
/// game countdown timer
|
|
/// </summary>
|
|
private DateTime _countdownDatetime;
|
|
|
|
/// <summary>
|
|
/// game round counter
|
|
/// </summary>
|
|
public int Round = -1;
|
|
|
|
/// <summary>
|
|
/// constructor for the gameplay class
|
|
/// </summary>
|
|
/// <param name="ui">the visual element object for the ui document with the GameView</param>
|
|
public Gameplay(VisualElement ui)
|
|
{
|
|
_roundText = ui.Q<Label>("RoundText");
|
|
_countdownText = ui.Q<Label>("TimeText");
|
|
_templateColour = ui.Q<VisualElement>("TemplateColour");
|
|
_responseColour = ui.Q<VisualElement>("ResponseColour");
|
|
}
|
|
|
|
/// <summary>
|
|
/// function for starting the game
|
|
/// </summary>
|
|
public void StartGame()
|
|
{
|
|
Round = 0;
|
|
_playedRounds.Clear();
|
|
AdvanceToNextRound();
|
|
}
|
|
|
|
/// <summary>
|
|
/// (to be) called once per frame
|
|
/// </summary>
|
|
public void Update()
|
|
{
|
|
if (Round < 1) return;
|
|
if (_countdownDatetime < DateTime.Now) AdvanceToNextRound();
|
|
Render();
|
|
}
|
|
|
|
/// <summary>
|
|
/// function for advancing to the next round
|
|
/// </summary>
|
|
private void AdvanceToNextRound()
|
|
{
|
|
if (Round > 0) StoreRoundInfo();
|
|
GenerateNewTemplateColour();
|
|
|
|
if (Round < RoundsPerGame)
|
|
{
|
|
Debug.Log("round advance");
|
|
Round++;
|
|
_countdownDatetime = DateTime.Now.AddSeconds(SecondsPerRound);
|
|
}
|
|
else
|
|
{
|
|
// end game
|
|
Round = -1;
|
|
GameManager.Instance.SignalGameEnd(_playedRounds);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// function for storing the round information
|
|
/// </summary>
|
|
private void StoreRoundInfo()
|
|
{
|
|
_playedRounds.Add(new RoundInfo
|
|
{
|
|
TemplateColour = _templateColour.style.backgroundColor.value,
|
|
ResponseColour = _responseColour.style.backgroundColor.value
|
|
});
|
|
Debug.Log(
|
|
$"stored round info (Template is {_templateColour.style.backgroundColor.value}, Response is {_responseColour.style.backgroundColor.value})");
|
|
}
|
|
|
|
/// <summary>
|
|
/// function for generating a new template colour
|
|
/// (a random colour that isn't hard to visually match)
|
|
/// </summary>
|
|
private void GenerateNewTemplateColour()
|
|
{
|
|
// - lightness: 30-90
|
|
// - chroma: 0.03-0.20
|
|
// - hue: all (0-360)
|
|
|
|
var r = new Random();
|
|
var l = Math.Clamp(r.NextDouble() * 60d + 30d, 30d, 90d);
|
|
var c = Math.Clamp(r.NextDouble() * 0.17d + 0.03d, 0.03d, 0.20d);
|
|
var h = Math.Clamp(r.NextDouble() * 360d, 0d, 360d);
|
|
var colour = Colorimetry.RawLchToColor(l, c, h);
|
|
Debug.Log($"generated new template colour LCh({l:F}, {c:F}, {h:F}) -> {colour}");
|
|
_templateColour.style.backgroundColor = colour;
|
|
}
|
|
|
|
/// <summary>
|
|
/// function for rendering the game state
|
|
/// </summary>
|
|
private void Render()
|
|
{
|
|
var remaining = (_countdownDatetime - DateTime.Now).TotalSeconds;
|
|
_roundText.text = $"{Round}/{RoundsPerGame}";
|
|
_countdownText.text = $"{remaining:F2}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// struct for storing round information
|
|
/// </summary>
|
|
public struct RoundInfo
|
|
{
|
|
public Color TemplateColour;
|
|
public Color ResponseColour;
|
|
}
|
|
} |