2025-02-05 12:34:38 +00:00
|
|
|
|
@tool
|
|
|
|
|
extends Node2D
|
|
|
|
|
|
2025-03-20 10:00:53 +00:00
|
|
|
|
@export var velocity := 0.15
|
2025-03-14 15:29:11 +00:00
|
|
|
|
@export var area_size := Vector2(500, 150):
|
2025-02-05 12:34:38 +00:00
|
|
|
|
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()
|
|
|
|
|
|
2025-02-12 07:03:41 +00:00
|
|
|
|
@onready var remote_node := $Node2D
|
|
|
|
|
@onready var remote_sprite := %Sprite2D
|
|
|
|
|
@onready var sign_mark := %Sign as Sign
|
|
|
|
|
|
|
|
|
|
var interacted_x = -10000
|
2025-02-05 12:34:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _draw() -> void:
|
|
|
|
|
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 个点; 先生成两个在左侧,再生成两个在右侧,然后再回到左侧,以此循环,形成左右摇摆的闭合路径
|
2025-03-20 10:00:53 +00:00
|
|
|
|
var bezier_points = [Vector2(0, 0), Vector2(150, 20), Vector2(250, 40), Vector2(350, 60), Vector2(400, 80), Vector2(300, 100), Vector2(250, 120), Vector2(160, 130), Vector2(120, 140), Vector2(60, 150), Vector2(0, 150)]
|
2025-02-05 12:34:38 +00:00
|
|
|
|
var current_position = Vector2.ZERO
|
|
|
|
|
var weight := 0.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _ready() -> void:
|
2025-02-12 07:03:41 +00:00
|
|
|
|
if Engine.is_editor_hint():
|
|
|
|
|
return
|
2025-03-14 15:29:11 +00:00
|
|
|
|
# 手动配置运动点
|
|
|
|
|
# # init points
|
|
|
|
|
# for i in range(5):
|
|
|
|
|
# bezier_points.append(_rand_point())
|
2025-02-12 07:03:41 +00:00
|
|
|
|
sign_mark.enabled = visible
|
|
|
|
|
sign_mark.interacted.connect(_on_interacted)
|
|
|
|
|
visibility_changed.connect(_on_visibility_changed)
|
|
|
|
|
interacted_x = ArchiveManager.archive.ground_archive().get_value(
|
|
|
|
|
name, "interacted_x", interacted_x
|
|
|
|
|
)
|
|
|
|
|
if interacted_x > -10000:
|
|
|
|
|
remote_node.position = Vector2(interacted_x, area_size.y)
|
|
|
|
|
remote_sprite.material = null
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func _on_visibility_changed() -> void:
|
|
|
|
|
sign_mark.enabled = visible
|
2025-02-05 12:34:38 +00:00
|
|
|
|
|
|
|
|
|
|
2025-03-14 15:29:11 +00:00
|
|
|
|
func _next_point() -> void:
|
2025-02-05 12:34:38 +00:00
|
|
|
|
# remove the first point
|
|
|
|
|
bezier_points.remove_at(0)
|
2025-03-14 15:29:11 +00:00
|
|
|
|
# # add a new point
|
|
|
|
|
# bezier_points.append(_rand_point())
|
2025-02-05 12:34:38 +00:00
|
|
|
|
|
|
|
|
|
|
2025-02-12 07:03:41 +00:00
|
|
|
|
func _on_interacted() -> void:
|
|
|
|
|
if interacted_x == -10000:
|
2025-03-14 15:29:11 +00:00
|
|
|
|
_set_current_x_as_interacted_x()
|
2025-03-09 14:01:51 +00:00
|
|
|
|
var inspect_texture = preload("res://asset/art/scene/c01/s07_书店外/纸片_正面.png")
|
2025-02-19 13:30:29 +00:00
|
|
|
|
SceneManager.get_inspector().pop_prop_inspection("", inspect_texture, true)
|
2025-02-12 07:03:41 +00:00
|
|
|
|
|
|
|
|
|
|
2025-03-14 15:29:11 +00:00
|
|
|
|
func _set_current_x_as_interacted_x() -> void:
|
|
|
|
|
interacted_x = remote_node.position.x
|
|
|
|
|
remote_node.position.y = area_size.y
|
|
|
|
|
remote_sprite.material = null
|
|
|
|
|
ArchiveManager.archive.ground_archive().set_pair(name, "interacted_x", interacted_x)
|
|
|
|
|
if GlobalConfig.DEBUG:
|
|
|
|
|
print("interacted_x:", interacted_x)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 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))
|
2025-02-05 12:34:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 从 bezier_points 中取出 4 个点,然后进行贝塞尔曲线插值
|
|
|
|
|
# 设置到 remote_transform 的 position 与 rotation
|
|
|
|
|
# 速度为 velocity,权重为 weight
|
|
|
|
|
func _process(delta: float) -> void:
|
2025-02-12 07:03:41 +00:00
|
|
|
|
if Engine.is_editor_hint() or not visible or interacted_x > -10000:
|
2025-02-05 12:34:38 +00:00
|
|
|
|
return
|
2025-03-14 15:29:11 +00:00
|
|
|
|
|
|
|
|
|
# 如果不到 4 个点,跳过
|
|
|
|
|
if bezier_points.size() < 4:
|
|
|
|
|
return
|
|
|
|
|
|
2025-02-05 12:34:38 +00:00
|
|
|
|
weight += velocity * delta
|
|
|
|
|
if weight >= 1.0:
|
|
|
|
|
weight = 0.0
|
2025-03-14 15:29:11 +00:00
|
|
|
|
_next_point()
|
|
|
|
|
|
|
|
|
|
# 当不到 4 个点时,落到地上
|
|
|
|
|
if bezier_points.size() < 4:
|
|
|
|
|
remote_node.position.y = area_size.y
|
|
|
|
|
_set_current_x_as_interacted_x()
|
|
|
|
|
return
|
2025-02-05 12:34:38 +00:00
|
|
|
|
|
|
|
|
|
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)
|
2025-02-06 12:19:45 +00:00
|
|
|
|
remote_node.position = p
|
2025-02-05 12:34:38 +00:00
|
|
|
|
# bezier 插值获得角度
|
2025-02-12 07:03:41 +00:00
|
|
|
|
remote_sprite.rotation = lerp_angle(remote_sprite.rotation, p1.angle_to(p2), delta)
|
|
|
|
|
remote_sprite.skew = -remote_sprite.rotation * 0.5
|