Initial commit: Theriapolis baseline at port/godot branch point
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Theriapolis.Game.Input;
|
||||
|
||||
/// <summary>
|
||||
/// Single-frame input snapshot with helper methods.
|
||||
/// Call Update() once per frame before any input queries.
|
||||
/// </summary>
|
||||
public sealed class InputManager
|
||||
{
|
||||
private KeyboardState _prevKeys;
|
||||
private KeyboardState _currKeys;
|
||||
private MouseState _prevMouse;
|
||||
private MouseState _currMouse;
|
||||
|
||||
public void Update()
|
||||
{
|
||||
_prevKeys = _currKeys;
|
||||
_currKeys = Keyboard.GetState();
|
||||
_prevMouse = _currMouse;
|
||||
_currMouse = Mouse.GetState();
|
||||
}
|
||||
|
||||
// ── Keyboard ──────────────────────────────────────────────────────────────
|
||||
public bool IsDown(Keys key) => _currKeys.IsKeyDown(key);
|
||||
public bool JustPressed(Keys key) => _currKeys.IsKeyDown(key) && _prevKeys.IsKeyUp(key);
|
||||
public bool JustReleased(Keys key) => _currKeys.IsKeyUp(key) && _prevKeys.IsKeyDown(key);
|
||||
|
||||
// ── Mouse ─────────────────────────────────────────────────────────────────
|
||||
public Vector2 MousePosition => new(_currMouse.X, _currMouse.Y);
|
||||
public bool LeftDown => _currMouse.LeftButton == ButtonState.Pressed;
|
||||
public bool LeftJustDown => _currMouse.LeftButton == ButtonState.Pressed && _prevMouse.LeftButton == ButtonState.Released;
|
||||
public bool LeftJustUp => _currMouse.LeftButton == ButtonState.Released && _prevMouse.LeftButton == ButtonState.Pressed;
|
||||
public bool RightDown => _currMouse.RightButton == ButtonState.Pressed;
|
||||
public bool RightJustDown => _currMouse.RightButton == ButtonState.Pressed && _prevMouse.RightButton == ButtonState.Released;
|
||||
|
||||
/// <summary>Mouse wheel delta in scroll "ticks" (positive = forward/up).</summary>
|
||||
public int ScrollDelta => _currMouse.ScrollWheelValue - _prevMouse.ScrollWheelValue;
|
||||
|
||||
private Vector2 _dragStart;
|
||||
private bool _dragging;
|
||||
private bool _dragActivated;
|
||||
private const float DragActivationPixels = 4f;
|
||||
public bool IsDragging => _dragging;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the world-space pan delta from mouse dragging. Panning is
|
||||
/// suppressed until the mouse moves more than <see cref="DragActivationPixels"/>
|
||||
/// from the press position, so hand-jitter during a click doesn't pan the
|
||||
/// camera (at low zoom, one screen pixel can be many world pixels).
|
||||
/// </summary>
|
||||
public Vector2 ConsumeDragDelta(Rendering.Camera2D camera)
|
||||
{
|
||||
if (LeftJustDown)
|
||||
{
|
||||
_dragStart = MousePosition;
|
||||
_dragging = true;
|
||||
_dragActivated = false;
|
||||
}
|
||||
if (LeftJustUp)
|
||||
{
|
||||
_dragging = false;
|
||||
_dragActivated = false;
|
||||
}
|
||||
|
||||
if (!_dragging || !LeftDown) return Vector2.Zero;
|
||||
|
||||
if (!_dragActivated)
|
||||
{
|
||||
if (Vector2.Distance(MousePosition, _dragStart) < DragActivationPixels)
|
||||
return Vector2.Zero;
|
||||
_dragActivated = true;
|
||||
_dragStart = MousePosition; // start panning from here, not from press
|
||||
}
|
||||
|
||||
Vector2 delta = MousePosition - _dragStart;
|
||||
_dragStart = MousePosition;
|
||||
return -delta / camera.Zoom;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user