Files
rthythm_archor_game/scenes/components/overhead_charge_segments.gd
T
2026-07-06 22:59:47 -07:00

97 lines
3.5 KiB
GDScript

class_name OverheadChargeSegments
extends Node2D
@export var charge_component_path: NodePath = ^"../ChargeComponent"
@export var segment_count := 3
@export var segment_size := Vector2(42.0, 12.0)
@export var segment_gap := 5.0
@export var border_width := 2.0
@export var background_color := Color(0.04, 0.055, 0.07, 0.86)
@export var fill_color := Color(0.25, 0.88, 1.0, 0.96)
@export var ready_fill_color := Color(1.0, 0.72, 0.18, 1.0)
@export var border_color := Color(0.88, 0.96, 1.0, 0.9)
@export var inactive_linger_seconds := 0.22
var _current := 0.0
var _maximum := 1.0
var _is_charge_ready := false
var _active := false
var _visual_linger_remaining := 0.0
@onready var _charge_component: Node = get_node_or_null(charge_component_path)
func _ready() -> void:
segment_count = maxi(1, segment_count)
z_index = max(z_index, 96)
visible = false
if _charge_component != null and _charge_component.has_signal("charge_changed"):
if not _charge_component.is_connected("charge_changed", _on_charge_changed):
_charge_component.connect("charge_changed", _on_charge_changed)
func active() -> bool:
return _active
func current_progress_segments() -> float:
if not _active and _visual_linger_remaining <= 0.0:
return 0.0
if _is_charge_ready:
return float(segment_count)
if _maximum <= float(segment_count - 1) + 0.1:
return clampf(_current + 1.0, 0.0, float(segment_count))
return clampf((_current / maxf(0.001, _maximum)) * float(segment_count), 0.0, float(segment_count))
func _on_charge_changed(current: float, maximum: float, ready: bool, active: bool) -> void:
var was_showing := _active or _visual_linger_remaining > 0.0
if active:
_current = maxf(0.0, current)
_maximum = maxf(0.001, maximum)
_is_charge_ready = ready
_visual_linger_remaining = 0.0
modulate.a = 1.0
visible = true
else:
if was_showing and inactive_linger_seconds > 0.0:
_visual_linger_remaining = inactive_linger_seconds
visible = true
else:
_visual_linger_remaining = 0.0
modulate.a = 1.0
visible = false
_active = active
queue_redraw()
func _process(delta: float) -> void:
if _visual_linger_remaining <= 0.0:
return
_visual_linger_remaining = maxf(0.0, _visual_linger_remaining - delta)
modulate.a = clampf(_visual_linger_remaining / maxf(0.001, inactive_linger_seconds), 0.0, 1.0)
if _visual_linger_remaining <= 0.0:
visible = false
modulate.a = 1.0
queue_redraw()
func _draw() -> void:
if not _active and _visual_linger_remaining <= 0.0:
return
var safe_count := maxi(1, segment_count)
var total_width := segment_size.x * float(safe_count) + segment_gap * float(maxi(0, safe_count - 1))
var origin := Vector2(-total_width * 0.5, 0.0)
var progress := current_progress_segments()
var plate_rect := Rect2(origin - Vector2(5.0, 4.0), Vector2(total_width + 10.0, segment_size.y + 8.0))
draw_rect(plate_rect, Color(0.0, 0.0, 0.0, 0.68), true)
draw_rect(plate_rect, Color(0.9, 0.96, 1.0, 0.42), false, 1.0)
for index: int in range(safe_count):
var rect := Rect2(origin + Vector2(float(index) * (segment_size.x + segment_gap), 0.0), segment_size)
draw_rect(rect, background_color, true)
var fill_ratio := clampf(progress - float(index), 0.0, 1.0)
if fill_ratio > 0.0:
var fill_rect := Rect2(rect.position + Vector2(border_width, border_width), Vector2(maxf(0.0, (segment_size.x - border_width * 2.0) * fill_ratio), maxf(0.0, segment_size.y - border_width * 2.0)))
draw_rect(fill_rect, ready_fill_color if _is_charge_ready else fill_color, true)
draw_rect(rect, border_color, false, border_width)