75 lines
2.8 KiB
GDScript
75 lines
2.8 KiB
GDScript
extends Node2D
|
|
|
|
const DURATION := 1.6
|
|
var _texture: Texture2D
|
|
var _fragments: Array[Dictionary] = []
|
|
var _dust: Array[Dictionary] = []
|
|
var _elapsed := 0.0
|
|
var _rng := RandomNumberGenerator.new()
|
|
var _dust_color := Color("b4a99a")
|
|
|
|
func configure(sprite: Sprite2D) -> void:
|
|
_texture = sprite.texture
|
|
transform = sprite.global_transform
|
|
var sprite_scale := global_scale
|
|
scale = Vector2.ONE
|
|
_rng.randomize()
|
|
var dimensions := _texture.get_size()
|
|
var grid: Array[Vector2] = []
|
|
for y in 5:
|
|
for x in 5:
|
|
var vertex := Vector2(x, y) * dimensions / 4.0
|
|
if x > 0 and x < 4:
|
|
vertex.x += _rng.randf_range(-0.3, 0.3) * dimensions.x / 4.0
|
|
if y > 0 and y < 4:
|
|
vertex.y += _rng.randf_range(-0.3, 0.3) * dimensions.y / 4.0
|
|
grid.append(vertex)
|
|
for y in 4:
|
|
for x in 4:
|
|
var a := grid[y * 5 + x]
|
|
var b := grid[y * 5 + x + 1]
|
|
var c := grid[(y + 1) * 5 + x + 1]
|
|
var d := grid[(y + 1) * 5 + x]
|
|
for triangle in [[a, b, c], [a, c, d]]:
|
|
var center: Vector2 = (triangle[0] + triangle[1] + triangle[2]) / 3.0
|
|
var origin := (center - dimensions * 0.5) * sprite_scale
|
|
var points := PackedVector2Array()
|
|
var uv := PackedVector2Array()
|
|
for vertex: Vector2 in triangle:
|
|
points.append((vertex - center) * sprite_scale)
|
|
uv.append(vertex / dimensions)
|
|
var direction := origin.normalized() if origin.length_squared() > 0.1 else Vector2.RIGHT
|
|
_fragments.append({"points": points, "uv": uv, "position": origin,
|
|
"velocity": direction.rotated(_rng.randf_range(-0.35, 0.35)) * _rng.randf_range(70.0, 170.0),
|
|
"angle": 0.0, "spin": _rng.randf_range(-4.0, 4.0)})
|
|
_dust_color = Color("a1c7df") if "ice" in _texture.resource_path else Color("b4a99a")
|
|
for index in 28:
|
|
_dust.append({"direction": Vector2.RIGHT.rotated(_rng.randf_range(0.0, TAU)),
|
|
"speed": _rng.randf_range(45.0, 210.0), "size": _rng.randf_range(1.0, 3.0)})
|
|
z_index = 35
|
|
light_mask = 4
|
|
|
|
func _process(delta: float) -> void:
|
|
_elapsed += delta
|
|
if _elapsed >= DURATION:
|
|
queue_free()
|
|
return
|
|
for fragment in _fragments:
|
|
fragment.position += fragment.velocity * delta
|
|
fragment.velocity *= exp(-1.2 * delta)
|
|
fragment.angle += fragment.spin * delta
|
|
queue_redraw()
|
|
|
|
func _draw() -> void:
|
|
var fade := 1.0 - smoothstep(0.65, DURATION, _elapsed)
|
|
for fragment in _fragments:
|
|
draw_set_transform(fragment.position, fragment.angle)
|
|
draw_polygon(fragment.points, PackedColorArray([Color(1.0, 1.0, 1.0, fade)]), fragment.uv, _texture)
|
|
draw_set_transform(Vector2.ZERO)
|
|
var dust_fade := maxf(0.0, 1.0 - _elapsed / 0.8)
|
|
for mote in _dust:
|
|
var travel: Vector2 = mote.direction * mote.speed * (1.0 - exp(-2.0 * _elapsed)) / 2.0
|
|
draw_circle(travel, mote.size * (1.0 + _elapsed), Color(_dust_color, dust_fade * 0.65))
|
|
if _elapsed < 0.18:
|
|
draw_circle(Vector2.ZERO, 16.0 * (1.0 - _elapsed / 0.18), Color(0.85, 0.9, 1.0, (1.0 - _elapsed / 0.18) * 0.55))
|