extends Control ## Intro menu: Siim's arena mockup as a looping video background with an ## overlaid Play / Options / Credits / Exit UI positioned over his sketch. ## Play fades to black and loads the game; Options rebinds controls. const GAME_SCENE := "res://scene.tscn" const FADE_TIME := 0.6 ## Friendly labels for the rebindable actions (order defines list order). const ACTION_LABELS: Dictionary = { &"move_forward": "Move Forward", &"move_back": "Move Back", &"move_left": "Move Left", &"move_right": "Move Right", &"charge": "Charge", &"ability_kick": "Kick", &"ability_slam": "Slam", &"ability_dash": "Dash", } @onready var main_panel: Control = $MainPanel @onready var options_panel: Control = $OptionsPanel @onready var credits_panel: Control = $CreditsPanel @onready var rebind_list: VBoxContainer = $OptionsPanel/VBox/Scroll/RebindList @onready var fade_rect: ColorRect = $FadeRect @onready var play_button: Button = $MainPanel/PlayButton @onready var options_button: Button = $MainPanel/OptionsButton @onready var credits_button: Button = $MainPanel/CreditsButton @onready var exit_button: Button = $MainPanel/ExitButton @onready var options_back: Button = $OptionsPanel/VBox/BackButton @onready var credits_back: Button = $CreditsPanel/VBox/BackButton @onready var video: VideoStreamPlayer = $VideoStreamPlayer var _listening_action: StringName = &"" var _listening_button: Button = null func _ready() -> void: Input.mouse_mode = Input.MOUSE_MODE_VISIBLE options_panel.visible = false credits_panel.visible = false fade_rect.color = Color(0, 0, 0, 0) if video.stream != null: video.play() video.finished.connect(video.play) # loop the background clip play_button.pressed.connect(_on_play_pressed) options_button.pressed.connect(_on_options_pressed) credits_button.pressed.connect(_on_credits_pressed) exit_button.pressed.connect(_on_exit_pressed) options_back.pressed.connect(_close_subpanels) credits_back.pressed.connect(_close_subpanels) _build_rebind_rows() play_button.grab_focus() func _build_rebind_rows() -> void: for child in rebind_list.get_children(): child.queue_free() for action: StringName in ACTION_LABELS: var row := HBoxContainer.new() row.size_flags_horizontal = Control.SIZE_EXPAND_FILL var name_label := Label.new() name_label.text = ACTION_LABELS[action] name_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL name_label.add_theme_color_override("font_outline_color", Color.BLACK) name_label.add_theme_constant_override("outline_size", 4) row.add_child(name_label) var key_button := Button.new() key_button.custom_minimum_size = Vector2(160, 0) key_button.text = Controls.get_key_label(action) key_button.pressed.connect(_on_rebind_pressed.bind(action, key_button)) row.add_child(key_button) rebind_list.add_child(row) func _on_play_pressed() -> void: _set_buttons_disabled(true) var tween := create_tween() tween.tween_property(fade_rect, "color:a", 1.0, FADE_TIME) tween.tween_callback(func() -> void: get_tree().change_scene_to_file(GAME_SCENE)) func _on_options_pressed() -> void: main_panel.visible = false options_panel.visible = true options_back.grab_focus() func _on_credits_pressed() -> void: main_panel.visible = false credits_panel.visible = true credits_back.grab_focus() func _on_exit_pressed() -> void: get_tree().quit() func _close_subpanels() -> void: _cancel_listening() options_panel.visible = false credits_panel.visible = false main_panel.visible = true play_button.grab_focus() func _set_buttons_disabled(value: bool) -> void: play_button.disabled = value options_button.disabled = value credits_button.disabled = value exit_button.disabled = value func _on_rebind_pressed(action: StringName, button: Button) -> void: _cancel_listening() _listening_action = action _listening_button = button button.text = "Press a key…" func _cancel_listening() -> void: if _listening_button != null: _listening_button.text = Controls.get_key_label(_listening_action) _listening_action = &"" _listening_button = null func _unhandled_input(event: InputEvent) -> void: if _listening_action == &"": return if event is InputEventKey and event.pressed and not event.echo: if event.physical_keycode == KEY_ESCAPE: _cancel_listening() else: var new_event := InputEventKey.new() new_event.physical_keycode = event.physical_keycode Controls.rebind(_listening_action, new_event) _listening_button.text = Controls.get_key_label(_listening_action) _listening_action = &"" _listening_button = null get_viewport().set_input_as_handled()