GameFlow.cs
namespace PixelPusher;
public enum GameScreen
{
Title,
ModePick,
Pixel,
Stage,
World,
Chip,
Library,
Play2D,
Play3D,
Pause,
Cleared
}
public static class GameFlow
{
public static GameScreen Screen { get; private set; } = GameScreen.Title;
public static GameScreen ResumeTo { get; private set; } = GameScreen.Pixel;
public static bool PlaytestFromStage { get; private set; }
public static GameScreen AfterPlay { get; private set; } = GameScreen.ModePick;
public static int Ui { get; private set; }
public static string Toast { get; private set; } = "";
static float _toastLeft;
public static bool InStudio =>
Screen is GameScreen.Pixel or GameScreen.Stage or GameScreen.World or GameScreen.Chip or GameScreen.Library;
public static bool InPlay => Screen is GameScreen.Play2D or GameScreen.Play3D;
public static void Bump() => Ui++;
public static void Tick()
{
if ( _toastLeft > 0f )
{
_toastLeft -= Time.Delta;
if ( _toastLeft <= 0f )
{
Toast = "";
Bump();
}
}
if ( Screen == GameScreen.Title )
return;
if ( Input.Pressed( "Pause" ) || Input.Pressed( "Menu" ) )
{
TogglePause();
return;
}
if ( InStudio )
{
if ( Input.Pressed( "Slot1" ) ) OpenStudio( GameScreen.Pixel );
else if ( Input.Pressed( "Slot2" ) ) OpenStudio( GameScreen.Stage );
else if ( Input.Pressed( "Slot3" ) ) OpenStudio( GameScreen.World );
else if ( Input.Pressed( "Slot4" ) ) OpenStudio( GameScreen.Chip );
else if ( Input.Pressed( "Slot5" ) ) OpenStudio( GameScreen.Library );
if ( Screen == GameScreen.Stage && Input.Pressed( "Score" ) )
StartPlaytest();
}
}
public static void ShowToast( string text, float seconds = 2.2f )
{
Toast = text ?? "";
_toastLeft = seconds;
ChipVoices.Tick();
Bump();
}
public static void GoTitle()
{
Desk.Autosave( quiet: true );
PlaytestFromStage = false;
AfterPlay = GameScreen.ModePick;
Screen = GameScreen.Title;
Bump();
}
public static void OpenModePick()
{
if ( !Desk.Ready )
Desk.Boot();
Screen = GameScreen.ModePick;
Bump();
}
public static void EnterBuild()
{
if ( !Desk.Ready )
Desk.Boot();
Lesson.MaybeStart();
Coach.OnEnterBuild();
OpenStudio( GameScreen.Pixel );
}
public static void StartTour()
{
if ( !Desk.Ready )
Desk.Boot();
Lesson.Start();
Coach.OnEnterBuild();
OpenStudio( GameScreen.Pixel );
}
public static void EnterPlay()
{
if ( !Desk.Ready )
Desk.Boot();
PlaytestFromStage = false;
AfterPlay = GameScreen.ModePick;
PlaySim.Start( Desk.Stage, fromPlaytest: false );
Coach.OnPlay();
Screen = GameScreen.Play2D;
Bump();
}
public static void EnterWalk()
{
if ( !Desk.Ready )
Desk.Boot();
PlaytestFromStage = false;
AfterPlay = GameScreen.ModePick;
PlaySim.Start( Desk.Stage, fromPlaytest: false, walk3d: true );
Coach.OnWalk();
Screen = GameScreen.Play3D;
Bump();
}
public static void StartWorldWalk()
{
Desk.Autosave( quiet: true );
PlaytestFromStage = true;
AfterPlay = GameScreen.World;
PlaySim.Start( Desk.Stage, fromPlaytest: true, walk3d: true );
Coach.OnWalk();
Screen = GameScreen.Play3D;
Bump();
}
public static void OpenStudio( GameScreen studio )
{
if ( studio is GameScreen.Play2D or GameScreen.Play3D or GameScreen.Pause or GameScreen.Cleared or GameScreen.Title )
return;
Desk.Autosave( quiet: true );
ResumeTo = studio;
Screen = studio;
if ( studio == GameScreen.World )
WorldStudio.EnsureFramed();
if ( studio is GameScreen.Stage or GameScreen.Library )
{
var start = Desk.Stage?.Find( "start" );
if ( start is not null && Desk.Stage is not null )
StageStudio.FocusPlayer( start.Tx * Desk.Stage.TileSize, start.Ty * Desk.Stage.TileSize );
}
Lesson.OnStudio( studio );
Coach.OnStudio( studio );
Bump();
}
public static void StartPlaytest()
{
Desk.Autosave( quiet: true );
PlaytestFromStage = true;
AfterPlay = GameScreen.Stage;
PlaySim.Start( Desk.Stage, fromPlaytest: true, dropX: StageStudio.DropX, dropY: StageStudio.DropY );
Coach.OnPlay();
Screen = GameScreen.Play2D;
Bump();
}
public static void LeavePlay()
{
var to = AfterPlay;
if ( PlaytestFromStage && to == GameScreen.Stage )
StageStudio.FocusPlayer( PlaySim.Px, PlaySim.Py );
if ( PlaytestFromStage && to == GameScreen.World )
WorldStudio.FocusPlayer( PlaySim.Px, PlaySim.Py, PlaySim.Pz );
PlaytestFromStage = false;
Screen = to == GameScreen.Title ? GameScreen.ModePick : to;
Bump();
}
public static void TogglePause()
{
if ( Screen == GameScreen.Pause )
{
Screen = ResumeTo;
Bump();
return;
}
if ( Screen == GameScreen.Title || Screen == GameScreen.ModePick )
return;
if ( Screen == GameScreen.Cleared )
{
LeavePlay();
return;
}
Desk.Autosave( quiet: true );
ResumeTo = Screen;
Screen = GameScreen.Pause;
Bump();
}
public static void Resume()
{
if ( Screen != GameScreen.Pause )
return;
Screen = ResumeTo;
Bump();
}
public static void PlayNextSample()
{
var id = StarterPack.NextStageId( Desk.Stage?.Name );
if ( string.IsNullOrEmpty( id ) || !StarterPack.LoadShelf( id ) )
{
LeavePlay();
return;
}
AfterPlay = GameScreen.Stage;
PlaytestFromStage = true;
PlaySim.Start( Desk.Stage, fromPlaytest: true );
Coach.OnPlay();
Screen = GameScreen.Play2D;
ShowToast( Desk.Name );
Bump();
}
public static void Replay()
{
var walk = PlaySim.Walk3D;
var after = AfterPlay;
var fromStudio = after is GameScreen.Stage or GameScreen.World;
if ( walk )
{
PlaySim.Start( Desk.Stage, fromPlaytest: fromStudio, walk3d: true );
Screen = GameScreen.Play3D;
Coach.OnWalk();
}
else
{
var drop = fromStudio;
PlaySim.Start( Desk.Stage, fromPlaytest: drop, dropX: drop ? StageStudio.DropX : -1, dropY: drop ? StageStudio.DropY : -1 );
Screen = GameScreen.Play2D;
Coach.OnPlay();
}
Bump();
}
public static void OnStageCleared()
{
ResumeTo = AfterPlay is GameScreen.Stage or GameScreen.World
? AfterPlay
: (PlaySim.Walk3D ? GameScreen.Play3D : GameScreen.Play2D);
Screen = GameScreen.Cleared;
Coach.OnCleared();
Bump();
}
public static void Quit()
{
Desk.Autosave( quiet: true );
Game.Close();
}
}