Randoloot/scripts/game/impact_effect.gd
2026-10-25 22:38:13 +01:00

81 lines
3.0 KiB
GDScript

extends Node2D
var _effect_color := Color(1.0,0.72,0.32)
var _elapsed := 0.0
var _duration := 0.30
var _is_explosion := false
var _kind := DamageTypes.Type.ENERGY
var _normal := Vector2.UP
var _directions: Array[Vector2] = []
var _speeds: Array[float] = []
var _sizes: Array[float] = []
func configure(is_explosion: bool, effect_color: Color) -> void:
_is_explosion = is_explosion
_effect_color = effect_color
_duration = 0.58 if is_explosion else 0.30
_seed_sparks()
func configure_contact(kind: int, incoming: Vector2) -> void:
_kind = clampi(kind,0,2)
_normal = -incoming.normalized() if incoming.length_squared()>0.001 else Vector2.UP
_effect_color = [Color("ffc071"),Color("68d9ff"),Color("88f35b")][_kind]
if not _is_explosion: _duration = [0.28,0.34,0.44][_kind]
_seed_sparks()
func _seed_sparks() -> void:
_directions.clear()
_speeds.clear()
_sizes.clear()
var count := 22 if _is_explosion else (13 if _kind==0 else 8)
for i in count:
var angle := randf_range(-1.35,1.35)
var direction := Vector2.RIGHT.rotated(randf()*TAU) if _is_explosion else _normal.rotated(angle)
_directions.append(direction)
_speeds.append(randf_range(65,230) if _kind==0 else randf_range(25,100))
_sizes.append(randf_range(1.1,2.4))
func _ready() -> void:
z_index = 30
add_to_group("combat_impacts")
if get_tree().get_nodes_in_group("combat_impacts").size()>72:
for old in get_tree().get_nodes_in_group("combat_impacts"):
if old!=self and not old.is_queued_for_deletion():
old.queue_free()
break
func _process(delta: float) -> void:
_elapsed += delta
if _elapsed>=_duration: queue_free()
else: queue_redraw()
func _draw() -> void:
var t := clampf(_elapsed/_duration,0,1)
var fade := 1.0-t
var flash := maxf(0.0,1.0-t*4.0)
var glow_radius := 20.0 if _is_explosion else 9.0
for layer in range(4,0,-1):
draw_circle(Vector2.ZERO,glow_radius*float(layer)/4.0,Color(_effect_color,flash*0.035))
draw_circle(Vector2.ZERO,2.5*flash,Color(_effect_color.lightened(0.8),flash))
if _is_explosion:
draw_arc(Vector2.ZERO,7+t*65,0,TAU,48,Color(_effect_color,fade*0.5),1.5,true)
if _kind==DamageTypes.Type.ENERGY:
for i in 4:
var angle := float(i)*TAU/4+_normal.angle()+t*0.4
draw_arc(Vector2.ZERO,4+t*18,angle,angle+0.8,10,Color(_effect_color,fade*0.65),1.1,true)
var a := Vector2.RIGHT.rotated(angle)*4
var b := Vector2.RIGHT.rotated(angle+0.25)*(9+t*12)
draw_polyline(PackedVector2Array([a,(a+b)*0.5+Vector2(2,-2),b]),Color(_effect_color,fade*0.65),1.0,true)
elif _kind==DamageTypes.Type.RADIATION:
for i in 3:
var angle := i*TAU/3+t*2
draw_arc(Vector2.ZERO,5+t*17,angle,angle+0.95,12,Color(_effect_color,fade*0.4),1.2,true)
for i in _directions.size():
var direction := _directions[i]
var point := direction*_speeds[i]*_elapsed
if _kind==DamageTypes.Type.KINETIC:
draw_line(point-direction*(3+fade*7),point,Color(_effect_color,fade),_sizes[i]*fade+0.4,true)
if i%3==0:
draw_line(point+Vector2(-1,0),point+Vector2(1,1),Color(0.65,0.72,0.79,fade),2.0,true)
else:
draw_circle(point,_sizes[i]*fade,Color(_effect_color,fade*0.75))