# 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`

保持一致，代码更清晰！
