extends Node ## Main scene script ## 主场景脚本,负责初始化和协调各个管理器 # 引用各个管理器节点 @onready var network_manager = $NetworkManager @onready var game_state_manager = $GameStateManager @onready var ui_layer = $UILayer @onready var game_world = $GameWorld @onready var error_notification: ErrorNotification = null @onready var loading_indicator: LoadingIndicator = null # 游戏场景和角色 var office_scene: Node2D = null var world_manager: Node = null var input_handler: Node = null var player_character: CharacterBody2D = null # 测试管理器 var dialogue_test_manager = null # 社交系统 var social_manager: SocialManager = null # 服务器配置 var server_url: String = "ws://localhost:8080" func _ready(): """主场景初始化""" print("[MAIN] AI Town Game - Main scene loaded") print("[MAIN] Godot version: ", Engine.get_version_info()) # 初始化游戏 _initialize_game() func _initialize_game(): """初始化游戏系统""" print("[MAIN] Initializing game systems...") # 初始化安全系统 _initialize_security() # 初始化社交系统 _initialize_social_systems() # 初始化UI组件 _setup_ui_components() # 连接信号 _connect_all_signals() # 显示登录界面 ui_layer.show_screen("login") print("[MAIN] Game initialization complete") ## 初始化安全系统 func _initialize_security(): """初始化安全配置和系统""" print("[SECURITY] Initializing security systems...") # 初始化安全配置 SecurityConfig.initialize() # 验证安全配置 if not SecurityConfig.validate_config(): print("[ERROR] Security configuration validation failed") if error_notification: error_notification.show_error("安全系统初始化失败") var security_level = SecurityConfig.get_security_level() print("[SECURITY] Security level: ", security_level) # 如果是高安全级别,记录安全事件 if security_level == "high": print("[INFO] [SYSTEM] High security mode activated") ## 初始化社交系统 func _initialize_social_systems(): """初始化社交系统""" print("[SOCIAL] Initializing social systems...") # 创建社交管理器 social_manager = SocialManager.new() social_manager.name = "SocialManager" add_child(social_manager) # 设置网络管理器引用 social_manager.set_network_manager(network_manager) # 连接社交系统信号 social_manager.social_notification.connect(_on_social_notification) social_manager.friend_activity.connect(_on_friend_activity) print("[SOCIAL] Social systems initialized") ## 设置UI组件 func _setup_ui_components(): """设置UI组件(错误通知和加载指示器)""" _setup_error_notification() _setup_loading_indicator() ## 连接所有信号 func _connect_all_signals(): """连接所有必要的信号""" # 游戏状态管理器信号 if not game_state_manager.state_changed.is_connected(_on_game_state_changed): game_state_manager.state_changed.connect(_on_game_state_changed) # 网络管理器信号 _connect_network_signals() # UI信号(延迟连接) _connect_ui_signals() ## 连接网络信号 func _connect_network_signals(): """连接网络管理器的所有信号""" var signals_to_connect = [ ["connected_to_server", _on_connected_to_server], ["disconnected_from_server", _on_disconnected_from_server], ["connection_error", _on_connection_error], ["message_received", _on_message_received] ] for signal_data in signals_to_connect: var signal_name = signal_data[0] var callback = signal_data[1] var signal_obj = network_manager.get(signal_name) if signal_obj and not signal_obj.is_connected(callback): signal_obj.connect(callback) ## 设置错误通知系统 func _setup_error_notification(): """设置错误通知系统""" var error_scene = load("res://scenes/ErrorNotification.tscn") if error_scene: error_notification = error_scene.instantiate() ui_layer.add_child(error_notification) print("[MAIN] Error notification system initialized") else: print("[ERROR] Failed to load ErrorNotification scene") ## 设置加载指示器 func _setup_loading_indicator(): """设置加载指示器""" var loading_scene = load("res://scenes/LoadingIndicator.tscn") if loading_scene: loading_indicator = loading_scene.instantiate() ui_layer.add_child(loading_indicator) print("[MAIN] Loading indicator initialized") else: print("[ERROR] Failed to load LoadingIndicator scene") ## 连接 UI 信号 func _connect_ui_signals(): """连接 UI 层的信号""" # 延迟一帧,确保 UI 元素已创建 await get_tree().process_frame # 连接登录界面信号 if ui_layer.login_screen: ui_layer.login_screen.login_requested.connect(login_to_server) ui_layer.login_screen.create_character_requested.connect(_on_create_character_ui_requested) print("Login screen signals connected") # 注意:角色创建界面会在切换到 CHARACTER_CREATION 状态时创建和连接 ## 处理创建角色 UI 请求 func _on_create_character_ui_requested(): """处理创建角色 UI 请求""" # 检查是否已连接并认证 if not network_manager.is_server_connected(): # 未连接,显示错误提示 if error_notification: error_notification.show_error("请先登录后再创建角色") return # 已连接,切换到角色创建界面 game_state_manager.change_state(GameStateManager.GameState.CHARACTER_CREATION) ## 处理返回登录请求 func _on_back_to_login_requested(): """处理返回登录请求""" game_state_manager.change_state(GameStateManager.GameState.LOGIN) ## 游戏状态变化处理 func _on_game_state_changed(old_state, new_state): """ 处理游戏状态变化 @param old_state: 旧状态 @param new_state: 新状态 """ print("Game state changed: ", GameStateManager.GameState.keys()[old_state], " -> ", GameStateManager.GameState.keys()[new_state]) # 根据状态切换 UI 和场景 match new_state: GameStateManager.GameState.LOGIN: ui_layer.show_screen("login") _cleanup_game_world() GameStateManager.GameState.CHARACTER_CREATION: ui_layer.show_screen("character_creation") # 连接角色创建界面的信号(如果还没连接) _connect_character_creation_signals() GameStateManager.GameState.IN_GAME: ui_layer.show_screen("hud") _load_game_world() # 更新HUD的网络状态 _update_hud_network_status() GameStateManager.GameState.DISCONNECTED: ui_layer.show_screen("login") _cleanup_game_world() ## 连接角色创建界面信号 func _connect_character_creation_signals(): """连接角色创建界面的信号""" if ui_layer.character_creation and not ui_layer.character_creation.character_created.is_connected(create_character): ui_layer.character_creation.character_created.connect(create_character) ui_layer.character_creation.back_requested.connect(_on_back_to_login_requested) print("Character creation signals connected") ## 网络连接成功 func _on_connected_to_server(): """服务器连接成功""" print("Connected to server successfully") if loading_indicator: loading_indicator.hide_loading() if error_notification: error_notification.show_success("连接成功!") # 更新HUD网络状态 _update_hud_network_status() ## 更新HUD网络状态 func _update_hud_network_status(): """更新HUD的网络状态显示""" if ui_layer.hud: ui_layer.hud.update_network_status(network_manager.is_server_connected()) ## 网络断开连接 func _on_disconnected_from_server(): """服务器断开连接""" print("Disconnected from server") if loading_indicator: loading_indicator.hide_loading() # 根据当前状态决定如何处理断线 var current_state = game_state_manager.current_state if current_state == GameStateManager.GameState.IN_GAME: # 在游戏中断线,显示警告但不退出游戏 if error_notification: error_notification.show_warning("与服务器断开连接,正在尝试重连...", 3.0) # 不改变游戏状态,让玩家继续游戏(离线模式) else: # 在登录或角色创建时断线,返回登录界面 if error_notification: error_notification.show_warning("与服务器断开连接") game_state_manager.change_state(GameStateManager.GameState.DISCONNECTED) ## 网络连接错误 func _on_connection_error(error: String): """网络连接错误""" print("Connection error: ", error) if loading_indicator: loading_indicator.hide_loading() if error_notification: error_notification.show_network_error(error) ## 接收到网络消息 func _on_message_received(message: Dictionary): """ 处理接收到的网络消息 @param message: 消息字典 """ if not message.has("type"): print("Warning: Received message without type") return var msg_type = message["type"] print("Received message: ", msg_type) # 根据消息类型处理 match msg_type: "auth_response": _handle_auth_response(message) "character_create": _handle_character_create_response(message) "character_move": _handle_character_move(message) "character_state": _handle_character_state(message) "world_state": _handle_world_state(message) "friend_request", "friend_response", "private_message", "event_invitation", "social_update": # 社交相关消息由SocialManager处理 pass _: print("Unknown message type: ", msg_type) ## 处理认证响应 func _handle_auth_response(message: Dictionary): """处理认证响应""" var data = message.get("data", {}) if data.get("success", false): print("Authentication successful") # 进入角色创建或游戏 game_state_manager.change_state(GameStateManager.GameState.CHARACTER_CREATION) else: var error_msg = data.get("error", "Unknown error") print("Authentication failed: ", error_msg) if error_notification: error_notification.show_error("登录失败: " + error_msg) ## 处理角色创建响应 func _handle_character_create_response(message: Dictionary): """处理角色创建响应""" var data = message.get("data", {}) if data.get("success", false): print("Character created successfully") var character_data = data.get("character", {}) game_state_manager.player_data = character_data # 隐藏加载指示器 if loading_indicator: loading_indicator.hide_loading() game_state_manager.change_state(GameStateManager.GameState.IN_GAME) else: var error_msg = data.get("error", "Unknown error") print("Character creation failed: ", error_msg) # 隐藏加载指示器并显示错误 if loading_indicator: loading_indicator.hide_loading() if error_notification: error_notification.show_error("创建角色失败: " + error_msg) ## 处理角色移动消息 func _handle_character_move(message: Dictionary): """处理其他角色的移动""" if not world_manager: return var data = message.get("data", {}) var character_id = data.get("characterId", "") var position = data.get("position", {}) print("Received character_move message - ID: ", character_id, " Position: ", position) # 检查是否是玩家自己的角色 var player_id = game_state_manager.player_data.get("id", "") if game_state_manager.player_data else "" if character_id == player_id: print("IGNORED: Received move message for player's own character - preventing auto-movement") return # 忽略玩家自己的移动消息,避免网络回环导致自动移动 if character_id and position: var pos = Vector2(position.get("x", 0), position.get("y", 0)) world_manager.update_character_position(character_id, pos) ## 处理角色状态更新 func _handle_character_state(message: Dictionary): """处理角色状态更新""" if not world_manager: return var data = message.get("data", {}) var character_id = data.get("characterId", "") var character_name = data.get("name", "") var position = data.get("position", {}) var is_online = data.get("isOnline", false) # 检查是否是玩家自己的角色,避免处理自己的状态更新 var player_id = game_state_manager.player_data.get("id", "") if game_state_manager.player_data else "" if character_id == player_id: print("Ignoring state update for player's own character: ", character_id) return if character_id: var state = { "id": character_id, "name": character_name, "position": position, "isOnline": is_online } print("Processing character state update - ID: ", character_id, " Online: ", is_online) world_manager.update_character_state(character_id, state) ## 处理世界状态同步 func _handle_world_state(message: Dictionary): """处理世界状态同步""" print("Received world state") var data = message.get("data", {}) var characters = data.get("characters", []) if world_manager: # 更新所有角色 for character_data in characters: var char_id = character_data.get("id", "") if char_id and char_id != game_state_manager.player_data.get("id", ""): # 不是玩家自己,生成或更新远程角色 world_manager.spawn_or_update_character(character_data) ## 加载游戏世界 func _load_game_world(): """加载游戏世界场景""" print("Loading game world...") # 加载 Datawhale 办公室场景 var office_scene_path = "res://scenes/DatawhaleOffice.tscn" var office_packed = load(office_scene_path) if office_packed: office_scene = office_packed.instantiate() game_world.add_child(office_scene) # 获取世界管理器 world_manager = office_scene.get_node_or_null("WorldManager") if not world_manager: # 如果场景中没有,创建一个 world_manager = preload("res://scripts/WorldManager.gd").new() world_manager.name = "WorldManager" office_scene.add_child(world_manager) # 设置角色容器 var characters_container = office_scene.get_node_or_null("Characters") if characters_container: world_manager.set_character_container(characters_container) print("Character container set for WorldManager") else: print("Warning: Characters container not found in office scene") # 创建玩家角色 _spawn_player_character() # 创建输入处理器 _setup_input_handler() # 初始化对话测试管理器 _setup_dialogue_test_manager() print("Game world loaded") else: print("Error: Failed to load office scene") ## 生成玩家角色 func _spawn_player_character(): """生成玩家角色""" print("Spawning player character...") var player_scene_path = "res://scenes/PlayerCharacter.tscn" var player_packed = load(player_scene_path) if player_packed and office_scene: player_character = player_packed.instantiate() # 获取角色容器 var characters_container = office_scene.get_characters_container() if characters_container: characters_container.add_child(player_character) else: office_scene.add_child(player_character) # 初始化玩家角色 var player_data = game_state_manager.player_data print("Player data from game_state_manager: ", player_data) if player_data: player_character.initialize(player_data) # 设置初始位置(场景中央)- 覆盖服务器位置 print("Setting player position to scene center: Vector2(1000, 750)") player_character.global_position = Vector2(1000, 750) # 确保角色完全静止 - 延迟执行确保所有系统都已初始化 _ensure_player_character_stopped() # 设置相机跟随 if office_scene.has_method("set_camera_target"): office_scene.set_camera_target(player_character) # 连接角色信号 player_character.position_updated.connect(_on_player_position_updated) print("Player character spawned") else: print("Error: Failed to load player character scene") ## 确保玩家角色停止移动 func _ensure_player_character_stopped(): """确保玩家角色完全停止移动""" if player_character and player_character.has_method("_reset_movement_state"): # 延迟执行,确保所有初始化完成 await get_tree().process_frame player_character._reset_movement_state() print("Player character movement state ensured to be stopped") # 同时清除输入处理器的状态 if input_handler and input_handler.has_method("_clear_all_movement_state"): input_handler._clear_all_movement_state() print("Input handler movement state cleared") ## 设置输入处理器 func _setup_input_handler(): """设置输入处理器""" print("Setting up input handler...") # 创建输入处理器 input_handler = preload("res://scripts/InputHandler.gd").new() input_handler.name = "InputHandler" add_child(input_handler) # 连接输入信号 input_handler.move_input.connect(_on_move_input) input_handler.interact_input.connect(_on_interact_input) print("Input handler ready") ## 玩家移动输入 func _on_move_input(direction: Vector2): """ 处理玩家移动输入 @param direction: 移动方向 """ if direction != Vector2.ZERO: print("Player input received - Direction: ", direction) if player_character: player_character.move_to(direction) ## 玩家交互输入 func _on_interact_input(): """处理玩家交互输入""" print("Interact key pressed (E)") if not player_character: print("No player character") return # 获取附近的NPC if dialogue_test_manager: var player_pos = player_character.global_position var nearby_npcs = dialogue_test_manager.get_nearby_npcs(player_pos, 100.0) if nearby_npcs.size() > 0: var closest_npc = nearby_npcs[0] print("Starting dialogue with: ", closest_npc.name) # 开始对话 dialogue_test_manager.start_dialogue_with_npc(closest_npc.id) # 显示对话框 if ui_layer and ui_layer.dialogue_box: ui_layer.show_dialogue(closest_npc.name) else: print("Dialogue box not available") else: print("No NPCs nearby to interact with") # 显示提示 if ui_layer and ui_layer.hud: ui_layer.hud.show_interaction_hint("附近没有可对话的角色") # 2秒后隐藏提示 await get_tree().create_timer(2.0).timeout ui_layer.hud.hide_interaction_hint() else: print("Dialogue test manager not available") ## 对话消息接收处理 func _on_dialogue_message_received(sender: String, message: String): """处理接收到的对话消息,显示在UI中""" if ui_layer and ui_layer.dialogue_box: # 只显示NPC的消息,玩家消息已经在DialogueBox中直接显示了 if sender != "player": var display_name = sender ui_layer.dialogue_box.add_message(display_name, message) else: # 玩家消息已经显示,这里只做日志记录 print("Player message processed: ", message) ## 玩家位置更新 func _on_player_position_updated(new_position: Vector2): """ 玩家位置更新时发送到服务器 @param new_position: 新位置 """ if network_manager.is_server_connected(): var message = MessageProtocol.create_character_move("", new_position, Vector2.ZERO) network_manager.send_message(message) ## 清理游戏世界 func _cleanup_game_world(): """清理游戏世界""" print("Cleaning up game world...") if input_handler: input_handler.queue_free() input_handler = null if office_scene: office_scene.queue_free() office_scene = null player_character = null world_manager = null print("Game world cleaned up") ## 登录到服务器 func login_to_server(username: String): """ 登录到服务器 @param username: 用户名 """ print("Attempting to login as: ", username) # 显示加载状态 if loading_indicator: loading_indicator.show_connecting() # 如果已经连接,直接发送认证请求 if network_manager.is_server_connected(): _send_auth_request(username) return # 否则先连接到服务器 network_manager.connect_to_server(server_url) # 等待连接成功 await network_manager.connected_to_server # 连接成功后发送认证请求 _send_auth_request(username) ## 发送认证请求 func _send_auth_request(username: String): """发送认证请求到服务器""" print("Sending auth request for: ", username) var auth_message = MessageProtocol.create_auth_request(username) network_manager.send_message(auth_message) ## 创建角色 func create_character(character_name: String, personalization_data: Dictionary = {}): """ 创建新角色 @param character_name: 角色名称 @param personalization_data: 个性化数据(外观、个性等) """ print("Creating character: ", character_name) print("Personalization data: ", personalization_data) # 检查是否已连接 if not network_manager.is_server_connected(): if error_notification: error_notification.show_error("未连接到服务器,无法创建角色") # 返回登录界面 game_state_manager.change_state(GameStateManager.GameState.LOGIN) return # 显示加载状态 if loading_indicator: loading_indicator.show_creating_character() # 创建包含个性化数据的角色创建消息 var create_message = MessageProtocol.create_character_create(character_name, personalization_data) network_manager.send_message(create_message) ## 设置对话测试管理器 func _setup_dialogue_test_manager(): """设置对话测试管理器""" print("Setting up dialogue test manager...") # 创建简单对话测试脚本 var test_script = load("res://scripts/SimpleDialogueTest.gd") dialogue_test_manager = test_script.new() dialogue_test_manager.name = "SimpleDialogueTest" add_child(dialogue_test_manager) # 获取对话系统引用 var dialogue_system = office_scene.get_node_or_null("DialogueSystem") if not dialogue_system: # 如果场景中没有,创建一个 var dialogue_script = load("res://scripts/DialogueSystem.gd") dialogue_system = dialogue_script.new() dialogue_system.name = "DialogueSystem" office_scene.add_child(dialogue_system) # 设置测试环境 dialogue_test_manager.setup_test(world_manager, dialogue_system) # 连接对话系统信号 if dialogue_system.message_received.connect(dialogue_test_manager.handle_player_message) != OK: print("Failed to connect dialogue signal") # 连接对话系统消息到UI if dialogue_system.message_received.connect(_on_dialogue_message_received) != OK: print("Failed to connect dialogue UI signal") # 设置对话系统的社交管理器引用 if social_manager: dialogue_system.set_social_manager(social_manager) # 延迟生成测试NPC,确保所有系统都已初始化 if player_character: var player_pos = player_character.global_position # 使用call_deferred确保在下一帧执行 dialogue_test_manager.call_deferred("spawn_test_npcs", player_pos) print("Dialogue test manager setup complete") ## 处理社交通知 func _on_social_notification(notification_type: String, title: String, message: String, _data: Dictionary): """ 处理社交系统通知 @param notification_type: 通知类型 @param title: 通知标题 @param message: 通知消息 @param _data: 通知数据 (暂未使用) """ print("[SOCIAL] Notification: ", notification_type, " - ", title, ": ", message) # 显示通知给用户 if error_notification: match notification_type: "friend_request", "friend_accepted", "event_invitation": error_notification.show_success(message, 5.0) "friend_online": error_notification.show_info(message, 3.0) "milestone": error_notification.show_success(message, 8.0) _: error_notification.show_info(message, 4.0) ## 处理好友活动 func _on_friend_activity(activity_type: String, data: Dictionary): """ 处理好友活动事件 @param activity_type: 活动类型 @param data: 活动数据 """ print("[SOCIAL] Friend activity: ", activity_type, " - ", data) # 这里可以更新UI显示好友活动 # 比如更新好友列表、活动日志等 func _process(_delta): # 主循环处理 pass