Suivre une courbe
Une Curve2D construite point par point, dessinée avec tessellate et parcourue par trois PathFollow2D. La progression est la seule chose qui change.
L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.
Classes Godot utilisées
Path2DPathFollow2DCurve2D
Le code
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)