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

157 lines
4.4 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 area_size := Vector2(500, 150):
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_node := $Node2D
@onready var remote_sprite := %Sprite2D
@onready var sign_mark := %Sign as Sign
var interacted_x = -10000
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 个点; 先生成两个在左侧,再生成两个在右侧,然后再回到左侧,以此循环,形成左右摇摆的闭合路径
var bezier_points = [Vector2(0, 0), Vector2(200, 30), Vector2(350, 60), Vector2(400, 80), Vector2(300, 90), Vector2(250, 120), Vector2(150, 150), Vector2(80, 150), Vector2(0, 150)]
var current_position = Vector2.ZERO
var weight := 0.0
func _ready() -> void:
if Engine.is_editor_hint():
return
# 手动配置运动点
# # init points
# for i in range(5):
# bezier_points.append(_rand_point())
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
func _next_point() -> void:
# remove the first point
bezier_points.remove_at(0)
# # add a new point
# bezier_points.append(_rand_point())
func _on_interacted() -> void:
if interacted_x == -10000:
_set_current_x_as_interacted_x()
var inspect_texture = preload("res://asset/art/scene/c01/s07_书店外/纸片_正面.png")
SceneManager.get_inspector().pop_prop_inspection("", inspect_texture, true)
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))
# 从 bezier_points 中取出 4 个点,然后进行贝塞尔曲线插值
# 设置到 remote_transform 的 position 与 rotation
# 速度为 velocity权重为 weight
func _process(delta: float) -> void:
if Engine.is_editor_hint() or not visible or interacted_x > -10000:
return
# 如果不到 4 个点,跳过
if bezier_points.size() < 4:
return
weight += velocity * delta
if weight >= 1.0:
weight = 0.0
_next_point()
# 当不到 4 个点时,落到地上
if bezier_points.size() < 4:
remote_node.position.y = area_size.y
_set_current_x_as_interacted_x()
return
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_node.position = p
# bezier 插值获得角度
remote_sprite.rotation = lerp_angle(remote_sprite.rotation, p1.angle_to(p2), delta)
remote_sprite.skew = -remote_sprite.rotation * 0.5