Expand bubble menu presentation
This commit is contained in:
parent
359a96f6e2
commit
f04d8db8ac
10 changed files with 1016 additions and 165 deletions
|
|
@ -53,7 +53,7 @@ signal interactive_pointer_ui_changed(is_open: bool)
|
||||||
@onready var _shop_prompt: PanelContainer = %ShopPrompt
|
@onready var _shop_prompt: PanelContainer = %ShopPrompt
|
||||||
@onready var _effect_status: Label = %EffectStatus
|
@onready var _effect_status: Label = %EffectStatus
|
||||||
@onready var _title_settings_panel: SettingsPanelType = (
|
@onready var _title_settings_panel: SettingsPanelType = (
|
||||||
$UIRoot/TitleScreen/SettingsPanel
|
$UIRoot/TitleScreen/ResponsiveTitleStage/TitlePresentationScaleRoot/SettingsPanel
|
||||||
)
|
)
|
||||||
@onready var _pause_settings_panel: SettingsPanelType = (
|
@onready var _pause_settings_panel: SettingsPanelType = (
|
||||||
$UIRoot/PauseMenu/SettingsCenter/SettingsPanel
|
$UIRoot/PauseMenu/SettingsCenter/SettingsPanel
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,64 @@
|
||||||
class_name PixelationResetOverlay
|
class_name PixelationResetOverlay
|
||||||
extends CanvasLayer
|
extends CanvasLayer
|
||||||
|
|
||||||
|
const DISPLAY_REFERENCE_SIZE: Vector2 = Vector2(1280.0, 720.0)
|
||||||
|
const MINIMUM_PRESENTATION_SCALE: float = 0.90
|
||||||
|
const MAXIMUM_PRESENTATION_SCALE: float = 1.35
|
||||||
|
const LARGE_DISPLAY_GROWTH: float = 0.45
|
||||||
|
const SCREEN_MARGIN: float = 16.0
|
||||||
|
const FADE_DURATION: float = 0.55
|
||||||
|
|
||||||
signal reset_requested
|
signal reset_requested
|
||||||
signal return_to_settings_requested
|
signal return_to_settings_requested
|
||||||
|
|
||||||
|
@onready var _presentation_root: Control = %ResetPresentationRoot
|
||||||
@onready var _reset_button: Button = %ResetPixelationButton
|
@onready var _reset_button: Button = %ResetPixelationButton
|
||||||
|
|
||||||
|
var _fade_tween: Tween
|
||||||
|
var _fade_generation: int = 0
|
||||||
|
var _settings_open: bool = false
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
_reset_button.pressed.connect(reset_requested.emit)
|
_reset_button.pressed.connect(reset_requested.emit)
|
||||||
_reset_button.gui_input.connect(_on_reset_button_gui_input)
|
_reset_button.gui_input.connect(_on_reset_button_gui_input)
|
||||||
|
get_viewport().size_changed.connect(_update_responsive_layout)
|
||||||
|
_presentation_root.modulate.a = 0.0
|
||||||
|
_set_interactive(false)
|
||||||
|
_update_responsive_layout()
|
||||||
|
|
||||||
|
|
||||||
func set_settings_open(is_open: bool) -> void:
|
func set_settings_open(is_open: bool) -> void:
|
||||||
visible = is_open
|
_settings_open = is_open
|
||||||
if not is_open and _reset_button.has_focus():
|
_fade_generation += 1
|
||||||
_reset_button.release_focus()
|
if _fade_tween != null:
|
||||||
|
_fade_tween.kill()
|
||||||
|
_fade_tween = null
|
||||||
|
if is_open:
|
||||||
|
show()
|
||||||
|
_set_interactive(true)
|
||||||
|
else:
|
||||||
|
_set_interactive(false)
|
||||||
|
var target_alpha: float = 1.0 if is_open else 0.0
|
||||||
|
if is_equal_approx(_presentation_root.modulate.a, target_alpha):
|
||||||
|
_finish_fade(_fade_generation, is_open)
|
||||||
|
return
|
||||||
|
var generation: int = _fade_generation
|
||||||
|
_fade_tween = create_tween()
|
||||||
|
_fade_tween.tween_property(
|
||||||
|
_presentation_root,
|
||||||
|
"modulate:a",
|
||||||
|
target_alpha,
|
||||||
|
FADE_DURATION
|
||||||
|
).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_fade_tween.finished.connect(
|
||||||
|
_finish_fade.bind(generation, is_open),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func focus_reset_button() -> void:
|
func focus_reset_button() -> void:
|
||||||
if visible:
|
if visible and _settings_open:
|
||||||
_reset_button.grab_focus()
|
_reset_button.grab_focus()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,3 +69,55 @@ func _on_reset_button_gui_input(event: InputEvent) -> void:
|
||||||
):
|
):
|
||||||
return_to_settings_requested.emit()
|
return_to_settings_requested.emit()
|
||||||
get_viewport().set_input_as_handled()
|
get_viewport().set_input_as_handled()
|
||||||
|
|
||||||
|
|
||||||
|
func _update_responsive_layout() -> void:
|
||||||
|
if not is_node_ready():
|
||||||
|
return
|
||||||
|
var display_size: Vector2 = Vector2(get_window().size)
|
||||||
|
if display_size.x <= 1.0 or display_size.y <= 1.0:
|
||||||
|
return
|
||||||
|
var responsive_scale: float = minf(
|
||||||
|
display_size.x / DISPLAY_REFERENCE_SIZE.x,
|
||||||
|
display_size.y / DISPLAY_REFERENCE_SIZE.y
|
||||||
|
)
|
||||||
|
var presentation_scale: float
|
||||||
|
if responsive_scale < 1.0:
|
||||||
|
presentation_scale = lerpf(
|
||||||
|
MINIMUM_PRESENTATION_SCALE,
|
||||||
|
1.0,
|
||||||
|
clampf((responsive_scale - 0.5) / 0.5, 0.0, 1.0)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
presentation_scale = minf(
|
||||||
|
MAXIMUM_PRESENTATION_SCALE,
|
||||||
|
1.0 + (responsive_scale - 1.0) * LARGE_DISPLAY_GROWTH
|
||||||
|
)
|
||||||
|
_presentation_root.scale = Vector2.ONE * presentation_scale
|
||||||
|
_presentation_root.position = (
|
||||||
|
display_size
|
||||||
|
- _presentation_root.size * presentation_scale
|
||||||
|
- Vector2.ONE * SCREEN_MARGIN
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _set_interactive(interactive: bool) -> void:
|
||||||
|
if not interactive and _reset_button.has_focus():
|
||||||
|
_reset_button.release_focus()
|
||||||
|
_reset_button.focus_mode = (
|
||||||
|
Control.FOCUS_ALL if interactive else Control.FOCUS_NONE
|
||||||
|
)
|
||||||
|
_reset_button.mouse_filter = (
|
||||||
|
Control.MOUSE_FILTER_STOP
|
||||||
|
if interactive
|
||||||
|
else Control.MOUSE_FILTER_IGNORE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_fade(generation: int, faded_in: bool) -> void:
|
||||||
|
if generation != _fade_generation or faded_in != _settings_open:
|
||||||
|
return
|
||||||
|
_fade_tween = null
|
||||||
|
_presentation_root.modulate.a = 1.0 if faded_in else 0.0
|
||||||
|
if not faded_in:
|
||||||
|
hide()
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,104 @@
|
||||||
[gd_scene load_steps=3 format=3]
|
[gd_scene load_steps=7 format=3]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://ui/pixelation_reset_overlay.gd" id="1_script"]
|
[ext_resource type="Script" path="res://ui/pixelation_reset_overlay.gd" id="1_script"]
|
||||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBox_reset_normal"]
|
||||||
|
content_margin_left = 18.0
|
||||||
|
content_margin_top = 18.0
|
||||||
|
content_margin_right = 18.0
|
||||||
|
content_margin_bottom = 18.0
|
||||||
|
bg_color = Color(0.035, 0.145, 0.22, 1)
|
||||||
|
border_width_left = 2
|
||||||
|
border_width_top = 2
|
||||||
|
border_width_right = 2
|
||||||
|
border_width_bottom = 2
|
||||||
|
border_color = Color(0.91, 0.98, 1, 0.85)
|
||||||
|
corner_radius_top_left = 74
|
||||||
|
corner_radius_top_right = 74
|
||||||
|
corner_radius_bottom_right = 74
|
||||||
|
corner_radius_bottom_left = 74
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBox_reset_hover"]
|
||||||
|
content_margin_left = 18.0
|
||||||
|
content_margin_top = 18.0
|
||||||
|
content_margin_right = 18.0
|
||||||
|
content_margin_bottom = 18.0
|
||||||
|
bg_color = Color(0.055, 0.205, 0.29, 1)
|
||||||
|
border_width_left = 3
|
||||||
|
border_width_top = 3
|
||||||
|
border_width_right = 3
|
||||||
|
border_width_bottom = 3
|
||||||
|
border_color = Color(0.91, 0.975, 0.985, 1)
|
||||||
|
corner_radius_top_left = 74
|
||||||
|
corner_radius_top_right = 74
|
||||||
|
corner_radius_bottom_right = 74
|
||||||
|
corner_radius_bottom_left = 74
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBox_reset_pressed"]
|
||||||
|
content_margin_left = 18.0
|
||||||
|
content_margin_top = 18.0
|
||||||
|
content_margin_right = 18.0
|
||||||
|
content_margin_bottom = 18.0
|
||||||
|
bg_color = Color(0.025, 0.12, 0.19, 1)
|
||||||
|
border_width_left = 3
|
||||||
|
border_width_top = 3
|
||||||
|
border_width_right = 3
|
||||||
|
border_width_bottom = 3
|
||||||
|
border_color = Color(0.94, 0.99, 1, 1)
|
||||||
|
corner_radius_top_left = 74
|
||||||
|
corner_radius_top_right = 74
|
||||||
|
corner_radius_bottom_right = 74
|
||||||
|
corner_radius_bottom_left = 74
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBox_reset_disabled"]
|
||||||
|
content_margin_left = 18.0
|
||||||
|
content_margin_top = 18.0
|
||||||
|
content_margin_right = 18.0
|
||||||
|
content_margin_bottom = 18.0
|
||||||
|
bg_color = Color(0.035, 0.145, 0.22, 0.72)
|
||||||
|
border_width_left = 2
|
||||||
|
border_width_top = 2
|
||||||
|
border_width_right = 2
|
||||||
|
border_width_bottom = 2
|
||||||
|
border_color = Color(0.81, 0.9, 0.92, 0.55)
|
||||||
|
corner_radius_top_left = 74
|
||||||
|
corner_radius_top_right = 74
|
||||||
|
corner_radius_bottom_right = 74
|
||||||
|
corner_radius_bottom_left = 74
|
||||||
|
|
||||||
[node name="PixelationResetOverlay" type="CanvasLayer"]
|
[node name="PixelationResetOverlay" type="CanvasLayer"]
|
||||||
layer = 300
|
layer = 300
|
||||||
visible = false
|
visible = false
|
||||||
script = ExtResource("1_script")
|
script = ExtResource("1_script")
|
||||||
|
|
||||||
[node name="ResetAnchor" type="MarginContainer" parent="."]
|
[node name="ResetPresentationRoot" type="Control" parent="."]
|
||||||
anchors_preset = 3
|
unique_name_in_owner = true
|
||||||
anchor_left = 1.0
|
offset_right = 156.0
|
||||||
anchor_top = 1.0
|
offset_bottom = 148.0
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = -324.0
|
|
||||||
offset_top = -86.0
|
|
||||||
offset_right = -16.0
|
|
||||||
offset_bottom = -16.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
grow_vertical = 0
|
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
theme = ExtResource("2_theme")
|
theme = ExtResource("2_theme")
|
||||||
|
|
||||||
[node name="ResetPixelationButton" type="Button" parent="ResetAnchor"]
|
[node name="ResetPixelationButton" type="Button" parent="ResetPresentationRoot"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(308, 70)
|
custom_minimum_size = Vector2(156, 148)
|
||||||
layout_mode = 2
|
layout_mode = 1
|
||||||
text = "reset pixelation"
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
tooltip_text = "reset pixelation"
|
||||||
|
accessibility_name = "reset pixelation"
|
||||||
|
theme_override_colors/font_color = Color(0.82, 0.93, 0.96, 1)
|
||||||
|
theme_override_colors/font_hover_color = Color(0.91, 0.975, 0.985, 1)
|
||||||
|
theme_override_colors/font_focus_color = Color(0.91, 0.975, 0.985, 1)
|
||||||
|
theme_override_colors/font_pressed_color = Color(0.7, 0.87, 0.92, 1)
|
||||||
|
theme_override_colors/font_disabled_color = Color(0.66, 0.77, 0.8, 0.78)
|
||||||
|
theme_override_font_sizes/font_size = 26
|
||||||
|
theme_override_styles/normal = SubResource("StyleBox_reset_normal")
|
||||||
|
theme_override_styles/hover = SubResource("StyleBox_reset_hover")
|
||||||
|
theme_override_styles/pressed = SubResource("StyleBox_reset_pressed")
|
||||||
|
theme_override_styles/focus = SubResource("StyleBox_reset_hover")
|
||||||
|
theme_override_styles/disabled = SubResource("StyleBox_reset_disabled")
|
||||||
|
text = "reset\npixelation"
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ extends Control
|
||||||
@export var compact_maximum_layout_size: Vector2 = Vector2.ZERO
|
@export var compact_maximum_layout_size: Vector2 = Vector2.ZERO
|
||||||
@export var compact_width_threshold: float = 680.0
|
@export var compact_width_threshold: float = 680.0
|
||||||
@export var compact_height_threshold: float = 500.0
|
@export var compact_height_threshold: float = 500.0
|
||||||
@export_range(0.1, 2.0, 0.01) var outgoing_rise_duration: float = 0.95
|
@export_range(0.1, 2.0, 0.01) var outgoing_rise_duration: float = 1.70
|
||||||
@export_range(0.1, 2.0, 0.01) var incoming_rise_duration: float = 1.05
|
@export_range(0.1, 2.0, 0.01) var incoming_rise_duration: float = 1.85
|
||||||
@export_range(0.0, 128.0, 1.0) var transition_safe_margin: float = 24.0
|
@export_range(0.0, 128.0, 1.0) var transition_safe_margin: float = 24.0
|
||||||
|
|
||||||
var _cluster: BubbleCluster
|
var _cluster: BubbleCluster
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ signal closed
|
||||||
signal opened
|
signal opened
|
||||||
signal crisp_reset_focus_requested
|
signal crisp_reset_focus_requested
|
||||||
signal panel_visibility_changed(is_visible: bool)
|
signal panel_visibility_changed(is_visible: bool)
|
||||||
|
signal navigation_transition_started
|
||||||
|
|
||||||
enum PresentationMode {
|
enum PresentationMode {
|
||||||
TITLE_EMBEDDED,
|
TITLE_EMBEDDED,
|
||||||
|
|
@ -226,6 +227,7 @@ func _start_page_transition(page_id: StringName, push_page: bool) -> void:
|
||||||
return
|
return
|
||||||
_page_transition_generation += 1
|
_page_transition_generation += 1
|
||||||
_page_transition_active = true
|
_page_transition_active = true
|
||||||
|
navigation_transition_started.emit()
|
||||||
var generation: int = _page_transition_generation
|
var generation: int = _page_transition_generation
|
||||||
outgoing_page.transition_out(
|
outgoing_page.transition_out(
|
||||||
_finish_outgoing_page.bind(
|
_finish_outgoing_page.bind(
|
||||||
|
|
@ -277,6 +279,7 @@ func _begin_embedded_close(applied_result: bool) -> void:
|
||||||
return
|
return
|
||||||
_page_transition_generation += 1
|
_page_transition_generation += 1
|
||||||
_page_transition_active = true
|
_page_transition_active = true
|
||||||
|
navigation_transition_started.emit()
|
||||||
var generation: int = _page_transition_generation
|
var generation: int = _page_transition_generation
|
||||||
active_page.transition_out(
|
active_page.transition_out(
|
||||||
_finish_embedded_close.bind(generation, applied_result),
|
_finish_embedded_close.bind(generation, applied_result),
|
||||||
|
|
|
||||||
252
ui/title_confirmation_bubble_page.gd
Normal file
252
ui/title_confirmation_bubble_page.gd
Normal file
|
|
@ -0,0 +1,252 @@
|
||||||
|
class_name TitleConfirmationBubblePage
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
signal confirmed
|
||||||
|
signal cancelled
|
||||||
|
|
||||||
|
@export var cluster_path: NodePath = ^"BubbleCluster"
|
||||||
|
@export var prompt_path: NodePath = ^"BubbleCluster/PromptBubble"
|
||||||
|
@export var prompt_label_path: NodePath = ^"BubbleCluster/PromptBubble/PromptLabel"
|
||||||
|
@export var confirm_path: NodePath = ^"BubbleCluster/ConfirmButton"
|
||||||
|
@export var confirm_label_path: NodePath = (
|
||||||
|
^"BubbleCluster/ConfirmButton/ConfirmLabel"
|
||||||
|
)
|
||||||
|
@export var cancel_path: NodePath = ^"BubbleCluster/CancelButton"
|
||||||
|
@export var multiline_confirm_neutral_size: Vector2 = Vector2(116.0, 116.0)
|
||||||
|
@export var multiline_confirm_compact_minimum_size: Vector2 = (
|
||||||
|
Vector2(90.0, 90.0)
|
||||||
|
)
|
||||||
|
@export var compact_height_threshold: float = 250.0
|
||||||
|
@export_range(0.0, 128.0, 1.0) var transition_safe_margin: float = 24.0
|
||||||
|
|
||||||
|
var _cluster: BubbleCluster
|
||||||
|
var _prompt: BubbleButton
|
||||||
|
var _prompt_label: Label
|
||||||
|
var _confirm_button: BubbleButton
|
||||||
|
var _confirm_label: Label
|
||||||
|
var _cancel_button: BubbleButton
|
||||||
|
var _default_confirm_neutral_size: Vector2
|
||||||
|
var _default_confirm_compact_minimum_size: Vector2
|
||||||
|
var _bubbles: Array[BubbleButton] = []
|
||||||
|
var _resting_cluster_position: Vector2 = Vector2.ZERO
|
||||||
|
var _transition: Tween
|
||||||
|
var _transition_generation: int = 0
|
||||||
|
var _is_transitioning: bool = false
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
_cluster = get_node(cluster_path) as BubbleCluster
|
||||||
|
_prompt = get_node(prompt_path) as BubbleButton
|
||||||
|
_prompt_label = get_node(prompt_label_path) as Label
|
||||||
|
_confirm_button = get_node(confirm_path) as BubbleButton
|
||||||
|
_confirm_label = get_node(confirm_label_path) as Label
|
||||||
|
_cancel_button = get_node(cancel_path) as BubbleButton
|
||||||
|
_default_confirm_neutral_size = _confirm_button.neutral_size
|
||||||
|
_default_confirm_compact_minimum_size = (
|
||||||
|
_confirm_button.compact_minimum_size
|
||||||
|
)
|
||||||
|
_bubbles = [_prompt, _confirm_button, _cancel_button]
|
||||||
|
_cluster.configure(_bubbles)
|
||||||
|
_prompt.focus_mode = Control.FOCUS_NONE
|
||||||
|
_prompt.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||||
|
_confirm_button.pressed.connect(confirmed.emit)
|
||||||
|
_cancel_button.pressed.connect(cancelled.emit)
|
||||||
|
_configure_focus()
|
||||||
|
hide_page()
|
||||||
|
|
||||||
|
|
||||||
|
func configure(
|
||||||
|
prompt_text: String,
|
||||||
|
confirm_text: String,
|
||||||
|
use_multiline_action_layout: bool = false,
|
||||||
|
) -> void:
|
||||||
|
_prompt_label.text = prompt_text
|
||||||
|
if use_multiline_action_layout:
|
||||||
|
_confirm_button.text = ""
|
||||||
|
_confirm_label.text = confirm_text
|
||||||
|
_confirm_label.show()
|
||||||
|
_confirm_button.label_control_path = ^"ConfirmLabel"
|
||||||
|
else:
|
||||||
|
_confirm_label.text = ""
|
||||||
|
_confirm_label.hide()
|
||||||
|
_confirm_button.label_control_path = NodePath()
|
||||||
|
_confirm_button.text = confirm_text
|
||||||
|
_confirm_button.apply_profile()
|
||||||
|
_confirm_button.neutral_size = (
|
||||||
|
multiline_confirm_neutral_size
|
||||||
|
if use_multiline_action_layout
|
||||||
|
else _default_confirm_neutral_size
|
||||||
|
)
|
||||||
|
_confirm_button.compact_minimum_size = (
|
||||||
|
multiline_confirm_compact_minimum_size
|
||||||
|
if use_multiline_action_layout
|
||||||
|
else _default_confirm_compact_minimum_size
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func set_stage_rect(stage_rect: Rect2) -> void:
|
||||||
|
if not is_node_ready():
|
||||||
|
return
|
||||||
|
var field_size := Vector2(
|
||||||
|
maxf(1.0, stage_rect.size.x),
|
||||||
|
maxf(1.0, stage_rect.size.y)
|
||||||
|
)
|
||||||
|
_resting_cluster_position = stage_rect.position
|
||||||
|
_cluster.size = field_size
|
||||||
|
_cluster.apply_layout(
|
||||||
|
field_size,
|
||||||
|
field_size.y < compact_height_threshold
|
||||||
|
)
|
||||||
|
if not _is_transitioning:
|
||||||
|
_cluster.position = _resting_cluster_position
|
||||||
|
|
||||||
|
|
||||||
|
func transition_in(
|
||||||
|
duration: float,
|
||||||
|
completed: Callable,
|
||||||
|
) -> void:
|
||||||
|
_transition_generation += 1
|
||||||
|
_cancel_transition()
|
||||||
|
show()
|
||||||
|
_is_transitioning = true
|
||||||
|
_set_interactive(false)
|
||||||
|
set_process(true)
|
||||||
|
_cluster.position = Vector2(
|
||||||
|
_resting_cluster_position.x,
|
||||||
|
size.y + transition_safe_margin
|
||||||
|
)
|
||||||
|
var generation: int = _transition_generation
|
||||||
|
_transition = create_tween()
|
||||||
|
_transition.tween_property(
|
||||||
|
_cluster,
|
||||||
|
"position",
|
||||||
|
_resting_cluster_position,
|
||||||
|
duration
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_transition.finished.connect(
|
||||||
|
_finish_transition_in.bind(generation, completed),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func transition_out(
|
||||||
|
duration: float,
|
||||||
|
completed: Callable,
|
||||||
|
) -> void:
|
||||||
|
if not visible or _is_transitioning:
|
||||||
|
return
|
||||||
|
_transition_generation += 1
|
||||||
|
_cancel_transition()
|
||||||
|
_is_transitioning = true
|
||||||
|
_set_interactive(false)
|
||||||
|
var generation: int = _transition_generation
|
||||||
|
_transition = create_tween()
|
||||||
|
_transition.tween_property(
|
||||||
|
_cluster,
|
||||||
|
"position:y",
|
||||||
|
-_cluster.size.y - transition_safe_margin,
|
||||||
|
duration
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_transition.finished.connect(
|
||||||
|
_finish_transition_out.bind(generation, completed),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func hide_page() -> void:
|
||||||
|
_transition_generation += 1
|
||||||
|
_cancel_transition()
|
||||||
|
_is_transitioning = false
|
||||||
|
_set_interactive(false)
|
||||||
|
set_process(false)
|
||||||
|
hide()
|
||||||
|
if _cluster != null:
|
||||||
|
_cluster.position = _resting_cluster_position
|
||||||
|
|
||||||
|
|
||||||
|
func lock_interaction() -> void:
|
||||||
|
_set_interactive(false)
|
||||||
|
|
||||||
|
|
||||||
|
func is_transitioning() -> bool:
|
||||||
|
return _is_transitioning
|
||||||
|
|
||||||
|
|
||||||
|
func focus_confirm() -> void:
|
||||||
|
if (
|
||||||
|
_confirm_button.visible
|
||||||
|
and _confirm_button.focus_mode != Control.FOCUS_NONE
|
||||||
|
):
|
||||||
|
_confirm_button.grab_focus()
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
if visible:
|
||||||
|
_cluster.advance_motion(delta)
|
||||||
|
|
||||||
|
|
||||||
|
func _configure_focus() -> void:
|
||||||
|
_confirm_button.focus_neighbor_left = _confirm_button.get_path_to(
|
||||||
|
_cancel_button
|
||||||
|
)
|
||||||
|
_confirm_button.focus_neighbor_right = _confirm_button.focus_neighbor_left
|
||||||
|
_confirm_button.focus_neighbor_top = _confirm_button.focus_neighbor_left
|
||||||
|
_confirm_button.focus_neighbor_bottom = _confirm_button.focus_neighbor_left
|
||||||
|
_cancel_button.focus_neighbor_left = _cancel_button.get_path_to(
|
||||||
|
_confirm_button
|
||||||
|
)
|
||||||
|
_cancel_button.focus_neighbor_right = _cancel_button.focus_neighbor_left
|
||||||
|
_cancel_button.focus_neighbor_top = _cancel_button.focus_neighbor_left
|
||||||
|
_cancel_button.focus_neighbor_bottom = _cancel_button.focus_neighbor_left
|
||||||
|
|
||||||
|
|
||||||
|
func _set_interactive(interactive: bool) -> void:
|
||||||
|
mouse_filter = (
|
||||||
|
Control.MOUSE_FILTER_PASS
|
||||||
|
if interactive
|
||||||
|
else Control.MOUSE_FILTER_IGNORE
|
||||||
|
)
|
||||||
|
for bubble: BubbleButton in [_confirm_button, _cancel_button]:
|
||||||
|
if bubble == null:
|
||||||
|
continue
|
||||||
|
bubble.focus_mode = (
|
||||||
|
Control.FOCUS_ALL if interactive else Control.FOCUS_NONE
|
||||||
|
)
|
||||||
|
bubble.mouse_filter = (
|
||||||
|
Control.MOUSE_FILTER_STOP
|
||||||
|
if interactive
|
||||||
|
else Control.MOUSE_FILTER_IGNORE
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_transition_in(
|
||||||
|
generation: int,
|
||||||
|
completed: Callable,
|
||||||
|
) -> void:
|
||||||
|
if generation != _transition_generation or not visible:
|
||||||
|
return
|
||||||
|
_transition = null
|
||||||
|
_is_transitioning = false
|
||||||
|
_set_interactive(true)
|
||||||
|
focus_confirm()
|
||||||
|
completed.call()
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_transition_out(
|
||||||
|
generation: int,
|
||||||
|
completed: Callable,
|
||||||
|
) -> void:
|
||||||
|
if generation != _transition_generation or not visible:
|
||||||
|
return
|
||||||
|
_transition = null
|
||||||
|
_is_transitioning = false
|
||||||
|
hide()
|
||||||
|
_cluster.position = _resting_cluster_position
|
||||||
|
set_process(false)
|
||||||
|
completed.call()
|
||||||
|
|
||||||
|
|
||||||
|
func _cancel_transition() -> void:
|
||||||
|
if _transition != null:
|
||||||
|
_transition.kill()
|
||||||
|
_transition = null
|
||||||
1
ui/title_confirmation_bubble_page.gd.uid
Normal file
1
ui/title_confirmation_bubble_page.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cvxkxoqfvkp3h
|
||||||
129
ui/title_confirmation_bubble_page.tscn
Normal file
129
ui/title_confirmation_bubble_page.tscn
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
[gd_scene load_steps=6 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://ui/title_confirmation_bubble_page.gd" id="1_page"]
|
||||||
|
[ext_resource type="PackedScene" path="res://ui/components/bubble_menu/bubble_button.tscn" id="2_bubble"]
|
||||||
|
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="3_cluster"]
|
||||||
|
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_menu_profile.gd" id="4_profile_script"]
|
||||||
|
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="5_profile"]
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="BubbleMenuProfile_confirmation_action"]
|
||||||
|
script = ExtResource("4_profile_script")
|
||||||
|
normal_border_width = 3
|
||||||
|
emphasized_border_width = 4
|
||||||
|
|
||||||
|
[node name="TitleConfirmationBubblePage" type="Control"]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
script = ExtResource("1_page")
|
||||||
|
|
||||||
|
[node name="BubbleCluster" type="Control" parent="."]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 396.0
|
||||||
|
offset_bottom = 318.0
|
||||||
|
script = ExtResource("3_cluster")
|
||||||
|
profile = ExtResource("5_profile")
|
||||||
|
desktop_reference_size = Vector2(396, 318)
|
||||||
|
compact_reference_size = Vector2(294, 200)
|
||||||
|
|
||||||
|
[node name="PromptBubble" parent="BubbleCluster" instance=ExtResource("2_bubble")]
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
offset_left = 70.0
|
||||||
|
offset_top = -2.0
|
||||||
|
offset_right = 326.0
|
||||||
|
offset_bottom = 254.0
|
||||||
|
neutral_size = Vector2(256, 256)
|
||||||
|
desktop_anchor = Vector2(198, 126)
|
||||||
|
compact_anchor = Vector2(198, 119)
|
||||||
|
compact_minimum_size = Vector2(190, 190)
|
||||||
|
label_control_path = NodePath("PromptLabel")
|
||||||
|
minimum_font_size = 15
|
||||||
|
maximum_font_size = 26
|
||||||
|
horizontal_amplitude = 1.6
|
||||||
|
vertical_amplitude = 4.2
|
||||||
|
motion_period = 6.4
|
||||||
|
motion_phase = 0.45
|
||||||
|
deformation_amplitude = 0.012
|
||||||
|
deformation_period = 7.1
|
||||||
|
|
||||||
|
[node name="PromptLabel" type="Label" parent="BubbleCluster/PromptBubble"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = 22.0
|
||||||
|
offset_top = 22.0
|
||||||
|
offset_right = -22.0
|
||||||
|
offset_bottom = -22.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
theme_override_colors/font_color = Color(0.035, 0.145, 0.22, 1)
|
||||||
|
theme_override_constants/line_spacing = -2
|
||||||
|
text = "confirm?"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
autowrap_mode = 2
|
||||||
|
|
||||||
|
[node name="ConfirmButton" parent="BubbleCluster" instance=ExtResource("2_bubble")]
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
offset_left = 20.0
|
||||||
|
offset_top = 222.0
|
||||||
|
offset_right = 136.0
|
||||||
|
offset_bottom = 334.0
|
||||||
|
profile = SubResource("BubbleMenuProfile_confirmation_action")
|
||||||
|
neutral_size = Vector2(116, 112)
|
||||||
|
desktop_anchor = Vector2(78, 278)
|
||||||
|
compact_anchor = Vector2(34, 280)
|
||||||
|
compact_minimum_size = Vector2(88, 86)
|
||||||
|
label_control_path = NodePath("ConfirmLabel")
|
||||||
|
minimum_font_size = 14
|
||||||
|
maximum_font_size = 21
|
||||||
|
horizontal_amplitude = 2.0
|
||||||
|
vertical_amplitude = 4.8
|
||||||
|
motion_period = 5.6
|
||||||
|
motion_phase = 2.15
|
||||||
|
deformation_amplitude = 0.016
|
||||||
|
deformation_period = 5.9
|
||||||
|
|
||||||
|
[node name="ConfirmLabel" type="Label" parent="BubbleCluster/ConfirmButton"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = 12.0
|
||||||
|
offset_top = 12.0
|
||||||
|
offset_right = -12.0
|
||||||
|
offset_bottom = -12.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
text = "confirm"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
autowrap_mode = 2
|
||||||
|
|
||||||
|
[node name="CancelButton" parent="BubbleCluster" instance=ExtResource("2_bubble")]
|
||||||
|
custom_minimum_size = Vector2(0, 0)
|
||||||
|
offset_left = 262.0
|
||||||
|
offset_top = 216.0
|
||||||
|
offset_right = 374.0
|
||||||
|
offset_bottom = 324.0
|
||||||
|
text = "cancel"
|
||||||
|
neutral_size = Vector2(112, 108)
|
||||||
|
desktop_anchor = Vector2(318, 270)
|
||||||
|
compact_anchor = Vector2(362, 272)
|
||||||
|
compact_minimum_size = Vector2(86, 84)
|
||||||
|
minimum_font_size = 14
|
||||||
|
maximum_font_size = 20
|
||||||
|
horizontal_amplitude = 1.7
|
||||||
|
vertical_amplitude = 4.1
|
||||||
|
motion_period = 5.1
|
||||||
|
motion_phase = 4.0
|
||||||
|
deformation_amplitude = 0.017
|
||||||
|
deformation_period = 5.4
|
||||||
|
|
@ -13,6 +13,9 @@ const BubbleButtonType = preload(
|
||||||
const BubbleClusterType = preload(
|
const BubbleClusterType = preload(
|
||||||
"res://ui/components/bubble_menu/bubble_cluster.gd"
|
"res://ui/components/bubble_menu/bubble_cluster.gd"
|
||||||
)
|
)
|
||||||
|
const TitleConfirmationBubblePageType = preload(
|
||||||
|
"res://ui/title_confirmation_bubble_page.gd"
|
||||||
|
)
|
||||||
const DECORATIVE_FISH_TEXTURES: Array[Texture2D] = [
|
const DECORATIVE_FISH_TEXTURES: Array[Texture2D] = [
|
||||||
preload("res://fish/species/bass/fish_bass_striped.png"),
|
preload("res://fish/species/bass/fish_bass_striped.png"),
|
||||||
preload("res://fish/species/bluegill/fish_bluegill.png"),
|
preload("res://fish/species/bluegill/fish_bluegill.png"),
|
||||||
|
|
@ -50,11 +53,20 @@ const BUBBLE_WOBBLE_MIN: float = 3.0
|
||||||
const BUBBLE_WOBBLE_MAX: float = 9.0
|
const BUBBLE_WOBBLE_MAX: float = 9.0
|
||||||
const BUBBLE_EDGE_MARGIN: float = 16.0
|
const BUBBLE_EDGE_MARGIN: float = 16.0
|
||||||
const MAX_DECORATIVE_BUBBLES: int = 6
|
const MAX_DECORATIVE_BUBBLES: int = 6
|
||||||
|
const TRANSITION_BUBBLE_COUNT_MIN: int = 4
|
||||||
|
const TRANSITION_BUBBLE_COUNT_MAX: int = 5
|
||||||
|
const MAX_TRANSITION_BUBBLES: int = 30
|
||||||
|
const TRANSITION_BUBBLE_X_MIN: float = 0.36
|
||||||
|
const TRANSITION_BUBBLE_X_MAX: float = 0.64
|
||||||
|
const TRANSITION_BUBBLE_Y_MIN: float = 0.60
|
||||||
|
const TRANSITION_BUBBLE_Y_MAX: float = 0.78
|
||||||
const LOGO_ASPECT_RATIO: float = 2560.0 / 760.0
|
const LOGO_ASPECT_RATIO: float = 2560.0 / 760.0
|
||||||
const LOGO_WIDTH_FACTOR: float = 0.4784
|
const LOGO_WIDTH_FACTOR: float = 0.4784
|
||||||
const LOGO_MIN_WIDTH: float = 294.0
|
const LOGO_MIN_WIDTH: float = 294.0
|
||||||
const LOGO_MAX_WIDTH: float = 662.0
|
const LOGO_MAX_WIDTH: float = 662.0
|
||||||
const TITLE_HORIZONTAL_MARGIN: float = 48.0
|
const TITLE_HORIZONTAL_MARGIN: float = 48.0
|
||||||
|
const TITLE_DESKTOP_REFERENCE_SIZE: Vector2 = Vector2(1280.0, 720.0)
|
||||||
|
const TITLE_COMPACT_REFERENCE_SIZE: Vector2 = Vector2(640.0, 480.0)
|
||||||
const BUBBLE_FIELD_MAX_WIDTH: float = 396.0
|
const BUBBLE_FIELD_MAX_WIDTH: float = 396.0
|
||||||
const BUBBLE_FIELD_DESKTOP_HEIGHT: float = 318.0
|
const BUBBLE_FIELD_DESKTOP_HEIGHT: float = 318.0
|
||||||
const BUBBLE_FIELD_COMPACT_WIDTH: float = 294.0
|
const BUBBLE_FIELD_COMPACT_WIDTH: float = 294.0
|
||||||
|
|
@ -89,10 +101,13 @@ enum ConfirmationAction {
|
||||||
@onready var _new_game_label: Label = %NewGameLabel
|
@onready var _new_game_label: Label = %NewGameLabel
|
||||||
@onready var _delete_save_label: Label = %DeleteSaveLabel
|
@onready var _delete_save_label: Label = %DeleteSaveLabel
|
||||||
@onready var _feedback_label: Label = %FeedbackLabel
|
@onready var _feedback_label: Label = %FeedbackLabel
|
||||||
@onready var _confirmation_panel: PanelContainer = %ConfirmationPanel
|
@onready var _confirmation_page: TitleConfirmationBubblePageType = (
|
||||||
@onready var _confirmation_text: Label = %ConfirmationText
|
%ConfirmationPage
|
||||||
@onready var _confirm_button: Button = %ConfirmButton
|
)
|
||||||
@onready var _settings_panel: SettingsPanelType = %SettingsPanel
|
@onready var _settings_panel: SettingsPanelType = %SettingsPanel
|
||||||
|
@onready var _title_presentation_scale_root: Control = (
|
||||||
|
%TitlePresentationScaleRoot
|
||||||
|
)
|
||||||
@onready var _background: ColorRect = %Background
|
@onready var _background: ColorRect = %Background
|
||||||
@onready var _decorative_fish_layer: Control = %DecorativeFishLayer
|
@onready var _decorative_fish_layer: Control = %DecorativeFishLayer
|
||||||
@onready var _decorative_fish_timer: Timer = %DecorativeFishTimer
|
@onready var _decorative_fish_timer: Timer = %DecorativeFishTimer
|
||||||
|
|
@ -102,13 +117,14 @@ enum ConfirmationAction {
|
||||||
@onready var _title_logo: TextureRect = %TitleLogo
|
@onready var _title_logo: TextureRect = %TitleLogo
|
||||||
@onready var _playtest_label: Label = %PlaytestLabel
|
@onready var _playtest_label: Label = %PlaytestLabel
|
||||||
@onready var _intro_branding_anchor: Control = %IntroBrandingAnchor
|
@onready var _intro_branding_anchor: Control = %IntroBrandingAnchor
|
||||||
@onready var _presentation_center: CenterContainer = $Center
|
@onready var _presentation_center: CenterContainer = %Center
|
||||||
@onready var _main_content: VBoxContainer = $Center/MainContent
|
@onready var _main_content: VBoxContainer = %MainContent
|
||||||
@onready var _branding_slot: Control = $Center/MainContent/BrandingSlot
|
@onready var _branding_slot: Control = %BrandingSlot
|
||||||
@onready var _branding_motion_root: Control = %BrandingMotionRoot
|
@onready var _branding_motion_root: Control = %BrandingMotionRoot
|
||||||
@onready var _title_spacer: Control = $Center/MainContent/Spacer
|
@onready var _version_row: Control = %VersionRow
|
||||||
|
@onready var _title_spacer: Control = %Spacer
|
||||||
@onready var _button_center: CenterContainer = %ButtonCenter
|
@onready var _button_center: CenterContainer = %ButtonCenter
|
||||||
@onready var _bubble_layout_slot: Control = $Center/MainContent/ButtonCenter/BubbleLayoutSlot
|
@onready var _bubble_layout_slot: Control = %BubbleLayoutSlot
|
||||||
@onready var _bubble_motion_root: Control = %BubbleMotionRoot
|
@onready var _bubble_motion_root: Control = %BubbleMotionRoot
|
||||||
@onready var _bubble_field: BubbleClusterType = %BubbleField
|
@onready var _bubble_field: BubbleClusterType = %BubbleField
|
||||||
@onready var _start_prompt_center: CenterContainer = %StartPromptCenter
|
@onready var _start_prompt_center: CenterContainer = %StartPromptCenter
|
||||||
|
|
@ -127,6 +143,7 @@ var _decorative_presentation_active: bool = false
|
||||||
var _decorative_generation: int = 0
|
var _decorative_generation: int = 0
|
||||||
var _decorative_bubbles: Array[TextureRect] = []
|
var _decorative_bubbles: Array[TextureRect] = []
|
||||||
var _decorative_bubble_tweens: Dictionary[int, Tween] = {}
|
var _decorative_bubble_tweens: Dictionary[int, Tween] = {}
|
||||||
|
var _transition_bubble_ids: Dictionary[int, bool] = {}
|
||||||
var _pending_cluster_bubbles: int = 0
|
var _pending_cluster_bubbles: int = 0
|
||||||
var _awaiting_start_input: bool = false
|
var _awaiting_start_input: bool = false
|
||||||
var _start_prompt_elapsed: float = 0.0
|
var _start_prompt_elapsed: float = 0.0
|
||||||
|
|
@ -150,6 +167,10 @@ var _feedback_text_before_settings: String = ""
|
||||||
var _continue_stats_hovered: bool = false
|
var _continue_stats_hovered: bool = false
|
||||||
var _continue_stats_focused: bool = false
|
var _continue_stats_focused: bool = false
|
||||||
var _continue_stats_fade: Tween
|
var _continue_stats_fade: Tween
|
||||||
|
var _confirmation_transition: Tween
|
||||||
|
var _confirmation_transition_generation: int = 0
|
||||||
|
var _confirmation_transition_active: bool = false
|
||||||
|
var _confirmation_title_content_rest_position: Vector2 = Vector2.ZERO
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
|
@ -170,11 +191,14 @@ func _ready() -> void:
|
||||||
_settings_button.pressed.connect(_open_settings)
|
_settings_button.pressed.connect(_open_settings)
|
||||||
_delete_button.pressed.connect(_on_delete_pressed)
|
_delete_button.pressed.connect(_on_delete_pressed)
|
||||||
%QuitButton.pressed.connect(_on_quit_pressed)
|
%QuitButton.pressed.connect(_on_quit_pressed)
|
||||||
_confirm_button.pressed.connect(_on_confirmation_accepted)
|
_confirmation_page.confirmed.connect(_on_confirmation_accepted)
|
||||||
%CancelConfirmButton.pressed.connect(_close_confirmation)
|
_confirmation_page.cancelled.connect(_request_close_confirmation)
|
||||||
_settings_panel.applied.connect(_on_settings_applied)
|
_settings_panel.applied.connect(_on_settings_applied)
|
||||||
_settings_panel.closed.connect(_on_settings_closed)
|
_settings_panel.closed.connect(_on_settings_closed)
|
||||||
_settings_panel.opened.connect(_on_settings_opened)
|
_settings_panel.opened.connect(_on_settings_opened)
|
||||||
|
_settings_panel.navigation_transition_started.connect(
|
||||||
|
_emit_navigation_bubble_flurry
|
||||||
|
)
|
||||||
_bubble_field.configure(_get_title_buttons())
|
_bubble_field.configure(_get_title_buttons())
|
||||||
_decorative_fish_timer.timeout.connect(_on_decorative_fish_timer_timeout)
|
_decorative_fish_timer.timeout.connect(_on_decorative_fish_timer_timeout)
|
||||||
_decorative_bubble_event_timer.timeout.connect(
|
_decorative_bubble_event_timer.timeout.connect(
|
||||||
|
|
@ -184,11 +208,11 @@ func _ready() -> void:
|
||||||
_on_decorative_bubble_cluster_timer_timeout
|
_on_decorative_bubble_cluster_timer_timeout
|
||||||
)
|
)
|
||||||
visibility_changed.connect(_on_title_visibility_changed)
|
visibility_changed.connect(_on_title_visibility_changed)
|
||||||
resized.connect(_update_title_layout)
|
resized.connect(_update_responsive_title_stage)
|
||||||
_start_prompt_label.resized.connect(_update_start_prompt_pivot)
|
_start_prompt_label.resized.connect(_update_start_prompt_pivot)
|
||||||
_decorative_rng.randomize()
|
_decorative_rng.randomize()
|
||||||
set_process(false)
|
set_process(false)
|
||||||
call_deferred("_update_title_layout")
|
call_deferred("_update_responsive_title_stage")
|
||||||
call_deferred("_update_start_prompt_pivot")
|
call_deferred("_update_start_prompt_pivot")
|
||||||
call_deferred("_capture_title_bubble_rest_position")
|
call_deferred("_capture_title_bubble_rest_position")
|
||||||
call_deferred("_capture_title_content_rest_position")
|
call_deferred("_capture_title_content_rest_position")
|
||||||
|
|
@ -213,7 +237,7 @@ func reopen() -> void:
|
||||||
_cancel_title_settings_transition()
|
_cancel_title_settings_transition()
|
||||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||||
_prepare_awaiting_start_input()
|
_prepare_awaiting_start_input()
|
||||||
_close_confirmation()
|
_reset_confirmation()
|
||||||
_settings_panel.hide()
|
_settings_panel.hide()
|
||||||
_refresh_save_inspection()
|
_refresh_save_inspection()
|
||||||
show()
|
show()
|
||||||
|
|
@ -250,10 +274,14 @@ func is_decorative_bubble_scheduler_active() -> bool:
|
||||||
func _update_title_layout() -> void:
|
func _update_title_layout() -> void:
|
||||||
if not is_node_ready():
|
if not is_node_ready():
|
||||||
return
|
return
|
||||||
var available_width: float = maxf(1.0, size.x - TITLE_HORIZONTAL_MARGIN)
|
var layout_size: Vector2 = _title_presentation_scale_root.size
|
||||||
|
var available_width: float = maxf(
|
||||||
|
1.0,
|
||||||
|
layout_size.x - TITLE_HORIZONTAL_MARGIN
|
||||||
|
)
|
||||||
var logo_width: float = minf(
|
var logo_width: float = minf(
|
||||||
clampf(
|
clampf(
|
||||||
size.x * LOGO_WIDTH_FACTOR,
|
layout_size.x * LOGO_WIDTH_FACTOR,
|
||||||
LOGO_MIN_WIDTH,
|
LOGO_MIN_WIDTH,
|
||||||
LOGO_MAX_WIDTH
|
LOGO_MAX_WIDTH
|
||||||
),
|
),
|
||||||
|
|
@ -270,17 +298,17 @@ func _update_title_layout() -> void:
|
||||||
logo_width,
|
logo_width,
|
||||||
logo_width / LOGO_ASPECT_RATIO
|
logo_width / LOGO_ASPECT_RATIO
|
||||||
+ branding_separation
|
+ branding_separation
|
||||||
+ _playtest_label.get_combined_minimum_size().y
|
+ _version_row.get_combined_minimum_size().y
|
||||||
)
|
)
|
||||||
_branding_slot.custom_minimum_size = branding_size
|
_branding_slot.custom_minimum_size = branding_size
|
||||||
_branding_motion_root.size = branding_size
|
_branding_motion_root.size = branding_size
|
||||||
var field_width: float = minf(BUBBLE_FIELD_MAX_WIDTH, available_width)
|
var field_width: float = minf(BUBBLE_FIELD_MAX_WIDTH, available_width)
|
||||||
var field_height: float = (
|
var field_height: float = (
|
||||||
BUBBLE_FIELD_COMPACT_HEIGHT
|
BUBBLE_FIELD_COMPACT_HEIGHT
|
||||||
if size.y < BUBBLE_COMPACT_HEIGHT_THRESHOLD
|
if layout_size.y < BUBBLE_COMPACT_HEIGHT_THRESHOLD
|
||||||
else BUBBLE_FIELD_DESKTOP_HEIGHT
|
else BUBBLE_FIELD_DESKTOP_HEIGHT
|
||||||
)
|
)
|
||||||
if size.y < BUBBLE_COMPACT_HEIGHT_THRESHOLD:
|
if layout_size.y < BUBBLE_COMPACT_HEIGHT_THRESHOLD:
|
||||||
field_width = minf(BUBBLE_FIELD_COMPACT_WIDTH, available_width)
|
field_width = minf(BUBBLE_FIELD_COMPACT_WIDTH, available_width)
|
||||||
_bubble_layout_slot.custom_minimum_size = Vector2(field_width, field_height)
|
_bubble_layout_slot.custom_minimum_size = Vector2(field_width, field_height)
|
||||||
_bubble_motion_root.size = Vector2(field_width, field_height)
|
_bubble_motion_root.size = Vector2(field_width, field_height)
|
||||||
|
|
@ -301,6 +329,35 @@ func _update_title_layout() -> void:
|
||||||
_update_world_preview_resolution()
|
_update_world_preview_resolution()
|
||||||
|
|
||||||
|
|
||||||
|
func _update_responsive_title_stage() -> void:
|
||||||
|
if not is_node_ready():
|
||||||
|
return
|
||||||
|
var display_size := Vector2(
|
||||||
|
maxf(1.0, size.x),
|
||||||
|
maxf(1.0, size.y)
|
||||||
|
)
|
||||||
|
var reference_size: Vector2 = (
|
||||||
|
TITLE_COMPACT_REFERENCE_SIZE
|
||||||
|
if display_size.y < BUBBLE_COMPACT_HEIGHT_THRESHOLD
|
||||||
|
else TITLE_DESKTOP_REFERENCE_SIZE
|
||||||
|
)
|
||||||
|
var presentation_scale: float = minf(
|
||||||
|
display_size.x / reference_size.x,
|
||||||
|
display_size.y / reference_size.y
|
||||||
|
)
|
||||||
|
_title_presentation_scale_root.size = reference_size
|
||||||
|
_title_presentation_scale_root.scale = Vector2.ONE * presentation_scale
|
||||||
|
_title_presentation_scale_root.position = (
|
||||||
|
display_size - reference_size * presentation_scale
|
||||||
|
) * 0.5
|
||||||
|
_update_title_layout()
|
||||||
|
if (
|
||||||
|
_is_confirmation_active()
|
||||||
|
and not _confirmation_page.is_transitioning()
|
||||||
|
):
|
||||||
|
_set_confirmation_stage_rect()
|
||||||
|
|
||||||
|
|
||||||
func _get_title_buttons() -> Array[BubbleButton]:
|
func _get_title_buttons() -> Array[BubbleButton]:
|
||||||
return [
|
return [
|
||||||
_continue_button,
|
_continue_button,
|
||||||
|
|
@ -385,7 +442,11 @@ func _process(delta: float) -> void:
|
||||||
func _input(event: InputEvent) -> void:
|
func _input(event: InputEvent) -> void:
|
||||||
if not visible:
|
if not visible:
|
||||||
return
|
return
|
||||||
if _title_settings_transition_active or _title_entry_transition_active:
|
if (
|
||||||
|
_title_settings_transition_active
|
||||||
|
or _title_entry_transition_active
|
||||||
|
or _confirmation_transition_active
|
||||||
|
):
|
||||||
get_viewport().set_input_as_handled()
|
get_viewport().set_input_as_handled()
|
||||||
return
|
return
|
||||||
if _awaiting_start_input:
|
if _awaiting_start_input:
|
||||||
|
|
@ -402,8 +463,8 @@ func _input(event: InputEvent) -> void:
|
||||||
return
|
return
|
||||||
if not event.is_action_pressed("ui_cancel"):
|
if not event.is_action_pressed("ui_cancel"):
|
||||||
return
|
return
|
||||||
if _confirmation_panel.visible:
|
if _is_confirmation_active():
|
||||||
_close_confirmation()
|
_request_close_confirmation()
|
||||||
elif _settings_panel.visible:
|
elif _settings_panel.visible:
|
||||||
_settings_panel.handle_back()
|
_settings_panel.handle_back()
|
||||||
else:
|
else:
|
||||||
|
|
@ -425,7 +486,7 @@ func _is_start_prompt_reveal_event(event: InputEvent) -> bool:
|
||||||
func _handle_primary_menu_focus_input(event: InputEvent) -> bool:
|
func _handle_primary_menu_focus_input(event: InputEvent) -> bool:
|
||||||
if (
|
if (
|
||||||
not _button_center.visible
|
not _button_center.visible
|
||||||
or _confirmation_panel.visible
|
or _is_confirmation_active()
|
||||||
or _settings_panel.visible
|
or _settings_panel.visible
|
||||||
):
|
):
|
||||||
return false
|
return false
|
||||||
|
|
@ -616,26 +677,37 @@ func _prepare_intro_presentation(generation: int) -> void:
|
||||||
_title_spacer.get_combined_minimum_size().y
|
_title_spacer.get_combined_minimum_size().y
|
||||||
+ float(_main_content.get_theme_constant("separation"))
|
+ float(_main_content.get_theme_constant("separation"))
|
||||||
)
|
)
|
||||||
var branding_target_global := Vector2(
|
var inverse_stage_transform: Transform2D = (
|
||||||
|
_title_presentation_scale_root.get_global_transform().affine_inverse()
|
||||||
|
)
|
||||||
|
var branding_anchor_position: Vector2 = (
|
||||||
|
inverse_stage_transform
|
||||||
|
* _intro_branding_anchor.get_global_transform().origin
|
||||||
|
)
|
||||||
|
var branding_slot_position: Vector2 = (
|
||||||
|
inverse_stage_transform
|
||||||
|
* _branding_slot.get_global_transform().origin
|
||||||
|
)
|
||||||
|
var branding_target_position := Vector2(
|
||||||
floorf(
|
floorf(
|
||||||
_intro_branding_anchor.global_position.x
|
branding_anchor_position.x
|
||||||
- _branding_motion_root.size.x * 0.5
|
- _branding_motion_root.size.x * 0.5
|
||||||
),
|
),
|
||||||
floorf(
|
floorf(
|
||||||
_intro_branding_anchor.global_position.y
|
branding_anchor_position.y
|
||||||
- (_branding_motion_root.size.y + intro_tail_height) * 0.5
|
- (_branding_motion_root.size.y + intro_tail_height) * 0.5
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
_branding_intro_position = (
|
_branding_intro_position = (
|
||||||
branding_target_global
|
branding_target_position
|
||||||
- _branding_slot.global_position
|
- branding_slot_position
|
||||||
)
|
)
|
||||||
var bubble_bounds: Rect2 = _get_title_bubble_global_bounds()
|
var bubble_bounds: Rect2 = _get_title_bubble_stage_bounds()
|
||||||
bubble_bounds.position -= _bubble_motion_root.position
|
bubble_bounds.position -= _bubble_motion_root.position
|
||||||
var presentation_allowance: float = _get_bubble_offscreen_allowance()
|
var presentation_allowance: float = _get_bubble_offscreen_allowance()
|
||||||
_bubble_intro_position = Vector2(
|
_bubble_intro_position = Vector2(
|
||||||
0.0,
|
0.0,
|
||||||
size.y
|
_title_presentation_scale_root.size.y
|
||||||
+ presentation_allowance
|
+ presentation_allowance
|
||||||
- bubble_bounds.position.y
|
- bubble_bounds.position.y
|
||||||
)
|
)
|
||||||
|
|
@ -646,14 +718,26 @@ func _prepare_intro_presentation(generation: int) -> void:
|
||||||
_intro_geometry_ready = true
|
_intro_geometry_ready = true
|
||||||
|
|
||||||
|
|
||||||
func _get_title_bubble_global_bounds() -> Rect2:
|
func _get_title_bubble_stage_bounds() -> Rect2:
|
||||||
var bubbles: Array[BubbleButton] = _get_title_buttons()
|
var bubbles: Array[BubbleButton] = _get_title_buttons()
|
||||||
var bounds: Rect2 = bubbles[0].get_global_rect()
|
var bounds: Rect2 = _get_title_stage_rect(bubbles[0])
|
||||||
for index: int in range(1, bubbles.size()):
|
for index: int in range(1, bubbles.size()):
|
||||||
bounds = bounds.merge(bubbles[index].get_global_rect())
|
bounds = bounds.merge(_get_title_stage_rect(bubbles[index]))
|
||||||
return bounds
|
return bounds
|
||||||
|
|
||||||
|
|
||||||
|
func _get_title_stage_rect(control: Control) -> Rect2:
|
||||||
|
var inverse_stage_transform: Transform2D = (
|
||||||
|
_title_presentation_scale_root.get_global_transform().affine_inverse()
|
||||||
|
)
|
||||||
|
var global_rect: Rect2 = control.get_global_rect()
|
||||||
|
var local_position: Vector2 = (
|
||||||
|
inverse_stage_transform * global_rect.position
|
||||||
|
)
|
||||||
|
var local_end: Vector2 = inverse_stage_transform * global_rect.end
|
||||||
|
return Rect2(local_position, local_end - local_position)
|
||||||
|
|
||||||
|
|
||||||
func _get_bubble_offscreen_allowance() -> float:
|
func _get_bubble_offscreen_allowance() -> float:
|
||||||
var maximum_vertical_amplitude: float = 0.0
|
var maximum_vertical_amplitude: float = 0.0
|
||||||
var maximum_deformation_growth: float = 0.0
|
var maximum_deformation_growth: float = 0.0
|
||||||
|
|
@ -707,7 +791,7 @@ func _update_continue_stats_visibility() -> void:
|
||||||
and not _title_entry_transition_active
|
and not _title_entry_transition_active
|
||||||
and not _title_settings_transition_active
|
and not _title_settings_transition_active
|
||||||
and not _settings_panel.visible
|
and not _settings_panel.visible
|
||||||
and not _confirmation_panel.visible
|
and not _is_confirmation_active()
|
||||||
and not _action_in_progress
|
and not _action_in_progress
|
||||||
and _presentation_center.visible
|
and _presentation_center.visible
|
||||||
)
|
)
|
||||||
|
|
@ -763,7 +847,7 @@ func _get_continue_stats_text() -> String:
|
||||||
func _on_continue_pressed() -> void:
|
func _on_continue_pressed() -> void:
|
||||||
if (
|
if (
|
||||||
_action_in_progress
|
_action_in_progress
|
||||||
or _confirmation_panel.visible
|
or _is_confirmation_active()
|
||||||
or _settings_panel.visible
|
or _settings_panel.visible
|
||||||
or _inspection == null
|
or _inspection == null
|
||||||
or not _inspection.can_continue()
|
or not _inspection.can_continue()
|
||||||
|
|
@ -783,7 +867,7 @@ func _on_continue_pressed() -> void:
|
||||||
func _on_new_game_pressed() -> void:
|
func _on_new_game_pressed() -> void:
|
||||||
if (
|
if (
|
||||||
_action_in_progress
|
_action_in_progress
|
||||||
or _confirmation_panel.visible
|
or _is_confirmation_active()
|
||||||
or _settings_panel.visible
|
or _settings_panel.visible
|
||||||
or _inspection == null
|
or _inspection == null
|
||||||
):
|
):
|
||||||
|
|
@ -805,14 +889,15 @@ func _on_new_game_pressed() -> void:
|
||||||
_open_confirmation(
|
_open_confirmation(
|
||||||
ConfirmationAction.NEW_GAME,
|
ConfirmationAction.NEW_GAME,
|
||||||
"start a new game? existing progression will be deleted.",
|
"start a new game? existing progression will be deleted.",
|
||||||
"start new game"
|
"start\nnew game",
|
||||||
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func _on_delete_pressed() -> void:
|
func _on_delete_pressed() -> void:
|
||||||
if (
|
if (
|
||||||
_action_in_progress
|
_action_in_progress
|
||||||
or _confirmation_panel.visible
|
or _is_confirmation_active()
|
||||||
or _settings_panel.visible
|
or _settings_panel.visible
|
||||||
or _inspection == null
|
or _inspection == null
|
||||||
or not _inspection.can_delete()
|
or not _inspection.can_delete()
|
||||||
|
|
@ -827,22 +912,32 @@ func _on_delete_pressed() -> void:
|
||||||
|
|
||||||
|
|
||||||
func _on_confirmation_accepted() -> void:
|
func _on_confirmation_accepted() -> void:
|
||||||
if _action_in_progress:
|
if (
|
||||||
|
_action_in_progress
|
||||||
|
or _confirmation_transition_active
|
||||||
|
or _confirmation_action == ConfirmationAction.NONE
|
||||||
|
):
|
||||||
return
|
return
|
||||||
var action: ConfirmationAction = _confirmation_action
|
var action: ConfirmationAction = _confirmation_action
|
||||||
_close_confirmation()
|
_confirmation_page.lock_interaction()
|
||||||
_action_in_progress = true
|
_action_in_progress = true
|
||||||
if not _save_manager.delete_progression_save():
|
if not _save_manager.delete_progression_save():
|
||||||
_feedback_label.text = "failed to delete saved progression."
|
_feedback_label.text = "failed to delete saved progression."
|
||||||
_action_in_progress = false
|
_action_in_progress = false
|
||||||
_refresh_save_inspection()
|
_refresh_save_inspection()
|
||||||
|
_begin_confirmation_return()
|
||||||
return
|
return
|
||||||
_save_manager.initialize_new_game()
|
_save_manager.initialize_new_game()
|
||||||
_refresh_save_inspection()
|
_refresh_save_inspection()
|
||||||
if action == ConfirmationAction.NEW_GAME:
|
if action == ConfirmationAction.NEW_GAME:
|
||||||
|
_confirmation_action = ConfirmationAction.NONE
|
||||||
|
_confirmation_transition_generation += 1
|
||||||
|
_cancel_confirmation_transition()
|
||||||
|
_confirmation_page.hide_page()
|
||||||
gameplay_requested.emit()
|
gameplay_requested.emit()
|
||||||
else:
|
else:
|
||||||
_feedback_label.text = "saved progression deleted."
|
_feedback_label.text = "saved progression deleted."
|
||||||
|
_begin_confirmation_return()
|
||||||
_action_in_progress = false
|
_action_in_progress = false
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -850,33 +945,177 @@ func _open_confirmation(
|
||||||
action: ConfirmationAction,
|
action: ConfirmationAction,
|
||||||
message: String,
|
message: String,
|
||||||
confirm_text: String,
|
confirm_text: String,
|
||||||
|
use_multiline_action_layout: bool = false,
|
||||||
) -> void:
|
) -> void:
|
||||||
_hide_continue_stats_context()
|
_hide_continue_stats_context()
|
||||||
_modal_restore_navigation_focus = _navigation_focus_active
|
_modal_restore_navigation_focus = _navigation_focus_active
|
||||||
_confirmation_action = action
|
_confirmation_action = action
|
||||||
_confirmation_text.text = message
|
_confirmation_page.configure(
|
||||||
_confirm_button.text = confirm_text
|
message,
|
||||||
_confirmation_panel.visible = true
|
confirm_text,
|
||||||
_confirm_button.grab_focus()
|
use_multiline_action_layout
|
||||||
|
)
|
||||||
|
_begin_confirmation_open()
|
||||||
|
|
||||||
|
|
||||||
func _close_confirmation() -> void:
|
func _request_close_confirmation() -> void:
|
||||||
|
if (
|
||||||
|
not _confirmation_page.visible
|
||||||
|
or _confirmation_transition_active
|
||||||
|
or _action_in_progress
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_begin_confirmation_return()
|
||||||
|
|
||||||
|
|
||||||
|
func _begin_confirmation_open() -> void:
|
||||||
|
_confirmation_transition_generation += 1
|
||||||
|
_cancel_confirmation_transition()
|
||||||
|
_confirmation_transition_active = true
|
||||||
|
_emit_navigation_bubble_flurry()
|
||||||
|
_confirmation_title_content_rest_position = _presentation_center.position
|
||||||
|
_set_confirmation_stage_rect()
|
||||||
|
_confirmation_page.hide_page()
|
||||||
|
_set_title_bubbles_interactive(false)
|
||||||
|
_release_primary_menu_focus()
|
||||||
|
var generation: int = _confirmation_transition_generation
|
||||||
|
var content_bounds: Rect2 = _get_title_stage_rect(_main_content)
|
||||||
|
var exit_distance: float = (
|
||||||
|
content_bounds.end.y + HOST_CLUSTER_SAFE_MARGIN
|
||||||
|
)
|
||||||
|
_confirmation_transition = create_tween()
|
||||||
|
_confirmation_transition.tween_property(
|
||||||
|
_presentation_center,
|
||||||
|
"position:y",
|
||||||
|
_confirmation_title_content_rest_position.y - exit_distance,
|
||||||
|
HOST_PRESENTATION_OUT_DURATION
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_confirmation_transition.finished.connect(
|
||||||
|
_finish_confirmation_title_exit.bind(generation),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_confirmation_title_exit(generation: int) -> void:
|
||||||
|
if (
|
||||||
|
generation != _confirmation_transition_generation
|
||||||
|
or not _confirmation_transition_active
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_confirmation_transition = null
|
||||||
|
_presentation_center.hide()
|
||||||
|
_presentation_center.position = _confirmation_title_content_rest_position
|
||||||
|
_confirmation_page.transition_in(
|
||||||
|
HOST_PRESENTATION_IN_DURATION,
|
||||||
|
_finish_confirmation_open.bind(generation)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_confirmation_open(generation: int) -> void:
|
||||||
|
if (
|
||||||
|
generation != _confirmation_transition_generation
|
||||||
|
or not _confirmation_transition_active
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_confirmation_transition_active = false
|
||||||
|
|
||||||
|
|
||||||
|
func _begin_confirmation_return() -> void:
|
||||||
|
if not _confirmation_page.visible or _confirmation_transition_active:
|
||||||
|
return
|
||||||
|
_confirmation_transition_generation += 1
|
||||||
|
_cancel_confirmation_transition()
|
||||||
|
_confirmation_transition_active = true
|
||||||
|
_emit_navigation_bubble_flurry()
|
||||||
|
_confirmation_page.lock_interaction()
|
||||||
|
var generation: int = _confirmation_transition_generation
|
||||||
|
_confirmation_page.transition_out(
|
||||||
|
HOST_PRESENTATION_OUT_DURATION,
|
||||||
|
_finish_confirmation_page_exit.bind(generation)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_confirmation_page_exit(generation: int) -> void:
|
||||||
|
if (
|
||||||
|
generation != _confirmation_transition_generation
|
||||||
|
or not _confirmation_transition_active
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_confirmation_action = ConfirmationAction.NONE
|
||||||
|
_presentation_center.position = Vector2(
|
||||||
|
_confirmation_title_content_rest_position.x,
|
||||||
|
_title_presentation_scale_root.size.y
|
||||||
|
+ HOST_CLUSTER_SAFE_MARGIN
|
||||||
|
)
|
||||||
|
_presentation_center.show()
|
||||||
|
_confirmation_transition = create_tween()
|
||||||
|
_confirmation_transition.tween_property(
|
||||||
|
_presentation_center,
|
||||||
|
"position",
|
||||||
|
_confirmation_title_content_rest_position,
|
||||||
|
HOST_PRESENTATION_IN_DURATION
|
||||||
|
).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
|
_confirmation_transition.finished.connect(
|
||||||
|
_finish_confirmation_return.bind(generation),
|
||||||
|
CONNECT_ONE_SHOT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _finish_confirmation_return(generation: int) -> void:
|
||||||
|
if (
|
||||||
|
generation != _confirmation_transition_generation
|
||||||
|
or not _confirmation_transition_active
|
||||||
|
):
|
||||||
|
return
|
||||||
|
_confirmation_transition = null
|
||||||
|
_confirmation_transition_active = false
|
||||||
|
_presentation_center.position = _confirmation_title_content_rest_position
|
||||||
|
_set_title_bubbles_interactive(true)
|
||||||
var restore_navigation_focus: bool = _modal_restore_navigation_focus
|
var restore_navigation_focus: bool = _modal_restore_navigation_focus
|
||||||
_modal_restore_navigation_focus = false
|
_modal_restore_navigation_focus = false
|
||||||
_confirmation_action = ConfirmationAction.NONE
|
|
||||||
_confirmation_panel.visible = false
|
|
||||||
if _awaiting_start_input:
|
|
||||||
return
|
|
||||||
if restore_navigation_focus:
|
if restore_navigation_focus:
|
||||||
_focus_initial_button()
|
_focus_initial_button()
|
||||||
else:
|
else:
|
||||||
_navigation_focus_active = false
|
_navigation_focus_active = false
|
||||||
_release_title_focus()
|
_release_title_focus()
|
||||||
|
_update_continue_stats_visibility()
|
||||||
|
|
||||||
|
|
||||||
|
func _set_confirmation_stage_rect() -> void:
|
||||||
|
var slot_rect: Rect2 = _get_title_stage_rect(_bubble_layout_slot)
|
||||||
|
_confirmation_page.set_stage_rect(
|
||||||
|
slot_rect
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func _reset_confirmation() -> void:
|
||||||
|
_confirmation_transition_generation += 1
|
||||||
|
_cancel_confirmation_transition()
|
||||||
|
_confirmation_transition_active = false
|
||||||
|
_confirmation_action = ConfirmationAction.NONE
|
||||||
|
_confirmation_page.hide_page()
|
||||||
|
if is_node_ready():
|
||||||
|
_presentation_center.position = _confirmation_title_content_rest_position
|
||||||
|
_presentation_center.show()
|
||||||
|
|
||||||
|
|
||||||
|
func _cancel_confirmation_transition() -> void:
|
||||||
|
if _confirmation_transition != null:
|
||||||
|
_confirmation_transition.kill()
|
||||||
|
_confirmation_transition = null
|
||||||
|
|
||||||
|
|
||||||
|
func _is_confirmation_active() -> bool:
|
||||||
|
return (
|
||||||
|
_confirmation_action != ConfirmationAction.NONE
|
||||||
|
or _confirmation_page.visible
|
||||||
|
or _confirmation_transition_active
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
func _open_settings() -> void:
|
func _open_settings() -> void:
|
||||||
if (
|
if (
|
||||||
_confirmation_panel.visible
|
_is_confirmation_active()
|
||||||
or _action_in_progress
|
or _action_in_progress
|
||||||
or _settings_panel.visible
|
or _settings_panel.visible
|
||||||
or _title_settings_transition_active
|
or _title_settings_transition_active
|
||||||
|
|
@ -909,15 +1148,15 @@ func _begin_title_cluster_exit() -> void:
|
||||||
_title_settings_transition_generation += 1
|
_title_settings_transition_generation += 1
|
||||||
_cancel_title_settings_tween()
|
_cancel_title_settings_tween()
|
||||||
_title_settings_transition_active = true
|
_title_settings_transition_active = true
|
||||||
|
_emit_navigation_bubble_flurry()
|
||||||
_title_content_rest_position = _presentation_center.position
|
_title_content_rest_position = _presentation_center.position
|
||||||
_title_bubble_rest_position = _bubble_field.position
|
_title_bubble_rest_position = _bubble_field.position
|
||||||
_set_title_bubbles_interactive(false)
|
_set_title_bubbles_interactive(false)
|
||||||
_release_primary_menu_focus()
|
_release_primary_menu_focus()
|
||||||
var generation: int = _title_settings_transition_generation
|
var generation: int = _title_settings_transition_generation
|
||||||
|
var content_bounds: Rect2 = _get_title_stage_rect(_main_content)
|
||||||
var exit_distance: float = (
|
var exit_distance: float = (
|
||||||
_main_content.global_position.y
|
content_bounds.end.y + HOST_CLUSTER_SAFE_MARGIN
|
||||||
+ _main_content.size.y
|
|
||||||
+ HOST_CLUSTER_SAFE_MARGIN
|
|
||||||
)
|
)
|
||||||
_title_settings_transition = create_tween()
|
_title_settings_transition = create_tween()
|
||||||
_title_settings_transition.tween_property(
|
_title_settings_transition.tween_property(
|
||||||
|
|
@ -957,17 +1196,9 @@ func _begin_title_cluster_return(feedback_text: String) -> void:
|
||||||
_hide_continue_stats_context()
|
_hide_continue_stats_context()
|
||||||
_set_title_bubbles_interactive(false)
|
_set_title_bubbles_interactive(false)
|
||||||
var generation: int = _title_settings_transition_generation
|
var generation: int = _title_settings_transition_generation
|
||||||
var rest_global_y: float = (
|
|
||||||
_presentation_center.global_position.y
|
|
||||||
- _presentation_center.position.y
|
|
||||||
+ _title_content_rest_position.y
|
|
||||||
)
|
|
||||||
_presentation_center.position = Vector2(
|
_presentation_center.position = Vector2(
|
||||||
_title_content_rest_position.x,
|
_title_content_rest_position.x,
|
||||||
_title_content_rest_position.y
|
_title_presentation_scale_root.size.y + HOST_CLUSTER_SAFE_MARGIN
|
||||||
+ size.y
|
|
||||||
+ HOST_CLUSTER_SAFE_MARGIN
|
|
||||||
- rest_global_y
|
|
||||||
)
|
)
|
||||||
_presentation_center.show()
|
_presentation_center.show()
|
||||||
_title_settings_transition = create_tween()
|
_title_settings_transition = create_tween()
|
||||||
|
|
@ -997,7 +1228,6 @@ func _finish_title_cluster_return(generation: int) -> void:
|
||||||
_restore_settings_focus()
|
_restore_settings_focus()
|
||||||
_update_continue_stats_visibility()
|
_update_continue_stats_visibility()
|
||||||
|
|
||||||
|
|
||||||
func _set_title_bubbles_interactive(interactive: bool) -> void:
|
func _set_title_bubbles_interactive(interactive: bool) -> void:
|
||||||
for bubble: BubbleButton in _get_title_buttons():
|
for bubble: BubbleButton in _get_title_buttons():
|
||||||
bubble.focus_mode = (
|
bubble.focus_mode = (
|
||||||
|
|
@ -1094,7 +1324,7 @@ func _focus_initial_button() -> void:
|
||||||
func _on_quit_pressed() -> void:
|
func _on_quit_pressed() -> void:
|
||||||
if (
|
if (
|
||||||
not _action_in_progress
|
not _action_in_progress
|
||||||
and not _confirmation_panel.visible
|
and not _is_confirmation_active()
|
||||||
and not _settings_panel.visible
|
and not _settings_panel.visible
|
||||||
):
|
):
|
||||||
_hide_continue_stats_context()
|
_hide_continue_stats_context()
|
||||||
|
|
@ -1112,6 +1342,7 @@ func _on_title_visibility_changed() -> void:
|
||||||
_stop_entry_prompt_animation()
|
_stop_entry_prompt_animation()
|
||||||
_navigation_focus_active = false
|
_navigation_focus_active = false
|
||||||
_modal_restore_navigation_focus = false
|
_modal_restore_navigation_focus = false
|
||||||
|
_reset_confirmation()
|
||||||
_stop_decorative_presentation()
|
_stop_decorative_presentation()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1155,6 +1386,7 @@ func _stop_decorative_presentation() -> void:
|
||||||
if is_instance_valid(bubble):
|
if is_instance_valid(bubble):
|
||||||
bubble.queue_free()
|
bubble.queue_free()
|
||||||
_decorative_bubbles.clear()
|
_decorative_bubbles.clear()
|
||||||
|
_transition_bubble_ids.clear()
|
||||||
|
|
||||||
|
|
||||||
func _schedule_next_decorative_fish(
|
func _schedule_next_decorative_fish(
|
||||||
|
|
@ -1338,7 +1570,7 @@ func _on_decorative_bubble_event_timer_timeout() -> void:
|
||||||
if not _decorative_presentation_active or not visible:
|
if not _decorative_presentation_active or not visible:
|
||||||
return
|
return
|
||||||
var available_slots: int = (
|
var available_slots: int = (
|
||||||
MAX_DECORATIVE_BUBBLES - _decorative_bubbles.size()
|
MAX_DECORATIVE_BUBBLES - _get_idle_decorative_bubble_count()
|
||||||
)
|
)
|
||||||
if available_slots <= 0:
|
if available_slots <= 0:
|
||||||
_schedule_next_decorative_bubble_event(
|
_schedule_next_decorative_bubble_event(
|
||||||
|
|
@ -1387,7 +1619,7 @@ func _on_decorative_bubble_cluster_timer_timeout() -> void:
|
||||||
):
|
):
|
||||||
_pending_cluster_bubbles = 0
|
_pending_cluster_bubbles = 0
|
||||||
return
|
return
|
||||||
if _decorative_bubbles.size() < MAX_DECORATIVE_BUBBLES:
|
if _get_idle_decorative_bubble_count() < MAX_DECORATIVE_BUBBLES:
|
||||||
_spawn_decorative_bubble(_decorative_generation)
|
_spawn_decorative_bubble(_decorative_generation)
|
||||||
_pending_cluster_bubbles -= 1
|
_pending_cluster_bubbles -= 1
|
||||||
if _pending_cluster_bubbles > 0:
|
if _pending_cluster_bubbles > 0:
|
||||||
|
|
@ -1399,15 +1631,24 @@ func _on_decorative_bubble_cluster_timer_timeout() -> void:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func _spawn_decorative_bubble(generation: int) -> bool:
|
func _spawn_decorative_bubble(
|
||||||
|
generation: int,
|
||||||
|
start_y_ratio: float = -1.0,
|
||||||
|
normalized_x_override: float = -1.0,
|
||||||
|
is_transition_bubble: bool = false,
|
||||||
|
) -> bool:
|
||||||
if (
|
if (
|
||||||
generation != _decorative_generation
|
generation != _decorative_generation
|
||||||
or not _decorative_presentation_active
|
or not _decorative_presentation_active
|
||||||
or not visible
|
or not visible
|
||||||
or _decorative_bubbles.size() >= MAX_DECORATIVE_BUBBLES
|
|
||||||
or DECORATIVE_BUBBLE_TEXTURES.is_empty()
|
or DECORATIVE_BUBBLE_TEXTURES.is_empty()
|
||||||
):
|
):
|
||||||
return false
|
return false
|
||||||
|
if is_transition_bubble:
|
||||||
|
if _transition_bubble_ids.size() >= MAX_TRANSITION_BUBBLES:
|
||||||
|
return false
|
||||||
|
elif _get_idle_decorative_bubble_count() >= MAX_DECORATIVE_BUBBLES:
|
||||||
|
return false
|
||||||
var layer_size: Vector2 = _decorative_bubble_layer.size
|
var layer_size: Vector2 = _decorative_bubble_layer.size
|
||||||
if layer_size.x <= 1.0 or layer_size.y <= 1.0:
|
if layer_size.x <= 1.0 or layer_size.y <= 1.0:
|
||||||
return false
|
return false
|
||||||
|
|
@ -1436,8 +1677,12 @@ func _spawn_decorative_bubble(generation: int) -> bool:
|
||||||
)
|
)
|
||||||
_decorative_bubble_layer.add_child(bubble)
|
_decorative_bubble_layer.add_child(bubble)
|
||||||
_decorative_bubbles.append(bubble)
|
_decorative_bubbles.append(bubble)
|
||||||
|
if is_transition_bubble:
|
||||||
|
_transition_bubble_ids[bubble.get_instance_id()] = true
|
||||||
|
|
||||||
var normalized_x: float = _decorative_rng.randf_range(0.08, 0.92)
|
var normalized_x: float = normalized_x_override
|
||||||
|
if normalized_x < 0.0:
|
||||||
|
normalized_x = _decorative_rng.randf_range(0.08, 0.92)
|
||||||
var drift_direction: float = (
|
var drift_direction: float = (
|
||||||
1.0 if _decorative_rng.randi_range(0, 1) == 1 else -1.0
|
1.0 if _decorative_rng.randi_range(0, 1) == 1 else -1.0
|
||||||
)
|
)
|
||||||
|
|
@ -1458,6 +1703,28 @@ func _spawn_decorative_bubble(generation: int) -> bool:
|
||||||
BUBBLE_TRAVEL_DURATION_MIN,
|
BUBBLE_TRAVEL_DURATION_MIN,
|
||||||
BUBBLE_TRAVEL_DURATION_MAX
|
BUBBLE_TRAVEL_DURATION_MAX
|
||||||
)
|
)
|
||||||
|
if start_y_ratio >= 0.0:
|
||||||
|
var full_start_y: float = (
|
||||||
|
layer_size.y + presentation_size.y + BUBBLE_EDGE_MARGIN
|
||||||
|
)
|
||||||
|
var end_y: float = -presentation_size.y - BUBBLE_EDGE_MARGIN
|
||||||
|
var burst_start_y: float = (
|
||||||
|
start_y_ratio * layer_size.y - presentation_size.y * 0.5
|
||||||
|
)
|
||||||
|
var remaining_distance: float = maxf(burst_start_y - end_y, 1.0)
|
||||||
|
var full_distance: float = maxf(full_start_y - end_y, 1.0)
|
||||||
|
travel_duration *= remaining_distance / full_distance
|
||||||
|
_update_decorative_bubble(
|
||||||
|
0.0,
|
||||||
|
bubble,
|
||||||
|
normalized_x,
|
||||||
|
horizontal_drift,
|
||||||
|
wobble_amplitude,
|
||||||
|
wobble_cycles,
|
||||||
|
wobble_phase,
|
||||||
|
start_y_ratio,
|
||||||
|
generation
|
||||||
|
)
|
||||||
var bubble_tween: Tween = create_tween()
|
var bubble_tween: Tween = create_tween()
|
||||||
_decorative_bubble_tweens[bubble.get_instance_id()] = bubble_tween
|
_decorative_bubble_tweens[bubble.get_instance_id()] = bubble_tween
|
||||||
bubble_tween.tween_method(
|
bubble_tween.tween_method(
|
||||||
|
|
@ -1468,6 +1735,7 @@ func _spawn_decorative_bubble(generation: int) -> bool:
|
||||||
wobble_amplitude,
|
wobble_amplitude,
|
||||||
wobble_cycles,
|
wobble_cycles,
|
||||||
wobble_phase,
|
wobble_phase,
|
||||||
|
start_y_ratio,
|
||||||
generation
|
generation
|
||||||
),
|
),
|
||||||
0.0,
|
0.0,
|
||||||
|
|
@ -1489,6 +1757,7 @@ func _update_decorative_bubble(
|
||||||
wobble_amplitude: float,
|
wobble_amplitude: float,
|
||||||
wobble_cycles: float,
|
wobble_cycles: float,
|
||||||
wobble_phase: float,
|
wobble_phase: float,
|
||||||
|
start_y_ratio: float,
|
||||||
generation: int,
|
generation: int,
|
||||||
) -> void:
|
) -> void:
|
||||||
if (
|
if (
|
||||||
|
|
@ -1501,6 +1770,8 @@ func _update_decorative_bubble(
|
||||||
var start_y: float = (
|
var start_y: float = (
|
||||||
layer_size.y + bubble.size.y + BUBBLE_EDGE_MARGIN
|
layer_size.y + bubble.size.y + BUBBLE_EDGE_MARGIN
|
||||||
)
|
)
|
||||||
|
if start_y_ratio >= 0.0:
|
||||||
|
start_y = start_y_ratio * layer_size.y - bubble.size.y * 0.5
|
||||||
var end_y: float = -bubble.size.y - BUBBLE_EDGE_MARGIN
|
var end_y: float = -bubble.size.y - BUBBLE_EDGE_MARGIN
|
||||||
var base_x: float = normalized_x * layer_size.x
|
var base_x: float = normalized_x * layer_size.x
|
||||||
var wobble: float = sin(
|
var wobble: float = sin(
|
||||||
|
|
@ -1523,9 +1794,37 @@ func _on_decorative_bubble_finished(
|
||||||
return
|
return
|
||||||
if is_instance_valid(bubble):
|
if is_instance_valid(bubble):
|
||||||
_decorative_bubble_tweens.erase(bubble.get_instance_id())
|
_decorative_bubble_tweens.erase(bubble.get_instance_id())
|
||||||
|
_transition_bubble_ids.erase(bubble.get_instance_id())
|
||||||
_decorative_bubbles.erase(bubble)
|
_decorative_bubbles.erase(bubble)
|
||||||
bubble.queue_free()
|
bubble.queue_free()
|
||||||
|
|
||||||
|
|
||||||
|
func _get_idle_decorative_bubble_count() -> int:
|
||||||
|
return _decorative_bubbles.size() - _transition_bubble_ids.size()
|
||||||
|
|
||||||
|
|
||||||
|
func _emit_navigation_bubble_flurry() -> void:
|
||||||
|
if not _decorative_presentation_active or not visible:
|
||||||
|
return
|
||||||
|
var bubble_count: int = _decorative_rng.randi_range(
|
||||||
|
TRANSITION_BUBBLE_COUNT_MIN,
|
||||||
|
TRANSITION_BUBBLE_COUNT_MAX
|
||||||
|
)
|
||||||
|
for _bubble_index: int in bubble_count:
|
||||||
|
if not _spawn_decorative_bubble(
|
||||||
|
_decorative_generation,
|
||||||
|
_decorative_rng.randf_range(
|
||||||
|
TRANSITION_BUBBLE_Y_MIN,
|
||||||
|
TRANSITION_BUBBLE_Y_MAX
|
||||||
|
),
|
||||||
|
_decorative_rng.randf_range(
|
||||||
|
TRANSITION_BUBBLE_X_MIN,
|
||||||
|
TRANSITION_BUBBLE_X_MAX
|
||||||
|
),
|
||||||
|
true
|
||||||
|
):
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
func _exit_tree() -> void:
|
func _exit_tree() -> void:
|
||||||
_stop_decorative_presentation()
|
_stop_decorative_presentation()
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=12 format=3]
|
[gd_scene load_steps=13 format=3]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://ui/title_screen.gd" id="1_script"]
|
[ext_resource type="Script" path="res://ui/title_screen.gd" id="1_script"]
|
||||||
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
[ext_resource type="Theme" path="res://ui/game_theme.tres" id="2_theme"]
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_button.gd" id="7_bubble_button"]
|
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_button.gd" id="7_bubble_button"]
|
||||||
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="8_bubble_cluster"]
|
[ext_resource type="Script" path="res://ui/components/bubble_menu/bubble_cluster.gd" id="8_bubble_cluster"]
|
||||||
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="9_bubble_profile"]
|
[ext_resource type="Resource" path="res://ui/components/bubble_menu/bubble_menu_profile.tres" id="9_bubble_profile"]
|
||||||
|
[ext_resource type="PackedScene" path="res://ui/title_confirmation_bubble_page.tscn" id="10_confirmation_page"]
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_water"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_title_water"]
|
||||||
shader = ExtResource("4_water_shader")
|
shader = ExtResource("4_water_shader")
|
||||||
|
|
@ -76,7 +77,25 @@ one_shot = true
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
one_shot = true
|
one_shot = true
|
||||||
|
|
||||||
[node name="StartPromptCenter" type="CenterContainer" parent="."]
|
[node name="ResponsiveTitleStage" type="Control" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
z_index = 10
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 1
|
||||||
|
|
||||||
|
[node name="TitlePresentationScaleRoot" type="Control" parent="ResponsiveTitleStage"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 1280.0
|
||||||
|
offset_bottom = 720.0
|
||||||
|
mouse_filter = 1
|
||||||
|
|
||||||
|
[node name="StartPromptCenter" type="CenterContainer" parent="ResponsiveTitleStage/TitlePresentationScaleRoot"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
z_index = 12
|
z_index = 12
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
|
@ -89,7 +108,7 @@ grow_horizontal = 2
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="StartPromptLabel" type="Label" parent="StartPromptCenter"]
|
[node name="StartPromptLabel" type="Label" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/StartPromptCenter"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
|
@ -101,7 +120,7 @@ text = "press any key to start"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="IntroBrandingAnchor" type="Control" parent="."]
|
[node name="IntroBrandingAnchor" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
|
|
@ -112,7 +131,8 @@ grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="Center" type="CenterContainer" parent="."]
|
[node name="Center" type="CenterContainer" parent="ResponsiveTitleStage/TitlePresentationScaleRoot"]
|
||||||
|
unique_name_in_owner = true
|
||||||
z_index = 10
|
z_index = 10
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
|
|
@ -121,23 +141,25 @@ anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
|
||||||
[node name="MainContent" type="VBoxContainer" parent="Center"]
|
[node name="MainContent" type="VBoxContainer" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_constants/separation = 7
|
theme_override_constants/separation = 7
|
||||||
alignment = 1
|
alignment = 1
|
||||||
|
|
||||||
[node name="BrandingSlot" type="Control" parent="Center/MainContent"]
|
[node name="BrandingSlot" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
|
||||||
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(640, 215)
|
custom_minimum_size = Vector2(640, 215)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="BrandingMotionRoot" type="Control" parent="Center/MainContent/BrandingSlot"]
|
[node name="BrandingMotionRoot" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/BrandingSlot"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 0
|
layout_mode = 0
|
||||||
offset_right = 640.0
|
offset_right = 640.0
|
||||||
offset_bottom = 215.0
|
offset_bottom = 215.0
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="BrandingContent" type="VBoxContainer" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot"]
|
[node name="BrandingContent" type="VBoxContainer" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/BrandingSlot/BrandingMotionRoot"]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
|
|
@ -146,7 +168,7 @@ grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
theme_override_constants/separation = 7
|
theme_override_constants/separation = 7
|
||||||
|
|
||||||
[node name="TitleLogo" type="TextureRect" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent"]
|
[node name="TitleLogo" type="TextureRect" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(640, 190)
|
custom_minimum_size = Vector2(640, 190)
|
||||||
material = SubResource("ShaderMaterial_title_logo")
|
material = SubResource("ShaderMaterial_title_logo")
|
||||||
|
|
@ -157,35 +179,57 @@ texture = ExtResource("5_logo")
|
||||||
expand_mode = 1
|
expand_mode = 1
|
||||||
stretch_mode = 5
|
stretch_mode = 5
|
||||||
|
|
||||||
[node name="PlaytestLabel" type="Label" parent="Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent"]
|
[node name="VersionRow" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(0, 18)
|
||||||
|
layout_mode = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="VersionAnchor" type="CenterContainer" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent/VersionRow"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchor_left = 0.7
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.7
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -140.0
|
||||||
|
offset_top = -17.0
|
||||||
|
offset_right = 140.0
|
||||||
|
offset_bottom = 11.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="PlaytestLabel" type="Label" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/BrandingSlot/BrandingMotionRoot/BrandingContent/VersionRow/VersionAnchor"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
|
theme_override_colors/font_color = Color(0.682, 0.733, 0.761, 1)
|
||||||
theme_override_font_sizes/font_size = 17
|
theme_override_font_sizes/font_size = 22
|
||||||
text = "pre-alpha playtest 0.2"
|
text = "pre-alpha playtest 0.2"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
[node name="Spacer" type="Control" parent="Center/MainContent"]
|
[node name="Spacer" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
|
||||||
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(0, 3)
|
custom_minimum_size = Vector2(0, 3)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="ButtonCenter" type="CenterContainer" parent="Center/MainContent"]
|
[node name="ButtonCenter" type="CenterContainer" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="BubbleLayoutSlot" type="Control" parent="Center/MainContent/ButtonCenter"]
|
[node name="BubbleLayoutSlot" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter"]
|
||||||
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(396, 318)
|
custom_minimum_size = Vector2(396, 318)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="BubbleMotionRoot" type="Control" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot"]
|
[node name="BubbleMotionRoot" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 0
|
layout_mode = 0
|
||||||
offset_right = 396.0
|
offset_right = 396.0
|
||||||
offset_bottom = 318.0
|
offset_bottom = 318.0
|
||||||
mouse_filter = 2
|
mouse_filter = 2
|
||||||
|
|
||||||
[node name="BubbleField" type="Control" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot"]
|
[node name="BubbleField" type="Control" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
custom_minimum_size = Vector2(396, 318)
|
custom_minimum_size = Vector2(396, 318)
|
||||||
layout_mode = 0
|
layout_mode = 0
|
||||||
|
|
@ -194,7 +238,7 @@ offset_bottom = 318.0
|
||||||
script = ExtResource("8_bubble_cluster")
|
script = ExtResource("8_bubble_cluster")
|
||||||
profile = ExtResource("9_bubble_profile")
|
profile = ExtResource("9_bubble_profile")
|
||||||
|
|
||||||
[node name="ContinueButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
[node name="ContinueButton" type="Button" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = 123.0
|
offset_left = 123.0
|
||||||
offset_top = 86.0
|
offset_top = 86.0
|
||||||
|
|
@ -214,7 +258,7 @@ motion_period = 5.8
|
||||||
deformation_amplitude = 0.01
|
deformation_amplitude = 0.01
|
||||||
deformation_period = 6.7
|
deformation_period = 6.7
|
||||||
|
|
||||||
[node name="NewGameButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
[node name="NewGameButton" type="Button" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = 42.0
|
offset_left = 42.0
|
||||||
offset_top = 4.0
|
offset_top = 4.0
|
||||||
|
|
@ -236,7 +280,7 @@ motion_phase = 1.2
|
||||||
deformation_amplitude = 0.018
|
deformation_amplitude = 0.018
|
||||||
deformation_period = 5.9
|
deformation_period = 5.9
|
||||||
|
|
||||||
[node name="NewGameLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField/NewGameButton"]
|
[node name="NewGameLabel" type="Label" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField/NewGameButton"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
|
|
@ -251,7 +295,7 @@ text = "new game"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="SettingsButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
[node name="SettingsButton" type="Button" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = 264.0
|
offset_left = 264.0
|
||||||
offset_top = 17.0
|
offset_top = 17.0
|
||||||
|
|
@ -270,7 +314,7 @@ motion_period = 4.9
|
||||||
motion_phase = 2.5
|
motion_phase = 2.5
|
||||||
deformation_period = 6.3
|
deformation_period = 6.3
|
||||||
|
|
||||||
[node name="DeleteSaveButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
[node name="DeleteSaveButton" type="Button" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = -11.0
|
offset_left = -11.0
|
||||||
offset_top = 122.0
|
offset_top = 122.0
|
||||||
|
|
@ -291,7 +335,7 @@ motion_phase = 3.7
|
||||||
deformation_amplitude = 0.018
|
deformation_amplitude = 0.018
|
||||||
deformation_period = 5.4
|
deformation_period = 5.4
|
||||||
|
|
||||||
[node name="DeleteSaveLabel" type="Label" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField/DeleteSaveButton"]
|
[node name="DeleteSaveLabel" type="Label" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField/DeleteSaveButton"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
|
|
@ -306,7 +350,7 @@ text = "delete save"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
|
|
||||||
[node name="QuitButton" type="Button" parent="Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
[node name="QuitButton" type="Button" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent/ButtonCenter/BubbleLayoutSlot/BubbleMotionRoot/BubbleField"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
offset_left = 275.0
|
offset_left = 275.0
|
||||||
offset_top = 217.0
|
offset_top = 217.0
|
||||||
|
|
@ -328,7 +372,7 @@ motion_phase = 4.8
|
||||||
deformation_amplitude = 0.02
|
deformation_amplitude = 0.02
|
||||||
deformation_period = 4.8
|
deformation_period = 4.8
|
||||||
|
|
||||||
[node name="FeedbackLabel" type="Label" parent="Center/MainContent"]
|
[node name="FeedbackLabel" type="Label" parent="ResponsiveTitleStage/TitlePresentationScaleRoot/Center/MainContent"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
visible = false
|
visible = false
|
||||||
custom_minimum_size = Vector2(0, 44)
|
custom_minimum_size = Vector2(0, 44)
|
||||||
|
|
@ -338,59 +382,17 @@ horizontal_alignment = 1
|
||||||
vertical_alignment = 1
|
vertical_alignment = 1
|
||||||
autowrap_mode = 2
|
autowrap_mode = 2
|
||||||
|
|
||||||
[node name="ConfirmationPanel" type="PanelContainer" parent="."]
|
[node name="ConfirmationPage" parent="ResponsiveTitleStage/TitlePresentationScaleRoot" instance=ExtResource("10_confirmation_page")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
visible = false
|
z_index = 11
|
||||||
z_index = 210
|
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 8
|
anchors_preset = 15
|
||||||
anchor_left = 0.5
|
anchor_right = 1.0
|
||||||
anchor_top = 0.5
|
anchor_bottom = 1.0
|
||||||
anchor_right = 0.5
|
|
||||||
anchor_bottom = 0.5
|
|
||||||
offset_left = -320.0
|
|
||||||
offset_top = -150.0
|
|
||||||
offset_right = 320.0
|
|
||||||
offset_bottom = 150.0
|
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
|
||||||
[node name="Margin" type="MarginContainer" parent="ConfirmationPanel"]
|
[node name="SettingsPanel" parent="ResponsiveTitleStage/TitlePresentationScaleRoot" instance=ExtResource("3_settings")]
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/margin_left = 24
|
|
||||||
theme_override_constants/margin_top = 20
|
|
||||||
theme_override_constants/margin_right = 24
|
|
||||||
theme_override_constants/margin_bottom = 20
|
|
||||||
|
|
||||||
[node name="Content" type="VBoxContainer" parent="ConfirmationPanel/Margin"]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/separation = 14
|
|
||||||
|
|
||||||
[node name="ConfirmationText" type="Label" parent="ConfirmationPanel/Margin/Content"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 2
|
|
||||||
text = "confirm?"
|
|
||||||
horizontal_alignment = 1
|
|
||||||
autowrap_mode = 2
|
|
||||||
|
|
||||||
[node name="Buttons" type="HBoxContainer" parent="ConfirmationPanel/Margin/Content"]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_constants/separation = 12
|
|
||||||
alignment = 1
|
|
||||||
|
|
||||||
[node name="ConfirmButton" type="Button" parent="ConfirmationPanel/Margin/Content/Buttons"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(190, 64)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "confirm"
|
|
||||||
|
|
||||||
[node name="CancelConfirmButton" type="Button" parent="ConfirmationPanel/Margin/Content/Buttons"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
custom_minimum_size = Vector2(160, 64)
|
|
||||||
layout_mode = 2
|
|
||||||
text = "cancel"
|
|
||||||
|
|
||||||
[node name="SettingsPanel" parent="." instance=ExtResource("3_settings")]
|
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
z_index = 210
|
z_index = 210
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue