优化项目架构

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,76 @@
extends Node
# 全局通用功能脚本
# 使用方法:首先在项目设置的自动加载中添加此脚本,然后在任何地方使用 GlobalFunctions.函数名() 调用
func _ready():
print("全局函数库已加载")
# 写入 TXT 文件
func write_txt_file(file_path: String, text: String, append: bool = false) -> void:
var file
if append == true:
file = FileAccess.open(file_path, FileAccess.READ_WRITE) # 追加模式
if file:
file.seek_end() # 移动光标到文件末尾
else:
file = FileAccess.open(file_path, FileAccess.WRITE) # 覆盖模式
if file:
file.store_string(text)
file.close()
if has_node("/root/ToastScript"):
get_node("/root/ToastScript").show("游戏已保存!", Color.GREEN, 5.0, 1.0)
else:
print("写入文件时打开失败: ", file_path)
if has_node("/root/ToastScript"):
get_node("/root/ToastScript").show("写入文件时打开失败!", Color.RED, 5.0, 1.0)
# 读取 TXT 文件
func read_txt_file(file_path: String) -> String:
var file = FileAccess.open(file_path, FileAccess.READ)
if file:
var text = file.get_as_text()
file.close()
return text
else:
print("打开文件失败: ", file_path)
return "false"
#生成随机数-用于作物随机死亡
func random_probability(probability: float) -> bool:
# 确保传入的概率值在 0 到 1 之间
if probability*0.001 < 0.0 or probability*0.001 > 1.0:
print("概率值必须在 0 和 1 之间")
return false
# 生成一个 0 到 1 之间的随机数
var random_value = randf()
# 如果随机数小于等于概率值,则返回 true
return random_value <= (probability*0.001)
# 格式化时间为可读字符串
func format_time(seconds: int) -> String:
var minutes = seconds / 60
seconds = seconds % 60
var hours = minutes / 60
minutes = minutes % 60
if hours > 0:
return "%02d:%02d:%02d" % [hours, minutes, seconds]
else:
return "%02d:%02d" % [minutes, seconds]
#双击切换UI事件-比如按一下打开再按一下关闭
func double_click_close(node):
if node.visible == false:
node.show()
pass
else :
node.hide()
pass
pass

View File

@@ -0,0 +1 @@
uid://bv4lf4v2c73pb

View File

@@ -0,0 +1,17 @@
extends Node
const client_version :String = "2.2.0" #记录客户端版本
var isZoomDisabled :bool = false
const server_configs = [
{"host": "127.0.0.1", "port": 7070, "name": "本地"},
#{"host": "192.168.31.233", "port": 6060, "name": "家里面局域网"},
#{"host": "192.168.31.205", "port": 6060, "name": "家里面电脑"},
#{"host": "192.168.1.110", "port": 4040, "name": "萌芽局域网"},
#{"host": "47.108.90.0", "port": 4040, "name": "成都内网穿透"}#成都内网穿透
#{"host": "47.108.90.0", "port": 6060, "name": "成都公网"}#成都服务器
]
const DisableWeatherDisplay :bool = false #是否禁止显示天气
const BackgroundMusicVolume = 1.0 #背景音乐音量

View File

@@ -0,0 +1 @@
uid://co5rk48low4kq

View File

