extends UIPage # 预加载 TypewriterLogic 类 (请替换为你的实际路径!) const _TypewriterLogic = preload("res://UI/class/TypewriterLogic.gd") @export var dialogues: Array var typing_speed: float = 20.0 # 每秒显示的字符数 var label_node_path: NodePath = "Part_2/Part_3/Label" # Label节点的路径 # --- 基础变量 --- var node_name: String # var next_ui_node = null # next_ui_node_path 从 UIPage 继承,这里不需要重复定义 var dialogue_queue = [] var current_dialogue_index = 0 # --- 节点和模块引用 --- var label: Label = null # 缓存Label节点引用 var typewriter: TypewriterLogic = null # 用于存储 TypewriterLogic 实例 func _ready() -> void: super._ready() # 确保调用父类的 _ready 方法 node_name = str(self.name) print(node_name + ": _ready executed.") # 尝试获取 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 信号 (如果需要响应) if not typewriter.is_connected("finished", Callable(self, "_on_dialogue_typing_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 _on_page_activated(): super._on_page_activated() # 调用父类的方法 print(node_name + ": Page activated.") _start(dialogues) func _on_page_deactivated(): super._on_page_deactivated() # 调用父类的方法 print(node_name + ": Page deactivated.") # 确保在页面停用时也停止输入处理和可能的游戏暂停状态 if typewriter != null: typewriter.stop_typing() set_process_input(false) # 启动对话框显示 func _start(p_dialogues) -> void: # Renamed parameter to avoid conflict print(node_name + ": _start function called.") if p_dialogues is String: dialogue_queue = [p_dialogues] elif p_dialogues is Array: dialogue_queue = p_dialogues.duplicate() # 使用 duplicate 以免修改原始导出数组 else: printerr(node_name + ": Invalid dialogues data type.") dialogue_queue = [] # 置空以避免后续错误 current_dialogue_index = 0 _show_current_dialogue() set_process_input(true) # 在页面激活时启用输入处理 # 使用 TypewriterLogic 显示当前对话 func _show_current_dialogue() -> void: if current_dialogue_index < dialogue_queue.size(): if typewriter == null: printerr(node_name + ": TypewriterLogic instance is null. Cannot display text with effect.") 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: '", full_text, "'") typewriter.start_typing(full_text) else: # 对话队列结束 print(node_name + ": Dialogue queue finished.") _close_dialogue() # 关闭对话框 func _close_dialogue(): print(node_name + ": Closing dialogue. Stopping typewriter if active.") if typewriter != null: typewriter.stop_typing() set_process_input(false) # 在关闭时禁用输入处理 print(node_name + ": Dialogue UI processing stopped.") # 处理 TypewriterLogic 发出的 finished 信号的回调函数 func _on_dialogue_typing_finished(): print(node_name + ": Received 'finished' signal from TypewriterLogic.") # 文本自然显示完毕后的逻辑。 # 例如,可以显示一个“点击继续”的提示图标。 # 对于当前的“点击任意处继续”逻辑,此函数可能不需要执行太多操作, # 因为 _input 函数会处理点击事件。 pass # --- 输入处理 --- # 新增/修改: 处理输入事件,特别是鼠标左键点击 func _input(event: InputEvent) -> void: # 只有当页面可见且输入处理已启用时才处理输入 # (set_process_input(true) 会在 _start 中调用) # (visible 状态由 MainController 和 UIPage 的 show_page/hide_page 管理) if not visible: return if event is InputEventMouseButton: if event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed(): print(node_name + ": Left-click detected.") # 行为1: 如果打字机正在打字,则立即完成当前行打字 (如果TypewriterLogic支持) # 行为2: 如果打字机已完成或未激活,则调用 go_next() # 当前的 TypewriterLogic 没有明确的 is_typing 或 skip_to_end 方法, # 所以我们直接调用 go_next()。 # go_next() -> _close_dialogue() -> typewriter.stop_typing() 会停止打字。 print(node_name + ": Calling go_next() due to left-click.") go_next() get_viewport().set_input_as_handled() # 消费事件,防止其他节点处理 return # 事件已处理 # 调用父类 (UIPage) 的 _input 方法,以保留其功能 (例如右键返回) # 如果此处的左键点击事件被处理并返回,则父类的 _input 不会再收到此特定事件。 super._input(event)