211 lines
5.8 KiB
GDScript
211 lines
5.8 KiB
GDScript
extends Node
|
|
## 通用工具类
|
|
## 提供项目中常用的工具函数和常量
|
|
|
|
# 常用常量
|
|
const EPSILON = 0.0001 # 浮点数比较精度
|
|
const DEFAULT_TWEEN_DURATION = 0.3 # 默认动画时长
|
|
|
|
# 颜色常量
|
|
const COLORS = {
|
|
"online": Color(0.2, 1.0, 0.2, 0.8), # 在线状态 - 绿色
|
|
"offline": Color(0.5, 0.5, 0.5, 0.6), # 离线状态 - 灰色
|
|
"error": Color(1.0, 0.3, 0.3, 0.9), # 错误 - 红色
|
|
"warning": Color(1.0, 0.8, 0.2, 0.9), # 警告 - 黄色
|
|
"success": Color(0.2, 0.8, 0.2, 0.9), # 成功 - 绿色
|
|
"info": Color(0.3, 0.7, 1.0, 0.9) # 信息 - 蓝色
|
|
}
|
|
|
|
# 字体大小常量
|
|
const FONT_SIZES = {
|
|
"small": 12,
|
|
"normal": 16,
|
|
"large": 20,
|
|
"title": 24
|
|
}
|
|
|
|
## 深度比较两个值是否相等
|
|
static func deep_equals(a, b) -> bool:
|
|
"""
|
|
深度比较两个值是否相等,支持字典、数组和基本类型
|
|
@param a: 第一个值
|
|
@param b: 第二个值
|
|
@return: 是否相等
|
|
"""
|
|
if typeof(a) != typeof(b):
|
|
return false
|
|
|
|
match typeof(a):
|
|
TYPE_DICTIONARY:
|
|
return _compare_dictionaries(a, b)
|
|
TYPE_ARRAY:
|
|
return _compare_arrays(a, b)
|
|
TYPE_FLOAT:
|
|
return abs(a - b) < EPSILON
|
|
_:
|
|
return a == b
|
|
|
|
## 比较两个字典
|
|
static func _compare_dictionaries(dict_a: Dictionary, dict_b: Dictionary) -> bool:
|
|
"""比较两个字典是否相等"""
|
|
if dict_a.size() != dict_b.size():
|
|
return false
|
|
|
|
for key in dict_a:
|
|
if not dict_b.has(key):
|
|
return false
|
|
if not deep_equals(dict_a[key], dict_b[key]):
|
|
return false
|
|
|
|
return true
|
|
|
|
## 比较两个数组
|
|
static func _compare_arrays(array_a: Array, array_b: Array) -> bool:
|
|
"""比较两个数组是否相等"""
|
|
if array_a.size() != array_b.size():
|
|
return false
|
|
|
|
for i in range(array_a.size()):
|
|
if not deep_equals(array_a[i], array_b[i]):
|
|
return false
|
|
|
|
return true
|
|
|
|
## 生成唯一ID
|
|
static func generate_unique_id(prefix: String = "") -> String:
|
|
"""
|
|
生成唯一ID
|
|
@param prefix: ID前缀
|
|
@return: 唯一ID字符串
|
|
"""
|
|
var timestamp = Time.get_unix_time_from_system()
|
|
var random = randi()
|
|
return prefix + str(timestamp) + "_" + str(random)
|
|
|
|
## 验证字符串是否为空白
|
|
static func is_string_blank(text: String) -> bool:
|
|
"""
|
|
检查字符串是否为空或只包含空白字符
|
|
@param text: 要检查的字符串
|
|
@return: 是否为空白
|
|
"""
|
|
return text.strip_edges().is_empty()
|
|
|
|
## 限制数值在指定范围内
|
|
static func clamp_vector2(vector: Vector2, min_val: Vector2, max_val: Vector2) -> Vector2:
|
|
"""
|
|
限制Vector2的值在指定范围内
|
|
@param vector: 输入向量
|
|
@param min_val: 最小值
|
|
@param max_val: 最大值
|
|
@return: 限制后的向量
|
|
"""
|
|
return Vector2(
|
|
clamp(vector.x, min_val.x, max_val.x),
|
|
clamp(vector.y, min_val.y, max_val.y)
|
|
)
|
|
|
|
## 安全地获取字典值
|
|
static func safe_get(dict: Dictionary, key: String, default_value = null):
|
|
"""
|
|
安全地从字典获取值,如果键不存在则返回默认值
|
|
@param dict: 字典
|
|
@param key: 键
|
|
@param default_value: 默认值
|
|
@return: 值或默认值
|
|
"""
|
|
return dict.get(key, default_value)
|
|
|
|
## 创建带阴影的标签
|
|
static func create_label_with_shadow(text: String, font_size: int = FONT_SIZES.normal) -> Label:
|
|
"""
|
|
创建带阴影效果的标签
|
|
@param text: 标签文本
|
|
@param font_size: 字体大小
|
|
@return: 配置好的Label节点
|
|
"""
|
|
var label = Label.new()
|
|
label.text = text
|
|
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
label.add_theme_font_size_override("font_size", font_size)
|
|
label.add_theme_color_override("font_color", Color.WHITE)
|
|
label.add_theme_color_override("font_shadow_color", Color(0, 0, 0, 0.8))
|
|
label.add_theme_constant_override("shadow_offset_x", 1)
|
|
label.add_theme_constant_override("shadow_offset_y", 1)
|
|
return label
|
|
|
|
## 创建状态指示器
|
|
static func create_status_indicator(is_online: bool) -> ColorRect:
|
|
"""
|
|
创建状态指示器
|
|
@param is_online: 是否在线
|
|
@return: 配置好的ColorRect节点
|
|
"""
|
|
var indicator = ColorRect.new()
|
|
indicator.size = Vector2(8, 8)
|
|
indicator.color = COLORS.online if is_online else COLORS.offline
|
|
return indicator
|
|
|
|
## 格式化时间戳
|
|
static func format_timestamp(timestamp: float) -> String:
|
|
"""
|
|
格式化时间戳为可读字符串
|
|
@param timestamp: Unix时间戳
|
|
@return: 格式化的时间字符串
|
|
"""
|
|
var datetime = Time.get_datetime_dict_from_unix_time(int(timestamp))
|
|
return "%02d:%02d:%02d" % [datetime.hour, datetime.minute, datetime.second]
|
|
|
|
## 计算两点间距离(平方)
|
|
static func distance_squared(pos1: Vector2, pos2: Vector2) -> float:
|
|
"""
|
|
计算两点间距离的平方(避免开方运算,提高性能)
|
|
@param pos1: 第一个点
|
|
@param pos2: 第二个点
|
|
@return: 距离的平方
|
|
"""
|
|
var diff = pos2 - pos1
|
|
return diff.x * diff.x + diff.y * diff.y
|
|
|
|
## 线性插值Vector2
|
|
static func lerp_vector2(from: Vector2, to: Vector2, weight: float) -> Vector2:
|
|
"""
|
|
Vector2的线性插值
|
|
@param from: 起始向量
|
|
@param to: 目标向量
|
|
@param weight: 插值权重(0-1)
|
|
@return: 插值结果
|
|
"""
|
|
return Vector2(
|
|
lerp(from.x, to.x, weight),
|
|
lerp(from.y, to.y, weight)
|
|
)
|
|
|
|
## 验证网络消息格式
|
|
static func validate_network_message(message: Dictionary) -> bool:
|
|
"""
|
|
验证网络消息是否包含必需字段
|
|
@param message: 消息字典
|
|
@return: 是否有效
|
|
"""
|
|
return message.has("type") and message.has("data") and message.has("timestamp")
|
|
|
|
## 打印调试信息(带时间戳)
|
|
static func debug_print(message: String, category: String = "DEBUG") -> void:
|
|
"""
|
|
打印带时间戳的调试信息
|
|
@param message: 调试消息
|
|
@param category: 消息类别
|
|
"""
|
|
var timestamp = format_timestamp(Time.get_unix_time_from_system())
|
|
print("[", timestamp, "] [", category, "] ", message)
|
|
|
|
## 安全地释放节点
|
|
static func safe_free_node(node: Node) -> void:
|
|
"""
|
|
安全地释放节点,避免重复释放
|
|
@param node: 要释放的节点
|
|
"""
|
|
if node and is_instance_valid(node):
|
|
node.queue_free()
|