Traînée de souris
Un Line2D qui gagne un point là où est le pointeur et lâche le plus ancien une fois plein. La courbe de largeur et le dégradé font l'estompage.
L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.
Classes Godot utilisées
Line2DGradientCurve
Le code
scripts/main.gd
extends Node
const MAX_POINTS: int = 110
const MIN_STEP: float = 7.0
const DRIFT_SPEED: float = 1.1
var trail: Line2D
var head: Polygon2D
var pointer: Vector2
var center: Vector2
var span: Vector2
var drifting: bool = true
var elapsed: float = 0.0
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
center = view * 0.5
span = view * 0.32
pointer = center
var gradient: Gradient = Gradient.new()
gradient.set_color(0, Color('#8da5f3', 0.0))
gradient.set_color(1, Color('#8eef97'))
var taper: Curve = Curve.new()
taper.add_point(Vector2(0.0, 0.05))
taper.add_point(Vector2(1.0, 1.0))
trail = Line2D.new()
trail.width = 16.0
trail.width_curve = taper
trail.gradient = gradient
trail.joint_mode = Line2D.LINE_JOINT_ROUND
trail.begin_cap_mode = Line2D.LINE_CAP_ROUND
trail.end_cap_mode = Line2D.LINE_CAP_ROUND
add_child(trail)
head = _make_circle(10.0, Color('#f3d48d'))
head.position = pointer
add_child(head)
_add_label('one point per frame, the oldest point leaves once the line is full', Vector2(40, 40))
print('move the mouse, the line keeps the last ' + str(MAX_POINTS) + ' points')
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
pointer = event.position
drifting = false
func _process(delta: float) -> void:
elapsed += delta
if drifting:
pointer = center + Vector2(cos(elapsed * DRIFT_SPEED), sin(elapsed * DRIFT_SPEED * 1.6)) * span
head.position = pointer
if trail.get_point_count() == 0 or trail.points[-1].distance_to(pointer) > MIN_STEP:
trail.add_point(pointer)
while trail.get_point_count() > MAX_POINTS:
trail.remove_point(0)
func _add_label(text: String, at: Vector2) -> void:
var label: Label = Label.new()
label.text = text
label.position = at
label.add_theme_color_override('font_color', Color('#999999'))
label.add_theme_font_size_override('font_size', 20)
add_child(label)
func _make_circle(radius: float, color: Color) -> Polygon2D:
var points: PackedVector2Array = PackedVector2Array()
for i in 24:
points.append(Vector2(cos(TAU * i / 24.0), sin(TAU * i / 24.0)) * radius)
var circle: Polygon2D = Polygon2D.new()
circle.polygon = points
circle.color = color
return circle
func _add_background() -> void:
var background: ColorRect = ColorRect.new()
background.color = Color('#12141a')
add_child(background)
background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)