chore:完善项目目录结构和基础框架

- 添加核心系统框架目录结构
- 创建游戏模块化组织架构
- 添加数据配置和本地化支持
- 建立脚本分类管理体系
- 创建场景预制件管理目录
This commit is contained in:
2025-12-24 20:38:57 +08:00
parent 15548ebb52
commit 73478c0500
39 changed files with 551 additions and 0 deletions

1
core/components/.gitkeep Normal file
View File

@@ -0,0 +1 @@
# 保持目录结构 - 组件脚本目录

1
core/input_box/.gitkeep Normal file
View File

@@ -0,0 +1 @@
# 保持目录结构 - 输入框组件目录

1
core/interfaces/.gitkeep Normal file
View File

@@ -0,0 +1 @@
# 保持目录结构 - 接口定义目录

View File

@@ -0,0 +1,50 @@
extends Node
# 游戏管理器 - 全局游戏状态管理
# 单例模式,管理游戏的整体状态和生命周期
signal game_state_changed(new_state: GameState)
enum GameState {
LOADING, # 加载中
AUTH, # 认证状态
MAIN_MENU, # 主菜单
IN_GAME, # 游戏中
PAUSED, # 暂停
SETTINGS # 设置
}
var current_state: GameState = GameState.LOADING
var previous_state: GameState = GameState.LOADING
var current_user: String = ""
var game_version: String = "1.0.0"
func _ready():
print("GameManager 初始化完成")
change_state(GameState.AUTH)
func change_state(new_state: GameState):
if current_state == new_state:
return
previous_state = current_state
current_state = new_state
print("游戏状态变更: ", GameState.keys()[previous_state], " -> ", GameState.keys()[current_state])
game_state_changed.emit(new_state)
func get_current_state() -> GameState:
return current_state
func get_previous_state() -> GameState:
return previous_state
func set_current_user(username: String):
current_user = username
print("当前用户设置为: ", username)
func get_current_user() -> String:
return current_user
func is_user_logged_in() -> bool:
return not current_user.is_empty()

View File

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

View File

@@ -0,0 +1,75 @@
extends Node
# 场景管理器 - 负责场景切换和管理
# 提供场景切换的统一接口
signal scene_changed(scene_name: String)
signal scene_change_started(scene_name: String)
var current_scene_name: String = ""
var is_changing_scene: bool = false
# 场景路径映射
var scene_paths: Dictionary = {
"main": "res://scenes/main_scene.tscn",
"auth": "res://scenes/auth_scene.tscn",
"game": "res://scenes/game_scene.tscn",
"battle": "res://scenes/battle_scene.tscn",
"inventory": "res://scenes/inventory_scene.tscn",
"shop": "res://scenes/shop_scene.tscn",
"settings": "res://scenes/settings_scene.tscn"
}
func _ready():
print("SceneManager 初始化完成")
func change_scene(scene_name: String, use_transition: bool = true):
if is_changing_scene:
print("场景切换中,忽略新的切换请求")
return false
if not scene_paths.has(scene_name):
print("错误: 未找到场景 ", scene_name)
return false
var scene_path = scene_paths[scene_name]
print("开始切换场景: ", current_scene_name, " -> ", scene_name)
is_changing_scene = true
scene_change_started.emit(scene_name)
if use_transition:
await show_transition()
var error = get_tree().change_scene_to_file(scene_path)
if error != OK:
print("场景切换失败: ", error)
is_changing_scene = false
return false
current_scene_name = scene_name
is_changing_scene = false
scene_changed.emit(scene_name)
if use_transition:
await hide_transition()
print("场景切换完成: ", scene_name)
return true
func get_current_scene_name() -> String:
return current_scene_name
func register_scene(scene_name: String, scene_path: String):
scene_paths[scene_name] = scene_path
print("注册场景: ", scene_name, " -> ", scene_path)
func show_transition():
# TODO: 实现场景切换过渡效果
print("显示场景切换过渡效果")
await get_tree().create_timer(0.2).timeout
func hide_transition():
# TODO: 隐藏场景切换过渡效果
print("隐藏场景切换过渡效果")
await get_tree().create_timer(0.2).timeout

View File

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

View File

