上下浮动
九个形状共用同一条正弦波,每个都比前一个提前一个相位。不用 Tween,也不用 AnimationPlayer。
上方的编辑器正在运行这个项目。改一行代码,它就会重新加载。
用到的 Godot 类
Node2DLine2DTime
代码
scripts/main.gd
extends Node
const COLUMNS: int = 9
const AMPLITUDE: float = 130.0
const FREQUENCY: float = 1.7
const PHASE_STEP: float = 0.6
var bobs: Array[Node2D] = []
var row: float = 0.0
func _ready() -> void:
_add_background()
var view: Vector2 = get_viewport().get_visible_rect().size
row = view.y * 0.55
for i in COLUMNS:
var column: float = view.x * (i + 1) / (COLUMNS + 1)
var rail: Line2D = Line2D.new()
rail.width = 2.0
rail.default_color = Color('#2a2f3d')
rail.points = PackedVector2Array([Vector2(column, row - AMPLITUDE), Vector2(column, row + AMPLITUDE)])
add_child(rail)
var bob: Node2D = Node2D.new()
bob.position = Vector2(column, row)
bob.add_child(_make_circle(26.0, Color('#8da5f3').lerp(Color('#8eef97'), float(i) / (COLUMNS - 1))))
add_child(bob)
bobs.append(bob)
_add_label('sin(time * frequency + phase), one phase step per column', Vector2(40, 40))
func _process(_delta: float) -> void:
var time: float = Time.get_ticks_msec() / 1000.0
for i in bobs.size():
var wave: float = sin(time * FREQUENCY + i * PHASE_STEP)
bobs[i].position.y = row + wave * AMPLITUDE
bobs[i].scale = Vector2.ONE * (1.0 + wave * 0.12)
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 26:
points.append(Vector2(cos(TAU * i / 26.0), sin(TAU * i / 26.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)