a game about throwing hammers made for the github game off
Diffstat (limited to 'fx/trail.gd')
| -rw-r--r-- | fx/trail.gd | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/fx/trail.gd b/fx/trail.gd new file mode 100644 index 0000000..dd8f064 --- /dev/null +++ b/fx/trail.gd @@ -0,0 +1,85 @@ +## Draws a 2D trail using a [Line2D]. +class_name Trail2D +extends Line2D + +@icon("./trail2d_icon.svg") + +## Enable or disable the trail +@export var is_emitting := false: + set(emitting): + is_emitting = emitting + if not is_inside_tree(): + await ready + + if is_emitting: + clear_points() + _points_creation_time.clear() + _last_point = to_local(target.global_position) + +## Resolution. Smaller = more points +@export var resolution := 2.0 + +## The lifetime for each point +@export var lifetime := 0.5 + +## Maximum number of points +@export var max_points := 100 + +## Optional path to the target node to follow. If not set, the instance follows its parent. +@onready @export var target: Node2D + +var _points_creation_time := [] +var _last_point := Vector2.ZERO +var _clock := 0.0 + +func _ready() -> void: + if not target: + target = get_parent() as Node2D + + joint_mode = Line2D.LINE_JOINT_BEVEL + top_level = true + clear_points() + position = Vector2.ZERO + _last_point = to_local(target.global_position) + + +func _process(delta: float) -> void: + _clock += delta + remove_older() + + if not is_emitting: + return + + # Adding new points if necessary. + var desired_point := (target.global_position) + var distance: float = _last_point.distance_to(desired_point) + if distance > resolution: + add_timed_point(desired_point, _clock) + + +## Creates a new point and stores its creation time. +func add_timed_point(point: Vector2, time: float) -> void: + add_point(point) + _points_creation_time.append(time) + _last_point = point + if get_point_count() > max_points: + remove_first_point() + + +## Removes the first point in the line and the corresponding time. +func remove_first_point() -> void: + if get_point_count() > 1: + remove_point(0) + _points_creation_time.pop_front() + + +## Remove points older than [code]lifetime[/code]. +func remove_older() -> void: + for creation_time in _points_creation_time: + var delta = _clock - creation_time + if delta > lifetime: + remove_first_point() + # Points in `_points_creation_time` are ordered from oldest to newest so as soon as a point + # isn't older than `lifetime`, we know all remaining points should stay as well. + else: + break |