@@ -0,0 +1,80 @@
extends Node
# 全局事件系统 - 提供解耦的事件通信机制
# 允许不同模块之间通过事件进行通信,避免直接依赖
# 事件监听器存储
var event_listeners: Dictionary = {}
func _ready():
print("EventSystem 初始化完成")
# 注册事件监听器
func connect_event(event_name: String, callback: Callable, target: Node = null):
if not event_listeners.has(event_name):
event_listeners[event_name] = []
var listener_info = {
"callback": callback,
"target": target
}
event_listeners[event_name].append(listener_info)
print("注册事件监听器: ", event_name, " -> ", callback)
# 移除事件监听器
func disconnect_event(event_name: String, callback: Callable, target: Node = null):
if not event_listeners.has(event_name):
return
var listeners = event_listeners[event_name]
for i in range(listeners.size() - 1, -1, -1):
var listener = listeners[i]
if listener.callback == callback and listener.target == target:
listeners.remove_at(i)
print("移除事件监听器: ", event_name, " -> ", callback)
break
# 发送事件
func emit_event(event_name: String, data: Variant = null):
print("发送事件: ", event_name, " 数据: ", data)
if not event_listeners.has(event_name):
return
var listeners = event_listeners[event_name]
for listener_info in listeners:
var target = listener_info.target
var callback = listener_info.callback
# 检查目标节点是否仍然有效
if target != null and not is_instance_valid(target):
continue
# 调用回调函数
if data != null:
callback.call(data)
else:
callback.call()
# 清理无效的监听器
func cleanup_invalid_listeners():
for event_name in event_listeners.keys():
var listeners = event_listeners[event_name]
for i in range(listeners.size() - 1, -1, -1):
var listener = listeners[i]
var target = listener.target
if target != null and not is_instance_valid(target):
listeners.remove_at(i)
print("清理无效监听器: ", event_name)
# 获取事件监听器数量
func get_listener_count(event_name: String) -> int:
if not event_listeners.has(event_name):
return 0
return event_listeners[event_name].size()
# 清空所有事件监听器
func clear_all_listeners():
event_listeners.clear()
print("清空所有事件监听器")

View File

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

105
core/utils/StringUtils.gd Normal file
View File

@@ -0,0 +1,105 @@
class_name StringUtils
# 字符串工具类 - 提供常用的字符串处理功能
# 验证邮箱格式
static func is_valid_email(email: String) -> bool:
var regex = RegEx.new()
regex.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")
return regex.search(email) != null
# 验证用户名格式(字母、数字、下划线)
static func is_valid_username(username: String) -> bool:
if username.is_empty() or username.length() > 50:
return false
var regex = RegEx.new()
regex.compile("^[a-zA-Z0-9_]+$")
return regex.search(username) != null
# 验证密码强度
static func validate_password_strength(password: String) -> Dictionary:
var result = {"valid": false, "message": "", "strength": 0}
if password.length() < 8:
result.message = "密码长度至少8位"
return result
if password.length() > 128:
result.message = "密码长度不能超过128位"
return result
var has_letter = false
var has_digit = false
var has_special = false
for i in range(password.length()):
var char = password[i]
if char >= 'a' and char <= 'z' or char >= 'A' and char <= 'Z':
has_letter = true
elif char >= '0' and char <= '9':
has_digit = true
elif char in "!@#$%^&*()_+-=[]{}|;:,.<>?":
has_special = true
var strength = 0
if has_letter:
strength += 1
if has_digit:
strength += 1
if has_special:
strength += 1
if password.length() >= 12:
strength += 1
result.strength = strength
if not (has_letter and has_digit):
result.message = "密码必须包含字母和数字"
return result
result.valid = true
result.message = "密码强度: " + ["", "", "", "很强"][min(strength - 1, 3)]
return result
# 截断字符串
static func truncate(text: String, max_length: int, suffix: String = "...") -> String:
if text.length() <= max_length:
return text
return text.substr(0, max_length - suffix.length()) + suffix
# 首字母大写
static func capitalize_first(text: String) -> String:
if text.is_empty():
return text
return text[0].to_upper() + text.substr(1)
# 转换为标题格式(每个单词首字母大写)
static func to_title_case(text: String) -> String:
var words = text.split(" ")
var result = []
for word in words:
if not word.is_empty():
result.append(capitalize_first(word.to_lower()))
return " ".join(result)
# 移除HTML标签
static func strip_html_tags(html: String) -> String:
var regex = RegEx.new()
regex.compile("<[^>]*>")
return regex.sub(html, "", true)
# 格式化文件大小
static func format_file_size(bytes: int) -> String:
var units = ["B", "KB", "MB", "GB", "TB"]
var size = float(bytes)
var unit_index = 0
while size >= 1024.0 and unit_index < units.size() - 1:
size /= 1024.0
unit_index += 1
if unit_index == 0:
return str(int(size)) + " " + units[unit_index]
else:
return "%.1f %s" % [size, units[unit_index]]

View File

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