xiandie/scene/ground/script/c01/s12_飘动的寻人启事.gd

120 lines
3.0 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@tool
extends Node2D
@export var velocity := 0.1
@export var remote_node: Node2D:
set(val):
remote_node = val
if is_node_ready():
if remote_node:
remote_transform.remote_path = remote_node.get_path()
else:
remote_transform.remote_path = ""
@export var area_size := Vector2(400, 50):
set(val):
area_size = val
queue_redraw()
@export var gizmo_outline_color := Color(0.5, 0.3, 0.4, 0.8):
set(val):
gizmo_outline_color = val
queue_redraw()
@onready var remote_transform := $RemoteTransform2D as RemoteTransform2D
func _draw() -> void:
remote_transform.remote_path = remote_node.get_path()
if Engine.is_editor_hint():
# draw gizmo
var area_rect = Rect2(Vector2.ZERO, area_size)
# fill
var fill_color = gizmo_outline_color
fill_color.a = 0.4
draw_rect(area_rect, fill_color)
# outline
draw_rect(area_rect, gizmo_outline_color, false, 1.0)
# 最多保持 4 个点; 先生成两个在左侧,再生成两个在右侧,然后再回到左侧,以此循环,形成左右摇摆的闭合路径
var bezier_points = []
var current_position = Vector2.ZERO
var weight := 0.0
func _ready() -> void:
# init points
for i in range(4):
bezier_points.append(_rand_point())
func _new_point() -> void:
# remove the first point
bezier_points.remove_at(0)
# add a new point
bezier_points.append(_rand_point())
var _generated_points = -1
func _rand_point() -> Vector2:
_generated_points += 1
# upleft,mid,downright,upright,mid,downleft,...
match _generated_points % 6:
0:
_generated_points = 0
# upleft
return Vector2(
randf_range(0, area_size.x * 0.3), randf_range(area_size.y * 0.6, area_size.y)
)
1:
# upleft to center
return Vector2(
randf_range(area_size.x * 0.4, area_size.x * 0.6),
randf_range(area_size.y * 0.3, area_size.y * 0.7)
)
2:
# center to downright
return Vector2(
randf_range(area_size.x * 0.7, area_size.x), randf_range(0, area_size.y * 0.4)
)
3:
# downright to upright
return Vector2(
randf_range(area_size.x * 0.7, area_size.x),
randf_range(area_size.y * 0.6, area_size.y)
)
4:
# upright to center
return Vector2(
randf_range(area_size.x * 0.4, area_size.x * 0.6),
randf_range(area_size.y * 0.3, area_size.y * 0.7)
)
_:
# center to downleft
return Vector2(randf_range(0, area_size.x * 0.3), randf_range(0, area_size.y * 0.4))
# 从 bezier_points 中取出 4 个点,然后进行贝塞尔曲线插值
# 设置到 remote_transform 的 position 与 rotation
# 速度为 velocity权重为 weight
func _process(delta: float) -> void:
if Engine.is_editor_hint():
return
weight += velocity * delta
if weight >= 1.0:
weight = 0.0
_new_point()
var p0 = bezier_points[0]
var p1 = bezier_points[1]
var p2 = bezier_points[2]
var p3 = bezier_points[3]
var p = p1.cubic_interpolate(p2, p0, p3, weight)
# var p = p1.bezier_interpolate(p0, p3, p2, weight)
remote_transform.position = p
# bezier 插值获得角度
remote_transform.rotation = lerp_angle(remote_transform.rotation, p1.angle_to(p2), delta)