173 lines
6.2 KiB
GDScript
173 lines
6.2 KiB
GDScript
extends Control
|
|
|
|
# 1. 预加载 TypewriterLogic 类 (请替换为你的实际路径!)
|
|
const TypewriterLogic = preload("res://UI/class/TypewriterLogic.gd")
|
|
|
|
# 导出变量保持不变
|
|
@export var typing_speed: float = 20.0 # 每秒显示的字符数
|
|
@export var label_node_path: NodePath = "Part_2/Part_3/Label" # Label节点的路径
|
|
|
|
# --- 基础变量 ---
|
|
var node_name: String
|
|
var next_ui_node = null
|
|
var dialogue_queue = []
|
|
var current_dialogue_index = 0
|
|
var is_active: bool = false
|
|
|
|
# --- 节点和模块引用 ---
|
|
var label: Label = null # 缓存Label节点引用
|
|
var typewriter: TypewriterLogic = null # 用于存储 TypewriterLogic 实例
|
|
|
|
# --- 移除旧的打字状态变量 ---
|
|
# var current_tween: Tween = null # 不再需要,由 TypewriterLogic 管理
|
|
# var is_typing: bool = false # 不再需要,由 TypewriterLogic 管理
|
|
|
|
|
|
func _ready() -> void:
|
|
node_name = str(self.name)
|
|
visible = false
|
|
set_process_input(false)
|
|
print(node_name + ": _ready executed, visibility set to false.")
|
|
|
|
# 尝试获取 Label 节点引用
|
|
label = get_node_or_null(label_node_path)
|
|
if label == null:
|
|
printerr(node_name + ": Failed to find Label node at path: ", label_node_path)
|
|
else:
|
|
# 2. 创建 TypewriterLogic 实例
|
|
print(node_name + ": Label found. Creating TypewriterLogic instance.")
|
|
typewriter = TypewriterLogic.new(label, typing_speed)
|
|
# 检查实例是否成功创建 (TypewriterLogic 内部会检查 Label 有效性)
|
|
if typewriter != null:
|
|
# 3. 连接 TypewriterLogic 的 finished 信号 (如果需要响应)
|
|
typewriter.finished.connect(_on_dialogue_typing_finished)
|
|
print(node_name + ": TypewriterLogic instance created and signal connected.")
|
|
else:
|
|
printerr(node_name + ": Failed to create TypewriterLogic instance.")
|
|
|
|
|
|
# 启动对话框显示 (逻辑基本不变)
|
|
func _start(dialogues, next_node = null) -> void:
|
|
print(node_name + ": _start function called. Making visible.")
|
|
if dialogues is String:
|
|
dialogue_queue = [dialogues]
|
|
else:
|
|
dialogue_queue = dialogues
|
|
|
|
current_dialogue_index = 0
|
|
next_ui_node = next_node
|
|
|
|
# 显示第一段对话 (现在会调用 typewriter)
|
|
_show_current_dialogue()
|
|
|
|
self.visible = true
|
|
is_active = true
|
|
if GameState: GameState.pause_game()
|
|
set_process_input(true)
|
|
|
|
|
|
# 4. 修改:使用 TypewriterLogic 显示当前对话
|
|
func _show_current_dialogue() -> void:
|
|
if current_dialogue_index < dialogue_queue.size():
|
|
# 检查 typewriter 实例是否有效
|
|
if typewriter == null:
|
|
printerr(node_name + ": TypewriterLogic instance is null. Cannot display text with effect.")
|
|
# 提供后备:如果 typewriter 无效,直接设置文本
|
|
if label != null:
|
|
label.text = dialogue_queue[current_dialogue_index]
|
|
label.visible_characters = label.text.length() # 确保完全可见
|
|
return
|
|
|
|
var full_text = dialogue_queue[current_dialogue_index]
|
|
print(node_name + ": Requesting typewriter to start typing.")
|
|
# 调用 TypewriterLogic 的方法来开始打字
|
|
typewriter.start_typing(full_text)
|
|
|
|
else:
|
|
# 对话队列结束
|
|
_close_dialogue()
|
|
|
|
|
|
# 5. 修改:使用 TypewriterLogic 处理输入事件
|
|
func _input(event):
|
|
if not is_active: return
|
|
|
|
# 检测鼠标左键点击事件
|
|
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed():
|
|
# 检查 typewriter 是否有效并且正在打字
|
|
if typewriter != null and typewriter.is_typing():
|
|
print(node_name + ": Input detected while typing. Skipping.")
|
|
# 调用 TypewriterLogic 的方法来跳过
|
|
typewriter.skip_typing()
|
|
get_viewport().set_input_as_handled()
|
|
# 如果没有在打字,则进入下一段对话或关闭
|
|
else:
|
|
print(node_name + ": Input detected. Advancing dialogue.")
|
|
current_dialogue_index += 1
|
|
if current_dialogue_index < dialogue_queue.size():
|
|
_show_current_dialogue() # 显示下一段对话
|
|
else:
|
|
_close_dialogue() # 所有对话结束,关闭
|
|
get_viewport().set_input_as_handled()
|
|
|
|
# 检测鼠标右键点击事件 - 直接关闭对话框
|
|
elif event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT and event.is_pressed():
|
|
print(node_name + ": Right-click detected. Closing dialogue.")
|
|
_close_dialogue() # 关闭会调用 typewriter.stop_typing()
|
|
get_viewport().set_input_as_handled()
|
|
|
|
|
|
# 6. 修改:关闭对话框时,调用 TypewriterLogic 的停止方法
|
|
func _close_dialogue():
|
|
if not is_active: return
|
|
|
|
print(node_name + ": Closing dialogue. Stopping typewriter if active.")
|
|
# --- 修改:调用 TypewriterLogic 的停止方法 ---
|
|
if typewriter != null:
|
|
typewriter.stop_typing()
|
|
# --- 修改结束 ---
|
|
|
|
self.visible = false
|
|
print(node_name + ": Dialogue UI hidden.")
|
|
|
|
# 恢复游戏并停止输入处理
|
|
if GameState:
|
|
print(node_name + ": Resuming game.")
|
|
GameState.resume_game()
|
|
set_process_input(false)
|
|
is_active = false # 确保在处理后续逻辑前标记为非活动
|
|
|
|
var parent = get_parent() # 获取父节点
|
|
|
|
# 检查是否有下一个UI需要显示 (逻辑保持不变)
|
|
if next_ui_node != null and is_instance_valid(next_ui_node):
|
|
print(node_name + ": Showing next UI: ", next_ui_node.name)
|
|
next_ui_node.visible = true
|
|
if next_ui_node.has_method("show_up"):
|
|
next_ui_node.show_up()
|
|
next_ui_node = null # 重置引用
|
|
else:
|
|
# 没有下一个UI节点 (逻辑保持不变)
|
|
if parent != null and parent.has_method("close_all_popups"):
|
|
print(node_name + ": No next UI node, calling parent's close_all_popups.")
|
|
parent.close_all_popups()
|
|
# ... (其他父节点检查逻辑) ...
|
|
next_ui_node = null
|
|
|
|
|
|
# 7. 添加:处理 TypewriterLogic 发出的 finished 信号的回调函数
|
|
func _on_dialogue_typing_finished():
|
|
# 这个函数会在 TypewriterLogic 自然完成一次打字动画时被调用
|
|
print(node_name + ": Received 'finished' signal from TypewriterLogic.")
|
|
# 你可以在这里添加任何需要在文本 *自然* 显示完毕后执行的逻辑
|
|
# 例如:显示一个 "继续" 图标,或者允许玩家在不点击的情况下自动前进等。
|
|
# 对于当前的点击继续逻辑,这个函数可能不需要做太多事情。
|
|
pass # 暂时留空
|
|
|
|
|
|
# 8. 移除旧的 _on_typing_finished 函数 (如果它只用于处理旧的 Tween)
|
|
# func _on_typing_finished(): # 这个函数不再需要了
|
|
# is_typing = false
|
|
# current_tween = null
|
|
# print(node_name + ": Typing finished.")
|