创建新工程

This commit is contained in:
moyin
2025-12-05 19:00:14 +08:00
commit ff4fa5fffd
227 changed files with 32804 additions and 0 deletions

View File

@@ -0,0 +1,385 @@
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)