67 lines
2.2 KiB
GDScript3
67 lines
2.2 KiB
GDScript3
|
|
extends Node2D
|
||
|
|
|
||
|
|
# Forgejo #87: a brief spray of sparks off the hull that just fired.
|
||
|
|
#
|
||
|
|
# Firing was silent at the ship's end - a bolt simply appeared in front of it.
|
||
|
|
# With a whole fleet shooting there was nothing tying a shot to the vessel it
|
||
|
|
# came from, which mattered more once the player started aiming: you could not
|
||
|
|
# see which of your ships were actually in the fight.
|
||
|
|
#
|
||
|
|
# Deliberately tiny and short. This fires several times a second per vessel,
|
||
|
|
# so it has to be legible at a glance and gone before the next one - anything
|
||
|
|
# with weight would turn a firing fleet into a smear.
|
||
|
|
#
|
||
|
|
# No class_name, and it loads itself by path: a global class-name identifier
|
||
|
|
# is not reliably resolvable from a script reached through a preload chain,
|
||
|
|
# which is what happens here. Same reason as ResourcePickupVFX.
|
||
|
|
|
||
|
|
const SELF_PATH: String = "res://vfx/MuzzleSparkVFX.gd"
|
||
|
|
const SPARK_COUNT: int = 4
|
||
|
|
const DURATION: float = 0.13
|
||
|
|
const SPREAD: float = 0.5
|
||
|
|
const LENGTH: float = 9.0
|
||
|
|
const COLOR: Color = Color(1.0, 0.88, 0.42)
|
||
|
|
|
||
|
|
var age: float = 0.0
|
||
|
|
var sparks: Array = []
|
||
|
|
|
||
|
|
|
||
|
|
static func spawn(parent: Node, world_position: Vector2, direction: Vector2) -> void:
|
||
|
|
if direction.length() < 0.001:
|
||
|
|
return
|
||
|
|
var vfx: Node2D = (load(SELF_PATH) as GDScript).new()
|
||
|
|
vfx.position = world_position
|
||
|
|
vfx.rotation = direction.angle()
|
||
|
|
parent.add_child(vfx)
|
||
|
|
|
||
|
|
|
||
|
|
func _ready() -> void:
|
||
|
|
# Built once here rather than per frame: the streaks never change shape,
|
||
|
|
# only how far along their own line they have travelled, so _draw reads
|
||
|
|
# fixed values. Same discipline as the explosion particles.
|
||
|
|
for i in range(SPARK_COUNT):
|
||
|
|
sparks.append({
|
||
|
|
"angle": randf_range(-SPREAD, SPREAD),
|
||
|
|
"speed": randf_range(190.0, 340.0),
|
||
|
|
"length": randf_range(LENGTH * 0.6, LENGTH),
|
||
|
|
})
|
||
|
|
queue_redraw()
|
||
|
|
|
||
|
|
|
||
|
|
func _process(delta: float) -> void:
|
||
|
|
age += delta
|
||
|
|
if age >= DURATION:
|
||
|
|
queue_free()
|
||
|
|
return
|
||
|
|
queue_redraw()
|
||
|
|
|
||
|
|
|
||
|
|
func _draw() -> void:
|
||
|
|
var t: float = clampf(age / DURATION, 0.0, 1.0)
|
||
|
|
var fade: float = 1.0 - t
|
||
|
|
for spark in sparks:
|
||
|
|
var heading: Vector2 = Vector2.RIGHT.rotated(float(spark.angle))
|
||
|
|
var start: Vector2 = heading * float(spark.speed) * age
|
||
|
|
var end: Vector2 = start + heading * float(spark.length)
|
||
|
|
NeonDraw.draw_glowing_line(self, start, end, COLOR, fade, 0.35,
|
||
|
|
COLOR.darkened(0.7))
|