D5/UI/popup/dialogue.gd

143 lines
5.3 KiB
GDScript

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)