Files
whale-town/scripts/ChatBubble.gd
2025-12-05 19:00:14 +08:00

110 lines
2.7 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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