Randoloot/scripts/game/ship_energy_indicator.gd
2026-10-11 18:42:15 +02:00

71 lines
2.8 KiB
GDScript

extends Node2D
var player: CharacterBody2D
var _display_ratio := 1.0
var _display_shield_ratio := 1.0
var _display_hull_ratio := 1.0
var _background: StyleBoxFlat
func _ready() -> void:
# World rendering interpolates this position together with the ship and camera.
top_level = true
process_physics_priority = 1
global_position = player.global_position
reset_physics_interpolation()
z_index = 24
_display_ratio = _energy_ratio()
_display_shield_ratio = _shield_ratio()
_display_hull_ratio = _hull_ratio()
_background = StyleBoxFlat.new()
_background.bg_color = Color("101925")
_background.border_color = Color("456277")
_background.set_border_width_all(1)
func _physics_process(_delta: float) -> void:
if is_instance_valid(player):
var teleported := global_position.distance_to(player.global_position) > 600.0
global_position = player.global_position
if teleported:
reset_physics_interpolation()
func _process(delta: float) -> void:
if not is_instance_valid(player):
return
visible = not bool(player.get("_is_destroyed"))
var target := _energy_ratio()
_display_ratio = lerpf(_display_ratio, target, 1.0 - exp(-20.0 * delta))
if absf(_display_ratio - target) < 0.001:
_display_ratio = target
var shield_target := _shield_ratio()
_display_shield_ratio = lerpf(_display_shield_ratio, shield_target, 1.0 - exp(-20.0 * delta))
if absf(_display_shield_ratio - shield_target) < 0.001:
_display_shield_ratio = shield_target
var hull_target := _hull_ratio()
_display_hull_ratio = lerpf(_display_hull_ratio, hull_target, 1.0 - exp(-20.0 * delta))
if absf(_display_hull_ratio - hull_target) < 0.001:
_display_hull_ratio = hull_target
queue_redraw()
func _energy_ratio() -> float:
return clampf(float(player.get("energy")) / maxf(1.0, float(player.get("max_energy"))), 0.0, 1.0)
func _shield_ratio() -> float:
return clampf(float(player.get("shields")) / maxf(1.0, float(player.get("max_shields"))), 0.0, 1.0)
func _hull_ratio() -> float:
return clampf(float(player.get("hull")) / maxf(1.0, float(player.get("max_hull"))), 0.0, 1.0)
func _draw() -> void:
if not is_instance_valid(player):
return
var color := Color("71e3ff") if _energy_ratio() >= 0.25 else Color("ffbd66")
var bar_position := Vector2(-44, 48)
draw_style_box(_background, Rect2(bar_position - Vector2(2, 2), Vector2(92, 10)))
draw_rect(Rect2(bar_position, Vector2(88 * _display_ratio, 6)), color)
var shield_bar_position := bar_position + Vector2(0, 14)
draw_style_box(_background, Rect2(shield_bar_position - Vector2(2, 2), Vector2(92, 10)))
draw_rect(Rect2(shield_bar_position, Vector2(88 * _display_shield_ratio, 6)), Color.WHITE)
var hull_bar_position := bar_position + Vector2(0, 28)
draw_style_box(_background, Rect2(hull_bar_position - Vector2(2, 2), Vector2(92, 10)))
draw_rect(Rect2(hull_bar_position, Vector2(88 * _display_hull_ratio, 6)), Color("ef5967"))