Files
whale-town/scripts/UILayer.gd
2025-12-05 19:00:14 +08:00

245 lines
6.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 CanvasLayer
class_name UILayer
## UI 层管理器
## 管理所有 UI 界面的显示和切换
# UI 界面引用
var login_screen: Control = null
var character_creation: Control = null
var hud: Control = null
var dialogue_box: DialogueBox = null
# 当前显示的界面
var current_screen: Control = null
func _ready():
"""初始化 UI 层"""
# 设置为最上层
layer = 100
# 创建响应式布局容器
_setup_responsive_layout()
# 创建对话框(始终存在但默认隐藏)
_create_dialogue_box()
print("UILayer initialized")
## 创建对话框
func _create_dialogue_box():
"""创建对话框"""
dialogue_box = DialogueBox.new()
dialogue_box.name = "DialogueBox"
add_child(dialogue_box)
# 连接信号
dialogue_box.message_sent.connect(_on_dialogue_message_sent)
dialogue_box.dialogue_closed.connect(_on_dialogue_closed)
## 对话消息发送处理
func _on_dialogue_message_sent(message: String):
"""处理对话消息发送"""
print("Dialogue message sent: ", message)
# 获取Main节点并发送消息到对话系统
var main = get_node("/root/Main")
if not main:
print("ERROR: Main node not found")
return
if not main.dialogue_test_manager:
print("ERROR: Dialogue test manager not found")
return
var office_scene = main.office_scene
if not office_scene:
print("ERROR: Office scene not found")
return
var dialogue_system = office_scene.get_node_or_null("DialogueSystem")
if not dialogue_system:
print("ERROR: Dialogue system not found")
return
if not dialogue_system.is_dialogue_active():
print("WARNING: Dialogue not active")
return
# 发送消息到对话系统
var success = dialogue_system.send_message(message)
if not success:
print("ERROR: Failed to send message through dialogue system")
# 可以在这里添加错误提示给用户
if dialogue_box:
dialogue_box.add_message("系统", "消息发送失败,请重试")
## 对话关闭处理
func _on_dialogue_closed():
"""处理对话关闭"""
print("Dialogue closed - clearing movement state")
# 结束对话系统中的对话
var main = get_node("/root/Main")
if main and main.dialogue_test_manager:
var office_scene = main.office_scene
if office_scene:
var dialogue_system = office_scene.get_node_or_null("DialogueSystem")
if dialogue_system:
dialogue_system.end_dialogue()
# 强制清除玩家角色的移动状态
if main and main.player_character:
if main.player_character.has_method("_reset_movement_state"):
main.player_character._reset_movement_state()
print("Player character movement reset after dialogue close")
# 清除输入处理器的移动状态
if main and main.input_handler:
if main.input_handler.has_method("_clear_all_movement_state"):
main.input_handler._clear_all_movement_state()
print("Input handler movement cleared after dialogue close")
## 设置响应式布局
func _setup_responsive_layout():
"""
设置响应式布局容器
确保 UI 在不同分辨率下正确显示
"""
# 监听窗口大小变化
get_viewport().size_changed.connect(_on_viewport_size_changed)
## 显示指定界面
func show_screen(screen_name: String) -> void:
"""
显示指定的 UI 界面
@param screen_name: 界面名称login, character_creation, hud
"""
# 隐藏当前界面
if current_screen:
current_screen.hide()
# 显示新界面
match screen_name:
"login":
if not login_screen:
_create_login_screen()
current_screen = login_screen
"character_creation":
if not character_creation:
_create_character_creation()
current_screen = character_creation
"hud":
if not hud:
_create_hud()
current_screen = hud
_:
push_warning("Unknown screen: ", screen_name)
return
if current_screen:
current_screen.show()
## 隐藏所有界面
func hide_all_screens() -> void:
"""隐藏所有 UI 界面"""
if login_screen:
login_screen.hide()
if character_creation:
character_creation.hide()
if hud:
hud.hide()
# 注意:对话框不在这里隐藏,它独立管理
current_screen = null
## 显示对话框
func show_dialogue(target_name: String) -> void:
"""
显示对话框
@param target_name: 对话目标的名称
"""
if dialogue_box:
dialogue_box.start_dialogue(target_name)
## 隐藏对话框
func hide_dialogue() -> void:
"""隐藏对话框"""
if dialogue_box:
dialogue_box.close_dialogue()
## 创建登录界面
func _create_login_screen() -> void:
"""创建登录界面"""
login_screen = LoginScreen.new()
login_screen.name = "LoginScreen"
login_screen.hide()
add_child(login_screen)
# 连接信号
login_screen.login_requested.connect(_on_login_requested)
login_screen.create_character_requested.connect(_on_create_character_requested)
## 登录请求处理
func _on_login_requested(_username: String):
"""处理登录请求"""
# 信号会传递到 Main.gd 处理
pass
## 创建角色请求处理
func _on_create_character_requested():
"""处理创建角色请求"""
# 信号会传递到 Main.gd 处理
pass
## 创建角色创建界面
func _create_character_creation() -> void:
"""创建角色创建界面"""
character_creation = CharacterCreation.new()
character_creation.name = "CharacterCreation"
character_creation.hide()
add_child(character_creation)
# 连接信号
character_creation.character_created.connect(_on_character_created)
character_creation.back_requested.connect(_on_back_to_login)
## 角色创建完成处理
func _on_character_created(_character_name: String, _personalization_data: Dictionary = {}):
"""处理角色创建完成"""
# 信号会传递到 Main.gd 处理
pass
## 返回登录界面
func _on_back_to_login():
"""返回登录界面"""
show_screen("login")
## 创建游戏内 HUD
func _create_hud() -> void:
"""创建游戏内 HUD"""
hud = HUD.new()
hud.name = "HUD"
hud.hide()
add_child(hud)
## 窗口大小变化回调
func _on_viewport_size_changed():
"""
窗口大小变化时调整 UI 布局
"""
var viewport_size = get_viewport().get_visible_rect().size
print("Viewport size changed: ", viewport_size)
# 通知所有子界面更新布局
_update_all_layouts()
## 更新所有界面布局
func _update_all_layouts():
"""更新所有界面的布局以适应新的窗口大小"""
if login_screen and login_screen.has_method("update_layout"):
login_screen.update_layout()
if character_creation and character_creation.has_method("update_layout"):
character_creation.update_layout()
if hud and hud.has_method("update_layout"):
hud.update_layout()