Seguir uma curva

Uma Curve2D montada ponto a ponto, desenhada com tessellate e percorrida por três PathFollow2D. O progresso é a única coisa que muda.

O editor acima está rodando este projeto. Mude uma linha e ele recarrega.

Classes do Godot usadas

Path2DPathFollow2DCurve2D

O código

scripts/main.gd
extends Node

const SPEED: float = 240.0
const MARKERS: int = 3
const COLORS: Array = ['#8da5f3', '#8eef97', '#f3d48d']

var followers: Array[PathFollow2D] = []


func _ready() -> void:
	_add_background()

	var view: Vector2 = get_viewport().get_visible_rect().size

	var curve: Curve2D = Curve2D.new()
	curve.add_point(Vector2(view.x * 0.12, view.y * 0.74), Vector2.ZERO, Vector2(0, -230))
	curve.add_point(Vector2(view.x * 0.36, view.y * 0.26), Vector2(-140, 0), Vector2(140, 0))
	curve.add_point(Vector2(view.x * 0.63, view.y * 0.76), Vector2(-150, 0), Vector2(150, 0))
	curve.add_point(Vector2(view.x * 0.88, view.y * 0.3), Vector2(0, 220), Vector2.ZERO)

	var line: Line2D = Line2D.new()
	line.width = 4.0
	line.default_color = Color('#2a2f3d')
	line.points = curve.tessellate(5, 2.0)
	add_child(line)

	for i in curve.point_count:
		add_child(_make_circle(curve.get_point_position(i), 7.0, Color('#2a2f3d')))

	var path: Path2D = Path2D.new()
	path.curve = curve
	add_child(path)

	for i in MARKERS:
		var follow: PathFollow2D = PathFollow2D.new()
		follow.rotates = true
		follow.add_child(_make_arrow(Color(COLORS[i])))
		path.add_child(follow)
		follow.progress_ratio = float(i) / MARKERS
		followers.append(follow)

	_add_label('the grey line is the Curve2D, each arrow is a PathFollow2D walking it by progress', Vector2(40, 40))


func _process(delta: float) -> void:
	for follow in followers:
		follow.progress += SPEED * delta


func _make_arrow(color: Color) -> Polygon2D:
	var arrow: Polygon2D = Polygon2D.new()
	arrow.polygon = PackedVector2Array([Vector2(18, 0), Vector2(-22, -15), Vector2(-14, 0), Vector2(-22, 15)])
	arrow.color = color

	return arrow


func _make_circle(at: Vector2, radius: float, color: Color) -> Polygon2D:
	var points: PackedVector2Array = PackedVector2Array()

	for i in 20:
		points.append(Vector2(cos(TAU * i / 20.0), sin(TAU * i / 20.0)) * radius)

	var circle: Polygon2D = Polygon2D.new()
	circle.polygon = points
	circle.color = color
	circle.position = at

	return circle


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 _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)

Mais exemplos de Movimento