110 lines
2.7 KiB
GDScript
110 lines
2.7 KiB
GDScript
extends Control
|
||
class_name ChatBubble
|
||
## 对话气泡
|
||
## 在角色上方显示短暂的对话消息
|
||
|
||
# UI 元素
|
||
var background: Panel
|
||
var label: Label
|
||
var timer: Timer
|
||
|
||
# 配置
|
||
var bubble_padding: Vector2 = Vector2(10, 5)
|
||
var max_width: float = 200.0
|
||
var default_duration: float = 3.0
|
||
|
||
func _ready():
|
||
"""初始化对话气泡"""
|
||
_create_ui()
|
||
|
||
## 创建 UI 元素
|
||
func _create_ui():
|
||
"""创建气泡的所有 UI 元素"""
|
||
# 设置为不阻挡输入
|
||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
|
||
# 创建背景面板
|
||
background = Panel.new()
|
||
background.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
add_child(background)
|
||
|
||
# 创建文本标签
|
||
label = Label.new()
|
||
label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||
label.add_theme_font_size_override("font_size", 14)
|
||
label.add_theme_color_override("font_color", Color(0, 0, 0))
|
||
background.add_child(label)
|
||
|
||
# 创建计时器
|
||
timer = Timer.new()
|
||
timer.one_shot = true
|
||
timer.timeout.connect(_on_timer_timeout)
|
||
add_child(timer)
|
||
|
||
## 显示气泡
|
||
func show_bubble(message: String, duration: float = 0.0) -> void:
|
||
"""
|
||
显示对话气泡
|
||
@param message: 消息内容
|
||
@param duration: 显示时长(秒),0 表示使用默认时长
|
||
"""
|
||
if duration <= 0:
|
||
duration = default_duration
|
||
|
||
# 设置文本
|
||
label.text = message
|
||
|
||
# 计算大小
|
||
var text_size = label.get_combined_minimum_size()
|
||
text_size.x = min(text_size.x, max_width)
|
||
|
||
# 设置标签大小
|
||
label.custom_minimum_size = text_size
|
||
label.size = text_size
|
||
|
||
# 设置背景大小
|
||
var panel_size = text_size + bubble_padding * 2
|
||
background.custom_minimum_size = panel_size
|
||
background.size = panel_size
|
||
|
||
# 设置标签位置(居中)
|
||
label.position = bubble_padding
|
||
|
||
# 设置整体大小
|
||
custom_minimum_size = panel_size
|
||
size = panel_size
|
||
|
||
# 显示气泡
|
||
show()
|
||
modulate = Color(1, 1, 1, 1)
|
||
|
||
# 启动计时器
|
||
timer.start(duration)
|
||
|
||
# 淡入动画
|
||
var tween = create_tween()
|
||
tween.tween_property(self, "modulate:a", 1.0, 0.2)
|
||
|
||
## 隐藏气泡
|
||
func hide_bubble() -> void:
|
||
"""隐藏对话气泡(带淡出动画)"""
|
||
var tween = create_tween()
|
||
tween.tween_property(self, "modulate:a", 0.0, 0.3)
|
||
tween.finished.connect(func(): hide())
|
||
|
||
## 计时器超时
|
||
func _on_timer_timeout():
|
||
"""计时器超时,隐藏气泡"""
|
||
hide_bubble()
|
||
|
||
## 设置气泡位置(相对于角色)
|
||
func set_bubble_position(character_position: Vector2, offset: Vector2 = Vector2(0, -40)):
|
||
"""
|
||
设置气泡位置
|
||
@param character_position: 角色位置
|
||
@param offset: 偏移量(默认在角色上方)
|
||
"""
|
||
global_position = character_position + offset - size / 2
|