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

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()