xiandie/scene/entity/ux/player_os.gd
2025-07-02 01:18:25 +08:00

81 lines
2.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.

extends Control
signal os_finished
@onready var os_pausing_timer = %OSTimer as Timer
@onready var os_label = %OSLabel as DialogueLabel
@onready var os_contaner = %PanelContainer as PanelContainer
var os_tween: Tween
# 保证每次 pop_os 后都会有一次 os_finished 信号
var os_finish_emit_lock := Mutex.new()
var os_finished_not_emitted := false
func _ready() -> void:
if Engine.is_editor_hint():
# 显示 os 效果
os_contaner.modulate.a = 1.0
os_label.text = "os 测试文本"
return
os_contaner.modulate.a = 0.0
os_label.text = ""
os_pausing_timer.timeout.connect(_on_os_line_timeout)
func pop_os(lines := []) -> void:
if os_tween:
os_tween.kill()
os_finish_emit_lock.lock()
if os_finished_not_emitted:
os_finished.emit()
os_finished_not_emitted = true
os_finish_emit_lock.unlock()
SceneManager.lock_player()
# os_finished 必然发送,防止 tween 被 kill保证一定 unlock
if os_finished.is_connected(SceneManager.unlock_player):
SceneManager.unlock_player()
else:
os_finished.connect(SceneManager.unlock_player, CONNECT_ONE_SHOT)
os_tween = create_tween()
os_label.text = ""
os_tween.tween_property(os_contaner, "modulate:a", 1.0, 0.2)
for line in lines:
# os_pausing_timer 启动最小时长 0.01 秒
var duration = max(GlobalConfigManager.config.os_wait_time, 0.01)
os_tween.tween_callback(_os_load_line.bind(line, duration))
os_tween.tween_property(os_contaner, "modulate:a", 0.0, 0.2)
os_tween.tween_callback(func():
os_finish_emit_lock.lock()
if os_finished_not_emitted:
os_finished_not_emitted = false
os_finished.emit()
os_finish_emit_lock.unlock()
)
# os 结束
await os_finished
func _os_load_line(line: DialogueLine, duration: float):
os_label.dialogue_line = line
os_label.type_out()
if os_label.finished_typing.is_connected(os_pausing_timer.start):
os_label.finished_typing.disconnect(os_pausing_timer.start)
os_label.finished_typing.connect(os_pausing_timer.start.bind(duration), CONNECT_ONE_SHOT)
os_tween.pause()
func _on_os_line_timeout(naturally := true):
if not naturally:
if os_label.is_typing:
os_label.skip_typing()
return
if os_tween and os_tween.is_valid():
os_tween.play()
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("interact"):
if os_pausing_timer and os_pausing_timer.time_left > 0:
get_viewport().set_input_as_handled()
_on_os_line_timeout(false)