ludumdare50/Assets/Scripts/GameFlowManager.cs
2022-04-03 18:23:46 -04:00

256 lines
6.6 KiB
C#

#nullable enable
using System;
using NaughtyAttributes;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using TMPro;
//Could be a singleton
public class GameFlowManager : MonoBehaviour {
[SerializeField] [Required]
GameTimer gameTimer = null!;
[SerializeField] [Required]
MainMenuManager mainMenu = null!;
[SerializeField] [Required]
Canvas UICanvas = null!;
BlurFade blurFade = null!;
public enum PauseLevel {
NotPaused,
PreventActions,
NothingMoves,
TimeStop,
}
[field: SerializeField]
public PauseLevel pauseLevel { get; private set; } = PauseLevel.PreventActions;
public bool CanDoAction => pauseLevel <= PauseLevel.NotPaused;
public BaseState CurrentState { get; private set; } = null!;
bool lastStartButton;
bool lastAcceptButton;
[field: SerializeField] float fadingTime = 3f;
[field: SerializeField] float minFadingValue = 0.1f;
float fadeStep = 0.02f;
float fadingTimer;
bool fadingIn = false;
[field: SerializeField] TMP_Text startTxt = null!;
[field: SerializeField] TMP_Text endTxt = null!;
public event Action<BaseState, BaseState>? stateChanged;
#region Unity Messages
void Awake() {
blurFade = GetComponentInChildren<BlurFade>();
CurrentState = new StartMenuFlowState(this);
if (startTxt != null) {
startTxt.transform.parent.gameObject.SetActive(true);
}
if (endTxt != null) {
endTxt.transform.parent.gameObject.SetActive(false);
}
}
void Start() => CurrentState.EnterState();
void Update() {
if (CurrentState.UpdateState() is {} newState)
SwitchState(newState);
}
#endregion
void SetPauseLevel(PauseLevel value) {
pauseLevel = value;
Time.timeScale = value >= PauseLevel.TimeStop ? 0f : 1f;
}
public void GameOver(){
if (endTxt != null) {
endTxt.transform.parent.gameObject.SetActive(true);
}
SwitchState(new DeadFlowState(this));
}
public void FadeStartTxt(){
fadingTimer += fadeStep;
if(fadingTimer >= fadingTime){
if(fadingIn){
fadingIn = false;
fadingTimer = 0;
}else{
fadingIn = true;
fadingTimer = 0;
}
}
if(!fadingIn){
startTxt.color = new Color(startTxt.color.r, startTxt.color.g, startTxt.color.b, (1+minFadingValue) - (fadingTimer/fadingTime));
}else{
startTxt.color = new Color(startTxt.color.r, startTxt.color.g, startTxt.color.b, (fadingTimer/fadingTime) + minFadingValue);
}
}
/// <summary>
/// For calling from main menu button
/// </summary>
public void ToStartFlowState() => SwitchState(new StartFlowState(this));
#region Inputs
public void OnStart(InputAction.CallbackContext ctx) {
if (!ctx.WasPressedThisFrame(ref lastStartButton))
return;
switch (CurrentState) {
case StartFlowState _:
SwitchState(new GameplayFlowState(this));
break;
case GameplayFlowState _:
SwitchState(new PauseMenuFlowState(this));
break;
case PauseMenuFlowState _:
SwitchState(new GameplayFlowState(this));
break;
}
}
public void OnAccept(InputAction.CallbackContext ctx) {
if (!ctx.WasPressedThisFrame(ref lastAcceptButton))
return;
if (CurrentState is DeadFlowState deadState)
deadState.ReloadGame();
}
#endregion
#region States
void SwitchState(BaseState newState) {
CurrentState.LeaveState();
BaseState oldState = CurrentState;
CurrentState = newState;
newState.EnterState();
stateChanged?.Invoke(oldState, newState);
}
public abstract class GameFlowState : BaseState {
readonly protected GameFlowManager gameFlowManager;
protected GameFlowState(GameFlowManager gameFlowManager) {
this.gameFlowManager = gameFlowManager;
}
}
class StartMenuFlowState : GameFlowState {
public StartMenuFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
public override void EnterState() {
base.EnterState();
gameFlowManager.mainMenu.gameObject.SetActive(true);
gameFlowManager.mainMenu.SetMenuMode(MainMenuManager.MenuMode.MainMenu);
gameFlowManager.UICanvas.gameObject.SetActive(false);
gameFlowManager.blurFade.SetBlurred(true);
}
public override void LeaveState() {
base.LeaveState();
gameFlowManager.mainMenu.ResetMenuState();
gameFlowManager.mainMenu.gameObject.SetActive(false);
gameFlowManager.UICanvas.gameObject.SetActive(true);
gameFlowManager.blurFade.SetBlurred(false);
}
}
public class StartFlowState : GameFlowState {
public StartFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
public override void EnterState() {
base.EnterState();
gameFlowManager.startTxt.transform.parent.gameObject.SetActive(true);
gameFlowManager.SetPauseLevel(PauseLevel.PreventActions);
}
public override BaseState? UpdateState(){
gameFlowManager.FadeStartTxt();
return null;
}
public override void LeaveState() => gameFlowManager.startTxt.transform.parent.gameObject.SetActive(false);
}
public class GameplayFlowState : GameFlowState {
public GameplayFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
public override void EnterState() {
base.EnterState();
gameFlowManager.gameTimer.Stopped = false;
gameFlowManager.SetPauseLevel(PauseLevel.NotPaused);
}
public override void LeaveState() {
base.LeaveState();
gameFlowManager.gameTimer.Stopped = true;
}
}
class PauseMenuFlowState : GameFlowState {
public PauseMenuFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
public override void EnterState() {
base.EnterState();
gameFlowManager.mainMenu.gameObject.SetActive(true);
gameFlowManager.mainMenu.SetMenuMode(MainMenuManager.MenuMode.PauseMenu);
gameFlowManager.SetPauseLevel(PauseLevel.TimeStop);
gameFlowManager.blurFade.SetBlurred(true);
gameFlowManager.gameTimer.ShowHighScore = true;
}
public override void LeaveState() {
base.EnterState();
gameFlowManager.mainMenu.ResetMenuState();
gameFlowManager.mainMenu.gameObject.SetActive(false);
gameFlowManager.SetPauseLevel(PauseLevel.NotPaused);
gameFlowManager.blurFade.SetBlurred(false);
gameFlowManager.gameTimer.ShowHighScore = false;
}
}
class DeadFlowState : GameFlowState {
public DeadFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
public override void EnterState() {
base.EnterState();
gameFlowManager.SetPauseLevel(PauseLevel.PreventActions);
gameFlowManager.blurFade.SetBlurred(true);
gameFlowManager.gameTimer.ShowHighScore = true;
}
public override void LeaveState() {
gameFlowManager.blurFade.SetBlurred(false);
gameFlowManager.gameTimer.ShowHighScore = false;
}
public void ReloadGame() {
Debug.Log("Reloading scene...");
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
#endregion
}