Interface that represents the eight directional input bits a player physics system reads each frame, plus two concrete implementations: LiveInputSource which forwards to a static InputState snapshot, and NullPlayerInput which always returns false.
namespace BlockParty;
/// <summary>
/// The eight gameplay input bits the player physics reads each step (four held directions + their
/// "just pressed" edges). The real player reads these from the static per-frame <see cref="InputState"/>
/// snapshot via <see cref="LiveInputSource"/>; an AI-controlled body (the Summoner block's impostor)
/// supplies its own via <see cref="AiInputSource"/>.
///
/// Introducing this indirection lets a single <see cref="Player"/> class drive both the human player
/// and an AI clone with identical physics (gravity, wall-jump, crush/spike death, wind/magnet/stasis)
/// without duplicating any of it. The live source returns exactly the same values the accessors read
/// before, so the real player's simulation is byte-identical.
/// </summary>
public interface IPlayerInput
{
bool Left { get; }
bool Right { get; }
bool Up { get; }
bool Down { get; }
bool LeftJust { get; }
bool RightJust { get; }
bool UpJust { get; }
bool DownJust { get; }
}
/// <summary>The default input source: forwards straight to the static <see cref="InputState"/> snapshot.
/// A single shared instance is enough (it holds no state).</summary>
public sealed class LiveInputSource : IPlayerInput
{
public static readonly LiveInputSource Instance = new();
public bool Left => InputState.Left;
public bool Right => InputState.Right;
public bool Up => InputState.Up;
public bool Down => InputState.Down;
public bool LeftJust => InputState.LeftJust;
public bool RightJust => InputState.RightJust;
public bool UpJust => InputState.UpJust;
public bool DownJust => InputState.DownJust;
}
/// <summary>No directional input. Used by a living twin while control is assigned to its sibling.</summary>
public sealed class NullPlayerInput : IPlayerInput
{
public static readonly NullPlayerInput Instance = new();
public bool Left => false;
public bool Right => false;
public bool Up => false;
public bool Down => false;
public bool LeftJust => false;
public bool RightJust => false;
public bool UpJust => false;
public bool DownJust => false;
}