Геймпад Xbox, меню паузы с настройками, новый хаб с музыкой

- Геймпад: раскладка под паркур и гонки, обзор правым стиком, навигация по меню (A/B/крестовина)
- Меню паузы (Esc/Start): выход в хаб, настройки (мышь, стик, FOV, громкость, инверсия), справка по управлению
- Хаб 48x32x10 м: колонны, окна с городом, голограмма, лавки; музыка «Local Forecast - Elevator» (Kevin MacLeod, CC-BY)
- Тесты: pause_test, pad_menu_test, hub_tour; README обновлён

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-31 18:36:50 +05:00
co-authored by Claude Sonnet 5.5
parent 0ffba7311f
commit 2d347d132b
27 changed files with 1220 additions and 41 deletions
+33
View File
@@ -0,0 +1,33 @@
extends Node
# Геймпад в меню паузы: фокус, A выбирает, крестовина двигает.
func frames(n: int) -> void:
for i in n:
await get_tree().process_frame
func btn(b: JoyButton, pressed: bool) -> void:
var e := InputEventJoypadButton.new()
e.button_index = b
e.pressed = pressed
Input.parse_input_event(e)
func _ready() -> void:
Net.nick_asked = true
add_child((load("res://maps/hub/hub.tscn") as PackedScene).instantiate())
await frames(5)
PauseMenu.open_menu()
await frames(5)
var f := get_viewport().gui_get_focus_owner()
print("фокус: ", f, " текст: ", f.text if f else "—")
btn(JOY_BUTTON_DPAD_DOWN, true); await frames(2); btn(JOY_BUTTON_DPAD_DOWN, false); await frames(2)
f = get_viewport().gui_get_focus_owner()
print("после вниз: ", f.text if f else "—")
btn(JOY_BUTTON_DPAD_UP, true); await frames(2); btn(JOY_BUTTON_DPAD_UP, false); await frames(2)
btn(JOY_BUTTON_A, true); await frames(2); btn(JOY_BUTTON_A, false); await frames(3)
print("после A на «Продолжить»: меню открыто = ", PauseMenu.open)
PauseMenu.open_menu(); await frames(5)
btn(JOY_BUTTON_DPAD_DOWN, true); await frames(2); btn(JOY_BUTTON_DPAD_DOWN, false); await frames(2)
btn(JOY_BUTTON_DPAD_DOWN, true); await frames(2); btn(JOY_BUTTON_DPAD_DOWN, false); await frames(2)
btn(JOY_BUTTON_DPAD_DOWN, true); await frames(2); btn(JOY_BUTTON_DPAD_DOWN, false); await frames(2)
f = get_viewport().gui_get_focus_owner()
print("фокус перед A: ", f.text if f else "—")
btn(JOY_BUTTON_A, true); await frames(2); btn(JOY_BUTTON_A, false); await frames(3)
print("страница после A: ", PauseMenu._page)
get_tree().quit()