Files
whale-town-front/docs/naming_convention.md

593 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`
---
## 目录结构
### 目录命名
**规则**:小写字母 + 下划线分隔
```
✅ 正确
scenes/ # 场景目录
scripts/ # 脚本目录
assets/ # 资源目录
sprites/ # 精灵图
sounds/ # 音效
music/ # 音乐
fonts/ # 字体
data/ # 数据目录
levels/ # 关卡数据
configs/ # 配置文件
addons/ # 插件目录
tests/ # 测试目录
❌ 错误
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`
保持一致,代码更清晰!