Randoloot/scripts/game/solar_energy_effect.gd
2026-10-10 23:07:57 +02:00

55 lines
2.0 KiB
GDScript

extends Node2D
var player: CharacterBody2D
var _particles: Array[Dictionary] = []
var _emission := 0.0
var _phase := 0.0
func _ready() -> void:
top_level = true
process_physics_priority = 1
global_position = player.global_position
reset_physics_interpolation()
z_index = 22
func _physics_process(_delta: float) -> void:
if is_instance_valid(player):
global_position = player.global_position
func _process(delta: float) -> void:
if not is_instance_valid(player):
return
_phase += delta
var bonus := float(player.call("get_solar_regeneration"))
var charging := bonus > 0.0 and float(player.get("energy")) < float(player.get("max_energy"))
if charging:
_emission += delta * 30.0
while _emission >= 1.0 and _particles.size() < 32:
_emission -= 1.0
var star: Node2D = player.get("charging_star")
var direction := (global_position - star.global_position).normalized()
var source := star.global_position + direction * float(star.get("radius"))
source += direction.orthogonal() * randf_range(-35.0, 35.0)
_particles.append({"source": source, "age": 0.0, "duration": randf_range(0.45, 0.8)})
else:
_emission = 0.0
for index in range(_particles.size() - 1, -1, -1):
_particles[index]["age"] += delta
if _particles[index]["age"] >= _particles[index]["duration"]:
_particles.remove_at(index)
queue_redraw()
func _draw() -> void:
if not is_instance_valid(player) or bool(player.get("_is_destroyed")):
return
for particle in _particles:
var progress: float = particle["age"] / particle["duration"]
var source: Vector2 = particle["source"] - global_position
var point := source.lerp(Vector2.ZERO, progress * progress)
var tail := source.lerp(Vector2.ZERO, maxf(0, progress - 0.06) ** 2)
var color := Color(0.35, 0.92, 1.0, sin(progress * PI))
draw_line(tail, point, color, 2.0, true)
draw_circle(point, 2.5, color)
if not _particles.is_empty():
draw_arc(Vector2.ZERO, 31.0 + sin(_phase * 5.0) * 2.0, 0, TAU, 48, Color(0.35, 0.92, 1.0, 0.45), 2.0, true)