Migrate pause menu to bubble UI
This commit is contained in:
parent
f04d8db8ac
commit
46175ee405
6 changed files with 694 additions and 109 deletions
195
ui/components/bubble_menu/bubble_transition_flurry.gd
Normal file
195
ui/components/bubble_menu/bubble_transition_flurry.gd
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
class_name BubbleTransitionFlurry
|
||||
extends Control
|
||||
|
||||
const BUBBLE_TEXTURES: Array[Texture2D] = [
|
||||
preload("res://ui/assets/title/bubbles/bubble1.png"),
|
||||
preload("res://ui/assets/title/bubbles/bubble2.png"),
|
||||
preload("res://ui/assets/title/bubbles/bubble3.png"),
|
||||
]
|
||||
const BUBBLE_COUNT_MIN: int = 4
|
||||
const BUBBLE_COUNT_MAX: int = 5
|
||||
const BUBBLE_SCALE_MIN: float = 0.65
|
||||
const BUBBLE_SCALE_MAX: float = 1.15
|
||||
const BUBBLE_OPACITY_MIN: float = 0.55
|
||||
const BUBBLE_OPACITY_MAX: float = 0.90
|
||||
const BUBBLE_DRIFT_MIN: float = 10.0
|
||||
const BUBBLE_DRIFT_MAX: float = 45.0
|
||||
const BUBBLE_WOBBLE_MIN: float = 3.0
|
||||
const BUBBLE_WOBBLE_MAX: float = 9.0
|
||||
const BUBBLE_TRAVEL_DURATION_MIN: float = 7.0
|
||||
const BUBBLE_TRAVEL_DURATION_MAX: float = 14.0
|
||||
const BUBBLE_EDGE_MARGIN: float = 16.0
|
||||
const BURST_X_MIN: float = 0.36
|
||||
const BURST_X_MAX: float = 0.64
|
||||
const BURST_Y_MIN: float = 0.60
|
||||
const BURST_Y_MAX: float = 0.78
|
||||
const MAX_ACTIVE_BUBBLES: int = 30
|
||||
|
||||
var _rng := RandomNumberGenerator.new()
|
||||
var _generation: int = 0
|
||||
var _bubbles: Array[TextureRect] = []
|
||||
var _tweens: Dictionary[int, Tween] = {}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_rng.randomize()
|
||||
|
||||
|
||||
func emit_flurry() -> void:
|
||||
if not visible or BUBBLE_TEXTURES.is_empty():
|
||||
return
|
||||
var bubble_count: int = _rng.randi_range(
|
||||
BUBBLE_COUNT_MIN,
|
||||
BUBBLE_COUNT_MAX
|
||||
)
|
||||
for _bubble_index: int in bubble_count:
|
||||
if not _spawn_bubble(
|
||||
_rng.randf_range(BURST_X_MIN, BURST_X_MAX),
|
||||
_rng.randf_range(BURST_Y_MIN, BURST_Y_MAX)
|
||||
):
|
||||
break
|
||||
|
||||
|
||||
func clear_flurries() -> void:
|
||||
_generation += 1
|
||||
for tween: Tween in _tweens.values():
|
||||
if tween != null and tween.is_valid():
|
||||
tween.kill()
|
||||
_tweens.clear()
|
||||
for bubble: TextureRect in _bubbles:
|
||||
if is_instance_valid(bubble):
|
||||
bubble.queue_free()
|
||||
_bubbles.clear()
|
||||
|
||||
|
||||
func get_active_bubble_count() -> int:
|
||||
return _bubbles.size()
|
||||
|
||||
|
||||
func _spawn_bubble(normalized_x: float, start_y_ratio: float) -> bool:
|
||||
if _bubbles.size() >= MAX_ACTIVE_BUBBLES:
|
||||
return false
|
||||
var layer_size: Vector2 = size
|
||||
if layer_size.x <= 1.0 or layer_size.y <= 1.0:
|
||||
return false
|
||||
var texture: Texture2D = BUBBLE_TEXTURES[
|
||||
_rng.randi_range(0, BUBBLE_TEXTURES.size() - 1)
|
||||
]
|
||||
var presentation_size: Vector2 = texture.get_size() * _rng.randf_range(
|
||||
BUBBLE_SCALE_MIN,
|
||||
BUBBLE_SCALE_MAX
|
||||
)
|
||||
var bubble := TextureRect.new()
|
||||
bubble.name = "TransitionBubble"
|
||||
bubble.texture = texture
|
||||
bubble.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||
bubble.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||
bubble.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
||||
bubble.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
bubble.size = presentation_size
|
||||
bubble.modulate.a = _rng.randf_range(
|
||||
BUBBLE_OPACITY_MIN,
|
||||
BUBBLE_OPACITY_MAX
|
||||
)
|
||||
add_child(bubble)
|
||||
_bubbles.append(bubble)
|
||||
|
||||
var drift_direction: float = (
|
||||
1.0 if _rng.randi_range(0, 1) == 1 else -1.0
|
||||
)
|
||||
var horizontal_drift: float = _rng.randf_range(
|
||||
BUBBLE_DRIFT_MIN,
|
||||
BUBBLE_DRIFT_MAX
|
||||
) * drift_direction
|
||||
var wobble_amplitude: float = _rng.randf_range(
|
||||
BUBBLE_WOBBLE_MIN,
|
||||
BUBBLE_WOBBLE_MAX
|
||||
)
|
||||
var wobble_cycles: float = _rng.randf_range(0.8, 1.6)
|
||||
var wobble_phase: float = _rng.randf_range(0.0, TAU)
|
||||
var full_start_y: float = (
|
||||
layer_size.y + presentation_size.y + BUBBLE_EDGE_MARGIN
|
||||
)
|
||||
var start_y: float = (
|
||||
start_y_ratio * layer_size.y - presentation_size.y * 0.5
|
||||
)
|
||||
var end_y: float = -presentation_size.y - BUBBLE_EDGE_MARGIN
|
||||
var full_distance: float = maxf(full_start_y - end_y, 1.0)
|
||||
var remaining_distance: float = maxf(start_y - end_y, 1.0)
|
||||
var travel_duration: float = _rng.randf_range(
|
||||
BUBBLE_TRAVEL_DURATION_MIN,
|
||||
BUBBLE_TRAVEL_DURATION_MAX
|
||||
) * remaining_distance / full_distance
|
||||
var generation: int = _generation
|
||||
_update_bubble(
|
||||
0.0,
|
||||
bubble,
|
||||
normalized_x,
|
||||
start_y_ratio,
|
||||
horizontal_drift,
|
||||
wobble_amplitude,
|
||||
wobble_cycles,
|
||||
wobble_phase,
|
||||
generation
|
||||
)
|
||||
var tween: Tween = create_tween()
|
||||
_tweens[bubble.get_instance_id()] = tween
|
||||
tween.tween_method(
|
||||
_update_bubble.bind(
|
||||
bubble,
|
||||
normalized_x,
|
||||
start_y_ratio,
|
||||
horizontal_drift,
|
||||
wobble_amplitude,
|
||||
wobble_cycles,
|
||||
wobble_phase,
|
||||
generation
|
||||
),
|
||||
0.0,
|
||||
1.0,
|
||||
travel_duration
|
||||
)
|
||||
tween.finished.connect(
|
||||
_finish_bubble.bind(bubble, generation),
|
||||
CONNECT_ONE_SHOT
|
||||
)
|
||||
return true
|
||||
|
||||
|
||||
func _update_bubble(
|
||||
progress: float,
|
||||
bubble: TextureRect,
|
||||
normalized_x: float,
|
||||
start_y_ratio: float,
|
||||
horizontal_drift: float,
|
||||
wobble_amplitude: float,
|
||||
wobble_cycles: float,
|
||||
wobble_phase: float,
|
||||
generation: int,
|
||||
) -> void:
|
||||
if generation != _generation or not is_instance_valid(bubble):
|
||||
return
|
||||
var start_y: float = start_y_ratio * size.y - bubble.size.y * 0.5
|
||||
var end_y: float = -bubble.size.y - BUBBLE_EDGE_MARGIN
|
||||
var wobble: float = sin(
|
||||
wobble_phase + progress * TAU * wobble_cycles
|
||||
) * wobble_amplitude
|
||||
bubble.position = Vector2(
|
||||
normalized_x * size.x
|
||||
+ horizontal_drift * progress
|
||||
+ wobble
|
||||
- bubble.size.x * 0.5,
|
||||
lerpf(start_y, end_y, progress)
|
||||
)
|
||||
|
||||
|
||||
func _finish_bubble(bubble: TextureRect, generation: int) -> void:
|
||||
if generation != _generation or not is_instance_valid(bubble):
|
||||
return
|
||||
_tweens.erase(bubble.get_instance_id())
|
||||
_bubbles.erase(bubble)
|
||||
bubble.queue_free()
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
clear_flurries()
|
||||
|
|
@ -0,0 +1 @@
|
|||
uid://bxqtrj8vujks3
|
||||
Loading…
Add table
Add a link
Reference in a new issue