# Godot 项目命名规范 本文档定义了 whaleTown 项目的命名规范,以保持代码的一致性和可读性。 ## 目录 - [场景文件](#场景文件) - [脚本文件](#脚本文件) - [节点命名](#节点命名) - [变量命名](#变量命名) - [函数命名](#函数命名) - [常量命名](#常量命名) - [资源文件](#资源文件) - [目录结构](#目录结构) --- ## 场景文件 **规则**:下划线分隔 + `_scene` 或 `_prefab` 后缀 ### 场景类型 - **主场景**:`_scene` 后缀,表示完整的游戏场景 - **预制体**:`_prefab` 后缀,表示可复用的场景组件 ### 示例 ``` ✅ 正确 main_scene.tscn # 主场景 battle_scene.tscn # 战斗场景 menu_scene.tscn # 菜单场景 player_prefab.tscn # 玩家预制体 enemy_boss_prefab.tscn # Boss 敌人预制体 ui_dialog_prefab.tscn # 对话框预制体 ❌ 错误 MainScene.tscn # 不使用大驼峰 main.tscn # 缺少 _scene 后缀 player.tscn # 预制体缺少 _prefab 后缀 ``` ### 命名建议 - 场景名称应清晰表达场景用途 - 多个单词使用下划线分隔 - 避免使用缩写,除非是通用缩写(如 ui、hp) --- ## 脚本文件 **规则**:大驼峰命名(PascalCase),`.gd` 扩展名 ### 脚本类型 - **控制器脚本**:`Controller` 后缀 - **管理器脚本**:`Manager` 后缀 - **UI 脚本**:`UI_` 前缀 - **数据类**:`Data` 后缀 - **工具类**:`Utils` 或 `Helper` 后缀 ### 示例 ``` ✅ 正确 PlayerController.gd # 玩家控制器 EnemyAI.gd # 敌人 AI GameManager.gd # 游戏管理器 AudioManager.gd # 音频管理器 UI_MainMenu.gd # 主菜单 UI UI_HealthBar.gd # 血条 UI PlayerData.gd # 玩家数据类 SaveData.gd # 存档数据类 MathUtils.gd # 数学工具类 StringHelper.gd # 字符串辅助类 ❌ 错误 player_controller.gd # 不使用下划线 playerController.gd # 不使用小驼峰 player.gd # 缺少明确的类型后缀 PLAYER.gd # 不使用全大写 ``` ### 命名建议 - 脚本名称应与类名一致 - 一个脚本文件只包含一个主要类 - 使用清晰的后缀表明脚本用途 --- ## 节点命名 **规则**:小驼峰命名(camelCase) ### 节点类型 - **UI 节点**:描述性名称,如 `startButton`、`healthBar` - **游戏对象**:对象名称,如 `player`、`enemy` - **容器节点**:用途 + Container,如 `itemContainer` - **特效节点**:效果 + Effect,如 `explosionEffect` ### 示例 ``` ✅ 正确 player # 玩家节点 enemy # 敌人节点 mainCamera # 主相机 playerHpBar # 玩家血条 startButton # 开始按钮 pauseMenu # 暂停菜单 itemContainer # 物品容器 backgroundMusic # 背景音乐 explosionEffect # 爆炸特效 collisionShape # 碰撞形状 ❌ 错误 Player # 不使用大驼峰 player_hp_bar # 不使用下划线 StartButton # 不使用大驼峰 PLAYER # 不使用全大写 btn_start # 避免缩写 ``` ### 命名建议 - 节点名称应简洁明了 - 同类型节点可以添加数字后缀,如 `enemy1`、`enemy2` - 避免使用无意义的名称,如 `Node2D`、`Control` --- ## 变量命名 **规则**:小驼峰命名(camelCase),可选类型前缀 ### 变量类型前缀(可选) 使用类型前缀可以提升代码可读性,但不是强制要求。 | 类型 | 前缀 | 示例 | |------|------|------| | 整数 | `i` | `iHealth`, `iScore` | | 浮点数 | `f` | `fSpeed`, `fDamage` | | 字符串 | `s` | `sPlayerName`, `sDialogText` | | 布尔值 | `b` 或 `is/has` | `bIsAlive`, `isJumping`, `hasKey` | | 数组 | `a` 或复数 | `aEnemies`, `enemies` | | 字典 | `d` | `dPlayerStats` | | 节点引用 | 无前缀 | `playerNode`, `healthBar` | ### 示例 ```gdscript ✅ 正确(带前缀) var iHealth: int = 100 var fSpeed: float = 5.0 var sPlayerName: String = "Player" var bIsAlive: bool = true var aEnemies: Array = [] var dInventory: Dictionary = {} ✅ 正确(不带前缀) var health: int = 100 var speed: float = 5.0 var playerName: String = "Player" var isAlive: bool = true var enemies: Array = [] var inventory: Dictionary = {} ✅ 正确(布尔值使用 is/has) var isJumping: bool = false var hasWeapon: bool = true var canMove: bool = true ❌ 错误 var Health: int = 100 # 不使用大驼峰 var player_name: String = "" # 不使用下划线 var SPEED: float = 5.0 # 常量才使用全大写 var i: int = 0 # 循环变量除外,其他避免单字母 ``` ### 成员变量 ```gdscript # 导出变量(Inspector 可见) @export var maxHealth: int = 100 @export var moveSpeed: float = 200.0 @export var playerName: String = "Player" # 私有变量(以下划线开头) var _currentHealth: int var _isInitialized: bool = false # 节点引用 @onready var healthBar: ProgressBar = $HealthBar @onready var animationPlayer: AnimationPlayer = $AnimationPlayer ``` ### 命名建议 - 变量名应具有描述性 - 布尔变量使用 `is`、`has`、`can` 等前缀 - 私有变量以下划线 `_` 开头 - 避免使用单字母变量名(循环变量 `i`、`j` 除外) --- ## 函数命名 **规则**:小驼峰命名(camelCase),动词开头 ### 函数类型 - **获取函数**:`get` 前缀 - **设置函数**:`set` 前缀 - **判断函数**:`is`、`has`、`can` 前缀,返回布尔值 - **事件处理**:`on` 或 `_on` 前缀 - **初始化函数**:`init` 或 `initialize` - **更新函数**:`update` 前缀 - **私有函数**:`_` 前缀 ### 示例 ```gdscript ✅ 正确 func getPlayerPosition() -> Vector2: return position func setHealth(value: int) -> void: health = value func isAlive() -> bool: return health > 0 func hasItem(itemName: String) -> bool: return inventory.has(itemName) func canJump() -> bool: return isOnFloor and not isJumping func onButtonPressed() -> void: print("Button pressed") func _onTimerTimeout() -> void: # 信号处理函数 pass func initializePlayer() -> void: health = maxHealth position = startPosition func updateMovement(delta: float) -> void: position += velocity * delta func _calculateDamage(baseDamage: int) -> int: # 私有函数 return baseDamage * damageMultiplier ❌ 错误 func GetPlayerPosition(): # 不使用大驼峰 func get_player_position(): # 不使用下划线 func PlayerPosition(): # 缺少动词 func JUMP(): # 不使用全大写 ``` ### 内置函数重写 ```gdscript # Godot 内置函数使用下划线命名(保持原样) func _ready() -> void: pass func _process(delta: float) -> void: pass func _physics_process(delta: float) -> void: pass func _input(event: InputEvent) -> void: pass ``` ### 命名建议 - 函数名应清晰表达功能 - 使用动词开头,如 `get`、`set`、`update`、`calculate` - 参数名称也使用小驼峰命名 - 私有函数以下划线开头 --- ## 常量命名 **规则**:全大写 + 下划线分隔 ### 示例 ```gdscript ✅ 正确 const MAX_HEALTH: int = 100 const DEFAULT_SPEED: float = 200.0 const PLAYER_NAME: String = "Player" const GRAVITY: float = 980.0 const JUMP_FORCE: float = -400.0 const MAX_ENEMIES: int = 10 const SAVE_FILE_PATH: String = "user://save.dat" const SCREEN_WIDTH: int = 1920 const SCREEN_HEIGHT: int = 1080 ❌ 错误 const maxHealth: int = 100 # 不使用小驼峰 const MaxHealth: int = 100 # 不使用大驼峰 const max_health: int = 100 # 不使用小写 ``` ### 枚举命名 ```gdscript # 枚举名使用大驼峰 enum PlayerState { IDLE, # 枚举值使用全大写 WALKING, RUNNING, JUMPING, ATTACKING } enum EnemyType { NORMAL, ELITE, BOSS } # 使用 var currentState: PlayerState = PlayerState.IDLE ``` ### 命名建议 - 常量名应清晰表达含义 - 使用全大写和下划线 - 枚举类型名使用大驼峰,枚举值使用全大写 --- ## 资源文件 **规则**:下划线分隔,小写字母 ### 图片资源 ``` ✅ 正确 bg_main_menu.png # 背景图 sprite_player_idle.png # 精灵图 icon_sword.png # 图标 ui_button_normal.png # UI 元素 tile_grass_01.png # 瓦片图 ❌ 错误 BgMainMenu.png # 不使用大驼峰 bg-main-menu.png # 不使用连字符 BACKGROUND.png # 不使用全大写 ``` ### 音频资源 ``` ✅ 正确 sound_jump.wav # 音效 sound_explosion.wav music_battle.ogg # 音乐 music_menu.ogg voice_npc_greeting.wav # 语音 ❌ 错误 Jump.wav sound-jump.wav SOUND_JUMP.wav ``` ### 其他资源 ``` ✅ 正确 font_main.ttf # 字体 shader_water.gdshader # 着色器 material_metal.tres # 材质 animation_walk.res # 动画 ❌ 错误 MainFont.ttf font-main.ttf FONT_MAIN.ttf ``` ### 资源命名建议 - 使用类型前缀,如 `bg_`、`sprite_`、`sound_`、`music_` - 多个单词使用下划线分隔 - 全部使用小写字母 - 同系列资源使用数字后缀,如 `tile_01.png`、`tile_02.png` ### 扩展资源类型 ``` ✅ 正确 # 材质资源 material_metal.tres # 金属材质 material_wood.tres # 木材材质 material_water.tres # 水材质 # 着色器资源 shader_water.gdshader # 水着色器 shader_fire.gdshader # 火焰着色器 shader_outline.gdshader # 轮廓着色器 # 特效资源 fx_explosion.png # 爆炸特效 fx_magic_circle.png # 魔法阵特效 fx_damage_numbers.png # 伤害数字特效 # 环境资源 obj_tree.png # 树木对象 obj_rock.png # 岩石对象 tile_grass_01.png # 草地瓦片 tile_stone_01.png # 石头瓦片 ❌ 错误 MetalMaterial.tres # 不使用大驼峰 material-wood.tres # 不使用连字符 SHADER_WATER.gdshader # 不使用全大写 ``` --- ## 目录结构 ### 目录命名 **规则**:小写字母 + 下划线分隔 ``` ✅ 正确 scenes/ # 场景目录 scripts/ # 脚本目录 assets/ # 资源目录 sprites/ # 精灵图 sounds/ # 音效 music/ # 音乐 fonts/ # 字体 materials/ # 材质 shaders/ # 着色器 data/ # 数据目录 levels/ # 关卡数据 configs/ # 配置文件 dialogues/ # 对话数据 localization/ # 本地化数据 core/ # 核心系统目录 managers/ # 管理器 systems/ # 系统组件 utils/ # 工具类 components/ # 通用组件 interfaces/ # 接口定义 module/ # 模块目录 UI/ # UI模块 Character/ # 角色模块 Inventory/ # 背包模块 Combat/ # 战斗模块 Dialogue/ # 对话模块 addons/ # 插件目录 tests/ # 测试目录 unit/ # 单元测试 integration/ # 集成测试 ui/ # UI测试 performance/ # 性能测试 docs/ # 文档目录 auth/ # 认证相关文档 ❌ 错误 Scenes/ # 不使用大写 Scripts/ Assets/ ``` ### 推荐的项目结构 ``` whaleTown/ ├── scenes/ │ ├── main_scene.tscn │ ├── battle_scene.tscn │ └── prefabs/ │ ├── player_prefab.tscn │ └── enemy_prefab.tscn ├── scripts/ │ ├── PlayerController.gd │ ├── EnemyAI.gd │ ├── GameManager.gd │ └── ui/ │ ├── UI_MainMenu.gd │ └── UI_HealthBar.gd ├── assets/ │ ├── sprites/ │ │ ├── sprite_player_idle.png │ │ └── sprite_enemy_walk.png │ ├── sounds/ │ │ ├── sound_jump.wav │ │ └── sound_attack.wav │ ├── music/ │ │ └── music_battle.ogg │ └── fonts/ │ └── font_main.ttf ├── data/ │ ├── levels/ │ │ └── level_01.json │ └── configs/ │ └── game_config.json └── addons/ └── plugin_name/ ``` --- ## 完整示例 ### 场景文件:`player_prefab.tscn` ``` [节点树] player # 根节点(小驼峰) ├── sprite # 精灵节点 ├── collisionShape # 碰撞形状 ├── animationPlayer # 动画播放器 └── healthBar # 血条 ``` ### 脚本文件:`PlayerController.gd` ```gdscript extends CharacterBody2D # 常量(全大写 + 下划线) const MAX_HEALTH: int = 100 const DEFAULT_SPEED: float = 200.0 const JUMP_FORCE: float = -400.0 # 导出变量(小驼峰) @export var moveSpeed: float = DEFAULT_SPEED @export var maxHealth: int = MAX_HEALTH # 成员变量(小驼峰,可选类型前缀) var currentHealth: int var isJumping: bool = false var hasDoubleJump: bool = false # 私有变量(下划线前缀) var _velocity: Vector2 = Vector2.ZERO var _isInitialized: bool = false # 节点引用 @onready var sprite: Sprite2D = $sprite @onready var animationPlayer: AnimationPlayer = $animationPlayer @onready var healthBar: ProgressBar = $healthBar # 内置函数 func _ready() -> void: initializePlayer() func _physics_process(delta: float) -> void: updateMovement(delta) updateAnimation() # 公共函数(小驼峰,动词开头) func initializePlayer() -> void: currentHealth = maxHealth updateHealthBar() _isInitialized = true func takeDamage(damage: int) -> void: currentHealth -= damage if currentHealth <= 0: die() updateHealthBar() func heal(amount: int) -> void: currentHealth = min(currentHealth + amount, maxHealth) updateHealthBar() func isAlive() -> bool: return currentHealth > 0 func canJump() -> bool: return is_on_floor() or hasDoubleJump # 私有函数(下划线前缀) func _calculateDamage(baseDamage: int) -> int: return baseDamage * 2 func updateMovement(delta: float) -> void: # 移动逻辑 pass func updateAnimation() -> void: # 动画逻辑 pass func updateHealthBar() -> void: if healthBar: healthBar.value = float(currentHealth) / float(maxHealth) * 100.0 func die() -> void: print("Player died") queue_free() # 信号处理(_on 前缀) func _onAreaEntered(area: Area2D) -> void: print("Area entered: ", area.name) ``` --- ## 总结 遵循统一的命名规范可以: - ✅ 提高代码可读性 - ✅ 便于团队协作 - ✅ 减少命名冲突 - ✅ 方便代码维护 - ✅ 提升开发效率 记住核心原则: 1. **场景文件**:`下划线_scene/prefab` 2. **脚本文件**:`PascalCase.gd` 3. **节点名称**:`camelCase` 4. **变量/函数**:`camelCase` 5. **常量**:`UPPER_CASE` 6. **资源文件**:`lower_case` 保持一致,代码更清晰!