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)

Plus d'exemples de Mouvement