优化项目架构

This commit is contained in:
2025-09-15 19:10:37 +08:00
parent 4119ed3445
commit 26b856d74e
1361 changed files with 4 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
# Toast.gd - 合并的Toast系统
extends Node
# Toast节点缓存
var toast_container: Control
func _ready():
# 延迟创建Toast容器避免在节点初始化期间添加子节点的冲突
setup_toast_container.call_deferred()
func setup_toast_container():
# 防止重复创建
if toast_container and is_instance_valid(toast_container):
return
# 创建一个CanvasLayer来确保Toast始终在最顶层
var canvas_layer = CanvasLayer.new()
canvas_layer.name = "ToastCanvasLayer"
canvas_layer.layer = 100 # 设置一个很高的层级值
# 创建一个容器来放置所有Toast
toast_container = Control.new()
toast_container.name = "ToastContainer"
toast_container.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
toast_container.mouse_filter = Control.MOUSE_FILTER_IGNORE
# 将容器添加到CanvasLayer中
canvas_layer.add_child(toast_container)
# 尝试添加到main/UI节点如果失败则添加到根节点
var ui_node = get_node_or_null("/root/main/UI")
if ui_node:
ui_node.add_child.call_deferred(canvas_layer)
print("Toast容器已添加到 main/UI 节点")
else:
# 如果没有UI节点直接添加到根节点
get_tree().root.add_child.call_deferred(canvas_layer)
print("Toast容器已添加到根节点")
func show(text: String,
color: Color = Color.WHITE,
duration: float = 2.0,
fade_duration: float = 0.5) -> void:
# 确保容器存在且有效
if not toast_container or not is_instance_valid(toast_container) or not toast_container.get_parent():
setup_toast_container.call_deferred()
# 等待容器设置完成
await get_tree().process_frame
await get_tree().process_frame # 额外等待一帧确保完成
# 再次检查容器是否有效
if not toast_container or not is_instance_valid(toast_container):
print("警告Toast容器初始化失败无法显示Toast")
return
# 创建Toast UI
var toast_panel = create_toast_ui(text, color)
toast_container.add_child(toast_panel)
# 显示动画和自动消失
show_toast_animation(toast_panel, duration, fade_duration)
func create_toast_ui(text: String, color: Color) -> PanelContainer:
# 创建主容器
var panel = PanelContainer.new()
panel.name = "Toast_" + str(Time.get_ticks_msec())
# 设置样式
var style_box = StyleBoxFlat.new()
style_box.bg_color = Color(0, 0, 0, 0.8) # 半透明黑色背景
style_box.corner_radius_top_left = 8
style_box.corner_radius_top_right = 8
style_box.corner_radius_bottom_left = 8
style_box.corner_radius_bottom_right = 8
style_box.content_margin_top = 12
style_box.content_margin_bottom = 12
style_box.content_margin_left = 16
style_box.content_margin_right = 16
panel.add_theme_stylebox_override("panel", style_box)
# 创建文本标签
var label = Label.new()
label.text = text
label.modulate = color
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
# 设置字体大小
label.add_theme_font_size_override("font_size", 16)
panel.add_child(label)
# 定位Toast屏幕中央偏下
position_toast(panel)
return panel
func position_toast(toast_panel: PanelContainer):
# 设置位置为屏幕中央偏下
toast_panel.set_anchors_and_offsets_preset(Control.PRESET_CENTER)
toast_panel.position.y += 100 # 向下偏移
# 调整现有Toast的位置避免重叠
var existing_toasts = []
for child in toast_container.get_children():
if child != toast_panel and child is PanelContainer:
existing_toasts.append(child)
# 向上堆叠
for i in range(existing_toasts.size()):
var existing_toast = existing_toasts[existing_toasts.size() - 1 - i]
var tween = create_tween()
tween.tween_property(existing_toast, "position:y",
existing_toast.position.y - 60, 0.3)
func show_toast_animation(toast_panel: PanelContainer, duration: float, fade_duration: float):
# 初始状态:完全透明并稍微向上
toast_panel.modulate.a = 0.0
toast_panel.position.y += 20
# 淡入动画
var fade_in_tween = create_tween()
fade_in_tween.parallel().tween_property(toast_panel, "modulate:a", 1.0, 0.3)
fade_in_tween.parallel().tween_property(toast_panel, "position:y",
toast_panel.position.y - 20, 0.3)
fade_in_tween.set_ease(Tween.EASE_OUT)
# 等待显示时间
await get_tree().create_timer(duration).timeout
# 淡出动画
var fade_out_tween = create_tween()
fade_out_tween.tween_property(toast_panel, "modulate:a", 0.0, fade_duration)
await fade_out_tween.finished
# 移除节点
toast_panel.queue_free()
# 便捷方法
func show_success(text: String, duration: float = 2.0):
show(text, Color.GREEN, duration)
func show_error(text: String, duration: float = 3.0):
show(text, Color.RED, duration)
func show_warning(text: String, duration: float = 2.5):
show(text, Color.YELLOW, duration)
func show_info(text: String, duration: float = 2.0):
show(text, Color.CYAN, duration)