extends Control ## 角色自定义界面 ## 允许玩家自定义角色外观和个性 # 预加载必要的类 const CharacterDataClass = preload("res://scripts/CharacterData.gd") # UI 元素 var container: VBoxContainer var tabs: TabContainer # 外观自定义 var appearance_container: VBoxContainer var body_color_picker: ColorPicker var head_color_picker: ColorPicker var hair_color_picker: ColorPicker var clothing_color_picker: ColorPicker var randomize_appearance_button: Button # 个性自定义 var personality_container: VBoxContainer var trait_checkboxes: Dictionary = {} var activity_option: OptionButton var bio_text: TextEdit # 预览 var preview_character: CharacterSprite # 按钮 var save_button: Button var cancel_button: Button # 数据 var character_data: Dictionary = {} # 信号 signal customization_saved(character_data: Dictionary) signal customization_cancelled() func _ready(): ## 初始化自定义界面 _create_ui() _setup_connections() ## 创建UI func _create_ui(): ## 创建自定义界面的所有UI元素 # 设置为全屏 anchor_right = 1.0 anchor_bottom = 1.0 # 添加半透明背景 var background = ColorRect.new() background.color = Color(0, 0, 0, 0.7) background.anchor_right = 1.0 background.anchor_bottom = 1.0 add_child(background) # 主容器 container = VBoxContainer.new() container.anchor_right = 1.0 container.anchor_bottom = 1.0 container.add_theme_constant_override("separation", 10) add_child(container) # 标题栏 var title_container = HBoxContainer.new() container.add_child(title_container) var title = Label.new() title.text = "角色自定义" title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER title.add_theme_font_size_override("font_size", 24) title.size_flags_horizontal = Control.SIZE_EXPAND_FILL title_container.add_child(title) var close_button = Button.new() close_button.text = "✕" close_button.custom_minimum_size = Vector2(40, 40) close_button.pressed.connect(_on_cancel_pressed) title_container.add_child(close_button) # 滚动容器 var scroll_container = ScrollContainer.new() scroll_container.size_flags_vertical = Control.SIZE_EXPAND_FILL container.add_child(scroll_container) # 标签页容器 tabs = TabContainer.new() tabs.custom_minimum_size = Vector2(0, 500) scroll_container.add_child(tabs) # 创建外观标签页 _create_appearance_tab() # 创建个性标签页 _create_personality_tab() # 预览区域 _create_preview_area() # 按钮区域 _create_button_area() ## 创建外观标签页 func _create_appearance_tab(): ## 创建外观自定义标签页 appearance_container = VBoxContainer.new() appearance_container.name = "外观" tabs.add_child(appearance_container) # 身体颜色 var body_section = _create_color_section("身体颜色", Color(0.29, 0.56, 0.89)) appearance_container.add_child(body_section.container) body_color_picker = body_section.picker # 头部颜色 var head_section = _create_color_section("头部颜色", Color(0.96, 0.90, 0.83)) appearance_container.add_child(head_section.container) head_color_picker = head_section.picker # 头发颜色 var hair_section = _create_color_section("头发颜色", Color(0.55, 0.27, 0.07)) appearance_container.add_child(hair_section.container) hair_color_picker = hair_section.picker # 服装颜色 var clothing_section = _create_color_section("服装颜色", Color(0.18, 0.55, 0.34)) appearance_container.add_child(clothing_section.container) clothing_color_picker = clothing_section.picker # 随机化按钮 randomize_appearance_button = Button.new() randomize_appearance_button.text = "随机外观" randomize_appearance_button.custom_minimum_size = Vector2(0, 40) appearance_container.add_child(randomize_appearance_button) ## 创建颜色选择区域 func _create_color_section(label_text: String, default_color: Color) -> Dictionary: ## 创建颜色选择区域 var section_container = VBoxContainer.new() var label = Label.new() label.text = label_text section_container.add_child(label) var picker = ColorPicker.new() picker.color = default_color picker.custom_minimum_size = Vector2(300, 200) picker.edit_alpha = false # 不需要透明度调节 section_container.add_child(picker) return { "container": section_container, "picker": picker } ## 创建个性标签页 func _create_personality_tab(): ## 创建个性自定义标签页 personality_container = VBoxContainer.new() personality_container.name = "个性" tabs.add_child(personality_container) # 个性特征 var traits_label = Label.new() traits_label.text = "个性特征 (最多选择4个):" personality_container.add_child(traits_label) var traits_grid = GridContainer.new() traits_grid.columns = 3 personality_container.add_child(traits_grid) var personalization = preload("res://scripts/CharacterPersonalization.gd") for trait_in in personalization.PERSONALITY_TRAITS: var checkbox = CheckBox.new() checkbox.text = trait_in traits_grid.add_child(checkbox) trait_checkboxes[trait_in] = checkbox # 喜欢的活动 var activity_label = Label.new() activity_label.text = "喜欢的活动:" personality_container.add_child(activity_label) activity_option = OptionButton.new() for activity in personalization.ACTIVITIES: activity_option.add_item(activity) personality_container.add_child(activity_option) # 个人简介 var bio_label = Label.new() bio_label.text = "个人简介 (可选):" personality_container.add_child(bio_label) bio_text = TextEdit.new() bio_text.custom_minimum_size = Vector2(0, 100) bio_text.placeholder_text = "介绍一下你的角色..." personality_container.add_child(bio_text) ## 创建预览区域 func _create_preview_area(): ## 创建角色预览区域 var preview_label = Label.new() preview_label.text = "预览:" preview_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER container.add_child(preview_label) var preview_container = CenterContainer.new() preview_container.custom_minimum_size = Vector2(0, 100) container.add_child(preview_container) preview_character = CharacterSprite.new() preview_container.add_child(preview_character) ## 创建按钮区域 func _create_button_area(): ## 创建按钮区域 var button_container = HBoxContainer.new() button_container.alignment = BoxContainer.ALIGNMENT_CENTER container.add_child(button_container) save_button = Button.new() save_button.text = "保存" save_button.custom_minimum_size = Vector2(100, 40) button_container.add_child(save_button) var spacer = Control.new() spacer.custom_minimum_size = Vector2(20, 0) button_container.add_child(spacer) cancel_button = Button.new() cancel_button.text = "取消" cancel_button.custom_minimum_size = Vector2(100, 40) button_container.add_child(cancel_button) ## 设置连接 func _setup_connections(): ## 设置信号连接 # 颜色选择器变化 body_color_picker.color_changed.connect(_on_appearance_changed) head_color_picker.color_changed.connect(_on_appearance_changed) hair_color_picker.color_changed.connect(_on_appearance_changed) clothing_color_picker.color_changed.connect(_on_appearance_changed) # 随机化按钮 randomize_appearance_button.pressed.connect(_on_randomize_appearance) # 个性特征复选框 for checkbox in trait_checkboxes.values(): checkbox.toggled.connect(_on_trait_toggled) # 按钮 save_button.pressed.connect(_on_save_pressed) cancel_button.pressed.connect(_on_cancel_pressed) ## 加载角色数据 func load_character_data(data: Dictionary): ## 加载角色数据到界面 ## @param data: 角色数据 character_data = data.duplicate(true) # 加载外观数据 var appearance = data.get(CharacterDataClass.FIELD_APPEARANCE, {}) if appearance.has("body_color"): body_color_picker.color = Color(appearance["body_color"]) if appearance.has("head_color"): head_color_picker.color = Color(appearance["head_color"]) if appearance.has("hair_color"): hair_color_picker.color = Color(appearance["hair_color"]) if appearance.has("clothing_color"): clothing_color_picker.color = Color(appearance["clothing_color"]) # 加载个性数据 var personality = data.get(CharacterDataClass.FIELD_PERSONALITY, {}) var traits = personality.get("traits", []) # 设置特征复选框 for trait_in in trait_checkboxes: trait_checkboxes[trait_in].button_pressed = trait_in in traits # 设置活动选项 var activity = personality.get("favorite_activity", "exploring") var personalization = preload("res://scripts/CharacterPersonalization.gd") var activity_index = personalization.ACTIVITIES.find(activity) if activity_index >= 0: activity_option.selected = activity_index # 设置简介 bio_text.text = personality.get("bio", "") # 更新预览 _update_preview() ## 外观变化回调 func _on_appearance_changed(_color: Color): ## 外观变化时更新预览 _update_preview() ## 随机化外观 func _on_randomize_appearance(): ## 随机化角色外观 var personalization = preload("res://scripts/CharacterPersonalization.gd") var random_appearance = personalization.generate_random_appearance() body_color_picker.color = Color(random_appearance["body_color"]) head_color_picker.color = Color(random_appearance["head_color"]) hair_color_picker.color = Color(random_appearance["hair_color"]) clothing_color_picker.color = Color(random_appearance["clothing_color"]) _update_preview() ## 特征切换回调 func _on_trait_toggled(_pressed: bool): ## 特征复选框切换时检查数量限制 var selected_traits = [] for trait_in in trait_checkboxes: if trait_checkboxes[trait_in].button_pressed: selected_traits.append(trait_in) # 限制最多4个特征 if selected_traits.size() > 4: # 找到最后选中的并取消 for trait_in in trait_checkboxes: if trait_checkboxes[trait_in].button_pressed and trait_in not in selected_traits.slice(0, 4): trait_checkboxes[trait_in].button_pressed = false break ## 保存按钮回调 func _on_save_pressed(): ## 保存自定义设置 # 更新外观数据 var appearance = { "sprite": "character_01", "color": "#FFFFFF", "body_color": body_color_picker.color.to_html(), "head_color": head_color_picker.color.to_html(), "hair_color": hair_color_picker.color.to_html(), "clothing_color": clothing_color_picker.color.to_html() } CharacterDataClass.set_appearance(character_data, appearance) # 更新个性数据 var selected_traits = [] for trait_in in trait_checkboxes: if trait_checkboxes[trait_in].button_pressed: selected_traits.append(trait_in) var personality = { "traits": selected_traits, "bio": bio_text.text, "favorite_activity": preload("res://scripts/CharacterPersonalization.gd").ACTIVITIES[activity_option.selected] } character_data[CharacterDataClass.FIELD_PERSONALITY] = personality customization_saved.emit(character_data) ## 取消按钮回调 func _on_cancel_pressed(): ## 取消自定义 customization_cancelled.emit() ## 处理输入事件 func _input(event): ## 处理ESC键关闭界面 if event is InputEventKey and event.pressed: if event.keycode == KEY_ESCAPE: _on_cancel_pressed() get_viewport().set_input_as_handled() ## 更新预览 func _update_preview(): ## 更新角色预览 if not preview_character: return var appearance = { "body_color": body_color_picker.color.to_html(), "head_color": head_color_picker.color.to_html(), "hair_color": hair_color_picker.color.to_html(), "clothing_color": clothing_color_picker.color.to_html() } var personalization = preload("res://scripts/CharacterPersonalization.gd") personalization.apply_appearance_to_sprite(preview_character, appearance)