Show Xbox-style A/B/X/Y glyphs on the ability bar for a gamepad
Controls now tracks whether the player's last deliberate press was a gamepad button/stick or a keyboard key/mouse click (ignoring plain mouse motion, since the mouse still drives the camera regardless of which device moves the bull). The HUD's ability-bar keycaps read from that: keyboard letters normally, Xbox-style face-button glyphs while a gamepad is in use, swapping live the moment the player switches devices. Godot's joypad button indices are already Xbox-position-normalized (by SDL natively, by the browser's Standard Gamepad Mapping on web), so the glyph mapping (button 0/1/2/3 -> A/B/X/Y) reads correctly for any controller brand with no per-device special-casing. Verified headlessly: labels start as the bound keyboard letters (F/G/H/J), switch to X/A/B/Y on a synthetic joypad button press (matching project.godot's kick/dash/slam/roll bindings), and switch back on a keyboard press. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MXBNaEBmrYDSMcv4NgUWtV
This commit is contained in:
@@ -27,6 +27,64 @@ func _ready() -> void:
|
||||
_install_web_fullscreen_hook()
|
||||
|
||||
|
||||
# ── Active input device ──────────────────────────────────────────────────────────
|
||||
# Tracks whether the player's last deliberate input was a gamepad or keyboard/mouse, so the
|
||||
# HUD can swap its ability-bar keycaps to match whichever the player is actually holding.
|
||||
# Mouse motion is deliberately ignored — the mouse still drives the camera regardless of
|
||||
# which device is moving the bull, so panning the camera shouldn't flip the hint away from
|
||||
# gamepad glyphs. A small deadzone on joypad axes avoids stick drift/noise doing the same.
|
||||
const _JOY_AXIS_DEADZONE := 0.5
|
||||
var _last_input_is_gamepad: bool = false
|
||||
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventJoypadButton:
|
||||
if event.pressed:
|
||||
_last_input_is_gamepad = true
|
||||
elif event is InputEventJoypadMotion:
|
||||
if absf(event.axis_value) > _JOY_AXIS_DEADZONE:
|
||||
_last_input_is_gamepad = true
|
||||
elif event is InputEventKey:
|
||||
if event.pressed:
|
||||
_last_input_is_gamepad = false
|
||||
elif event is InputEventMouseButton:
|
||||
if event.pressed:
|
||||
_last_input_is_gamepad = false
|
||||
|
||||
|
||||
## Whether the player's last button/key/stick press was on a gamepad rather than
|
||||
## keyboard/mouse. Drives which glyph set the HUD's ability keycaps show.
|
||||
func using_gamepad() -> bool:
|
||||
return _last_input_is_gamepad
|
||||
|
||||
|
||||
# Godot's joypad button indices are already Xbox-position-normalized — by SDL on native, by
|
||||
# the browser's Standard Gamepad Mapping on web — so this reads correctly for any controller
|
||||
# brand (a Nintendo pad's physically-labelled "A" is button 1 here, same as "B" on Xbox).
|
||||
const _XBOX_BUTTON_GLYPHS := {
|
||||
JOY_BUTTON_A: "A",
|
||||
JOY_BUTTON_B: "B",
|
||||
JOY_BUTTON_X: "X",
|
||||
JOY_BUTTON_Y: "Y",
|
||||
}
|
||||
|
||||
|
||||
## Xbox-style face-button glyph ("A"/"B"/"X"/"Y") for the action's bound joypad button, or
|
||||
## "—" if it has none.
|
||||
func get_joy_button_label(action: StringName) -> String:
|
||||
for event: InputEvent in InputMap.action_get_events(action):
|
||||
if event is InputEventJoypadButton:
|
||||
return _XBOX_BUTTON_GLYPHS.get(event.button_index, "?")
|
||||
return "—"
|
||||
|
||||
|
||||
## Ability-bar keycap label for `action`: the bound Xbox-style face button while a gamepad
|
||||
## is in use, else the bound keyboard key — so the on-screen prompt always matches whichever
|
||||
## the player is actually holding.
|
||||
func ability_key_label(action: StringName) -> String:
|
||||
return get_joy_button_label(action) if using_gamepad() else get_key_label(action)
|
||||
|
||||
|
||||
## Godot's built-in ui_accept (menu/button confirm) ships with zero joypad bindings —
|
||||
## checked directly: only Enter/Kp Enter/Space. ui_left/right/up/down, by contrast, do
|
||||
## default to the D-pad and stick, which is why gamepad focus navigation on a menu works out
|
||||
|
||||
Reference in New Issue
Block a user