@@ -0,0 +1,239 @@
extends Node
## 资源加载调试器
## 用于诊断和监控资源加载问题
class_name ResourceLoadingDebugger
# 调试信息收集
var loading_stats: Dictionary = {}
var failed_resources: Array = []
var performance_metrics: Dictionary = {}
## 初始化调试器
func _ready():
print("[ResourceLoadingDebugger] 资源加载调试器已启动")
_init_performance_monitoring()
## 初始化性能监控
func _init_performance_monitoring():
performance_metrics = {
"total_load_time": 0.0,
"average_load_time": 0.0,
"peak_memory_usage": 0,
"current_memory_usage": 0,
"successful_loads": 0,
"failed_loads": 0
}
## 记录资源加载开始
func start_loading_resource(resource_path: String) -> int:
var start_time = Time.get_ticks_msec()
var load_id = randi()
loading_stats[load_id] = {
"path": resource_path,
"start_time": start_time,
"status": "loading"
}
return load_id
## 记录资源加载完成
func finish_loading_resource(load_id: int, success: bool, resource: Resource = null):
if not loading_stats.has(load_id):
return
var end_time = Time.get_ticks_msec()
var load_info = loading_stats[load_id]
var load_time = end_time - load_info["start_time"]
load_info["end_time"] = end_time
load_info["load_time"] = load_time
load_info["success"] = success
load_info["status"] = "completed"
# 更新性能指标
performance_metrics["total_load_time"] += load_time
if success:
performance_metrics["successful_loads"] += 1
if resource:
load_info["resource_size"] = _get_resource_memory_size(resource)
else:
performance_metrics["failed_loads"] += 1
failed_resources.append(load_info["path"])
# 计算平均加载时间
var total_loads = performance_metrics["successful_loads"] + performance_metrics["failed_loads"]
if total_loads > 0:
performance_metrics["average_load_time"] = performance_metrics["total_load_time"] / total_loads
# 更新内存使用情况
_update_memory_usage()
## 获取资源内存大小估算
func _get_resource_memory_size(resource: Resource) -> int:
if resource is Texture2D:
var texture = resource as Texture2D
var size = texture.get_size()
# 估算RGBA * 宽 * 高 * 4字节
return size.x * size.y * 4
return 0
## 更新内存使用情况
func _update_memory_usage():
var current_memory = OS.get_static_memory_usage()
performance_metrics["current_memory_usage"] = current_memory
if current_memory > performance_metrics["peak_memory_usage"]:
performance_metrics["peak_memory_usage"] = current_memory
## 检测设备资源加载能力
func detect_device_capabilities() -> Dictionary:
var capabilities = {}
# 设备基本信息
capabilities["platform"] = OS.get_name()
capabilities["processor_count"] = OS.get_processor_count()
capabilities["memory_total"] = OS.get_static_memory_usage()
# 图形信息
var rendering_device = RenderingServer.get_rendering_device()
if rendering_device:
capabilities["gpu_name"] = rendering_device.get_device_name()
capabilities["gpu_vendor"] = rendering_device.get_device_vendor_name()
# 存储信息
capabilities["user_data_dir"] = OS.get_user_data_dir()
# 性能测试
capabilities["texture_loading_speed"] = _benchmark_texture_loading()
return capabilities
## 基准测试纹理加载速度
func _benchmark_texture_loading() -> float:
var test_path = "res://assets/作物/默认/0.webp"
if not ResourceLoader.exists(test_path):
return -1.0
var start_time = Time.get_ticks_msec()
var iterations = 10
for i in range(iterations):
var texture = ResourceLoader.load(test_path)
if not texture:
return -1.0
var end_time = Time.get_ticks_msec()
return float(end_time - start_time) / iterations
## 诊断资源加载问题
func diagnose_loading_issues() -> Dictionary:
var diagnosis = {
"issues_found": [],
"recommendations": [],
"severity": "normal"
}
# 检查失败率
var total_loads = performance_metrics["successful_loads"] + performance_metrics["failed_loads"]
if total_loads > 0:
var failure_rate = float(performance_metrics["failed_loads"]) / total_loads
if failure_rate > 0.1: # 失败率超过10%
diagnosis["issues_found"].append("资源加载失败率过高: %.1f%%" % (failure_rate * 100))
diagnosis["recommendations"].append("检查资源文件完整性和路径正确性")
diagnosis["severity"] = "warning"
if failure_rate > 0.3: # 失败率超过30%
diagnosis["severity"] = "critical"
diagnosis["recommendations"].append("考虑降低资源质量或减少同时加载的资源数量")
# 检查加载速度
if performance_metrics["average_load_time"] > 100: # 平均加载时间超过100ms
diagnosis["issues_found"].append("资源加载速度较慢: %.1fms" % performance_metrics["average_load_time"])
diagnosis["recommendations"].append("考虑使用多线程加载或预加载常用资源")
if diagnosis["severity"] == "normal":
diagnosis["severity"] = "warning"
# 检查内存使用
var memory_mb = performance_metrics["peak_memory_usage"] / (1024 * 1024)
if memory_mb > 500: # 峰值内存使用超过500MB
diagnosis["issues_found"].append("内存使用过高: %.1fMB" % memory_mb)
diagnosis["recommendations"].append("实施LRU缓存清理或降低缓存大小")
if diagnosis["severity"] == "normal":
diagnosis["severity"] = "warning"
# 检查平台特定问题
var platform = OS.get_name()
if platform in ["Android", "iOS"]:
if performance_metrics["failed_loads"] > 5:
diagnosis["issues_found"].append("移动设备上资源加载失败较多")
diagnosis["recommendations"].append("移动设备内存有限,建议降低资源质量或实施更积极的缓存清理")
return diagnosis
## 生成资源加载报告
func generate_loading_report() -> String:
var report = "=== 资源加载调试报告 ===\n\n"
# 基本统计
report += "基本统计:\n"
report += " 成功加载: %d\n" % performance_metrics["successful_loads"]
report += " 失败加载: %d\n" % performance_metrics["failed_loads"]
report += " 平均加载时间: %.1fms\n" % performance_metrics["average_load_time"]
report += " 总加载时间: %.1fs\n" % (performance_metrics["total_load_time"] / 1000.0)
report += " 峰值内存使用: %.1fMB\n\n" % (performance_metrics["peak_memory_usage"] / (1024 * 1024))
# 设备信息
var capabilities = detect_device_capabilities()
report += "设备信息:\n"
report += " 平台: %s\n" % capabilities.get("platform", "未知")
report += " CPU核心数: %d\n" % capabilities.get("processor_count", 0)
report += " 纹理加载速度: %.1fms\n\n" % capabilities.get("texture_loading_speed", -1)
# 失败的资源
if failed_resources.size() > 0:
report += "加载失败的资源:\n"
for i in range(min(10, failed_resources.size())): # 只显示前10个
report += " - %s\n" % failed_resources[i]
if failed_resources.size() > 10:
report += " ... 还有 %d 个失败的资源\n" % (failed_resources.size() - 10)
report += "\n"
# 诊断结果
var diagnosis = diagnose_loading_issues()
report += "诊断结果 [%s]:\n" % diagnosis["severity"].to_upper()
for issue in diagnosis["issues_found"]:
report += " 问题: %s\n" % issue
for recommendation in diagnosis["recommendations"]:
report += " 建议: %s\n" % recommendation
return report
## 清理调试数据
func clear_debug_data():
loading_stats.clear()
failed_resources.clear()
_init_performance_monitoring()
print("[ResourceLoadingDebugger] 调试数据已清理")
## 导出调试数据到文件
func export_debug_data_to_file():
var report = generate_loading_report()
var datetime = Time.get_datetime_dict_from_system()
var filename = "resource_loading_debug_%04d%02d%02d_%02d%02d%02d.txt" % [
datetime.year, datetime.month, datetime.day,
datetime.hour, datetime.minute, datetime.second
]
var file_path = OS.get_user_data_dir() + "/" + filename
var file = FileAccess.open(file_path, FileAccess.WRITE)
if file:
file.store_string(report)
file.close()
print("[ResourceLoadingDebugger] 调试报告已导出到: ", file_path)
return file_path
else:
print("[ResourceLoadingDebugger] 导出调试报告失败")
return ""

View File

@@ -0,0 +1 @@
uid://dk6uoldjqtc0p

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)

View File

@@ -0,0 +1 @@
uid://336lik63ehtt