创建新工程
This commit is contained in:
385
scripts/CharacterCustomization.gd
Normal file
385
scripts/CharacterCustomization.gd
Normal 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)
|
||||
Reference in New Issue
Block a user