Files
whale-town-front/docs/02-开发规范/代码注释规范.md
moyin 1ff677b3b2 docs: 重新组织文档结构,按开发阶段分类
新的目录结构:
  01-项目入门/     # 新人必读,项目基础
  02-开发规范/     # 编码标准和规范
  03-技术实现/     # 具体开发指导
  04-高级开发/     # 进阶开发技巧
  05-部署运维/     # 发布和部署
  06-功能模块/     # 特定功能文档

 新增导航文档:
- docs/README.md - 完整的文档导航和使用指南
- 各目录下的README.md - 分类说明和使用指导

 优化效果:
- 开发者可以按阶段快速定位需要的文档
- 新人有清晰的学习路径
- 不同角色有针对性的文档推荐
- 提供了问题导向的快速查找功能
2025-12-31 18:02:16 +08:00

433 lines
12 KiB
Markdown
Raw Permalink 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.
# GDScript 代码注释规范
本文档详细说明了 whaleTown 项目中 GDScript 代码的注释规范,旨在提高代码可读性和维护性。
## 目录
- [基本原则](#基本原则)
- [文件头注释](#文件头注释)
- [类和函数注释](#类和函数注释)
- [变量注释](#变量注释)
- [行内注释](#行内注释)
- [特殊注释标记](#特殊注释标记)
- [AI辅助注释指南](#ai辅助注释指南)
## 基本原则
### 注释的目的
- **解释为什么**,而不是解释做什么
- **提供上下文**,帮助理解代码意图
- **记录重要决策**和设计考虑
- **警告潜在问题**和注意事项
### 注释质量标准
- 简洁明了,避免冗余
- 使用中文,保持一致性
- 及时更新,与代码同步
- 避免显而易见的注释
## 文件头注释
每个 GDScript 文件都应该包含文件头注释,说明文件的用途和基本信息。
### 标准格式
```gdscript
# ============================================================================
# 文件名: PlayerController.gd
# 作用: 玩家角色控制器,处理玩家输入和移动逻辑
#
# 主要功能:
# - 处理键盘和手柄输入
# - 控制角色移动和跳跃
# - 管理角色状态切换
# - 处理碰撞检测
#
# 依赖: MovementComponent, AnimationComponent
# 作者: [开发者名称]
# 创建时间: 2024-12-24
# ============================================================================
extends CharacterBody2D
```
### 管理器类文件头
```gdscript
# ============================================================================
# 游戏管理器 - GameManager.gd
#
# 全局单例管理器,负责游戏状态管理和生命周期控制
#
# 核心职责:
# - 游戏状态切换 (加载、认证、游戏中、暂停等)
# - 用户信息管理
# - 全局配置访问
# - 系统初始化和清理
#
# 使用方式:
# GameManager.change_state(GameManager.GameState.IN_GAME)
# GameManager.set_current_user("player123")
#
# 注意事项:
# - 作为自动加载单例,全局可访问
# - 状态变更会触发 game_state_changed 信号
# ============================================================================
extends Node
```
## 类和函数注释
### 类注释
```gdscript
# 玩家数据类
#
# 存储和管理玩家的基本属性和状态信息
# 支持数据序列化和反序列化,用于存档系统
class_name PlayerData
# 武器组件类
#
# 为角色提供武器功能,包括攻击、换弹、特殊技能等
# 可以挂载到任何具有攻击能力的角色上
#
# 使用示例:
# var weapon = WeaponComponent.new()
# weapon.setup_weapon("sword", 50)
# add_child(weapon)
class_name WeaponComponent
```
### 函数注释格式
```gdscript
# 处理玩家输入并更新移动状态
#
# 参数:
# delta: float - 帧时间间隔
#
# 返回值: 无
#
# 注意事项:
# - 需要在 _physics_process 中调用
# - 会自动处理重力和碰撞
func handle_movement(delta: float) -> void:
# 验证用户输入的邮箱格式
#
# 参数:
# email: String - 待验证的邮箱地址
#
# 返回值:
# Dictionary - 包含验证结果和错误信息
# {
# "valid": bool, # 是否有效
# "message": String # 错误信息(如果无效)
# }
#
# 使用示例:
# var result = validate_email("test@example.com")
# if result.valid:
# print("邮箱格式正确")
static func validate_email(email: String) -> Dictionary:
```
## 变量注释
### 成员变量注释
```gdscript
# 玩家基础属性
@export var max_health: int = 100 # 最大生命值
@export var move_speed: float = 200.0 # 移动速度 (像素/秒)
@export var jump_force: float = -400.0 # 跳跃力度 (负值向上)
# 状态管理
var current_health: int # 当前生命值
var is_grounded: bool = false # 是否在地面上
var can_double_jump: bool = true # 是否可以二段跳
# 节点引用 - 在 _ready() 中初始化
@onready var sprite: Sprite2D = $Sprite2D
@onready var collision: CollisionShape2D = $CollisionShape2D
@onready var animation_player: AnimationPlayer = $AnimationPlayer
# 私有变量 - 内部使用
var _velocity: Vector2 = Vector2.ZERO # 当前速度向量
var _last_direction: int = 1 # 最后面向方向 (1=右, -1=左)
```
### 常量注释
```gdscript
# 游戏配置常量
const GRAVITY: float = 980.0 # 重力加速度 (像素/秒²)
const MAX_FALL_SPEED: float = 1000.0 # 最大下落速度
const COYOTE_TIME: float = 0.1 # 土狼时间 (离开平台后仍可跳跃的时间)
# 输入动作名称
const ACTION_MOVE_LEFT: String = "move_left"
const ACTION_MOVE_RIGHT: String = "move_right"
const ACTION_JUMP: String = "jump"
# 动画名称常量
const ANIM_IDLE: String = "idle"
const ANIM_WALK: String = "walk"
const ANIM_JUMP: String = "jump"
const ANIM_FALL: String = "fall"
```
## 行内注释
### 复杂逻辑注释
```gdscript
func update_movement(delta: float):
# 处理水平移动输入
var input_direction = Input.get_axis("move_left", "move_right")
if input_direction != 0:
velocity.x = input_direction * move_speed
_last_direction = sign(input_direction) # 记录面向方向
else:
# 应用摩擦力,逐渐停止
velocity.x = move_toward(velocity.x, 0, friction * delta)
# 应用重力 (只在空中时)
if not is_on_floor():
velocity.y += gravity * delta
velocity.y = min(velocity.y, max_fall_speed) # 限制最大下落速度
# 处理跳跃输入
if Input.is_action_just_pressed("jump"):
if is_on_floor():
velocity.y = jump_force # 普通跳跃
elif can_double_jump:
velocity.y = jump_force * 0.8 # 二段跳 (力度稍小)
can_double_jump = false
# 重置二段跳能力
if is_on_floor() and not can_double_jump:
can_double_jump = true
```
### 临时解决方案注释
```gdscript
func handle_collision(body: Node2D):
# TODO: 重构碰撞处理逻辑,当前实现过于复杂
# FIXME: 在某些情况下会出现重复碰撞检测
# HACK: 临时解决方案,等待 Godot 4.6 修复相关 bug
if body.has_method("take_damage"):
# NOTE: 伤害计算需要考虑护甲和抗性
var damage = calculate_damage(base_damage)
body.take_damage(damage)
```
## 特殊注释标记
使用标准化的标记来标识不同类型的注释:
### 标记类型
```gdscript
# TODO: 待实现的功能
# TODO: 添加音效播放功能
# TODO: 实现存档系统
# FIXME: 需要修复的问题
# FIXME: 内存泄漏问题,需要及时释放资源
# FIXME: 在低帧率下移动不流畅
# HACK: 临时解决方案
# HACK: 绕过 Godot 引擎的已知 bug
# HACK: 临时方案,等待更好的实现
# NOTE: 重要说明
# NOTE: 此函数会修改全局状态,谨慎使用
# NOTE: 性能敏感代码,避免频繁调用
# WARNING: 警告信息
# WARNING: 不要在 _ready() 之前调用此函数
# WARNING: 此操作不可逆,请确认后执行
# OPTIMIZE: 性能优化点
# OPTIMIZE: 可以使用对象池优化内存分配
# OPTIMIZE: 考虑使用缓存提高查询效率
```
### 版本和兼容性标记
```gdscript
# @since 1.0.0 - 添加基础移动功能
# @deprecated 使用 new_movement_system() 替代
# @godot_version 4.5+ - 需要 Godot 4.5 或更高版本
# @platform_specific Windows/Linux - 仅在桌面平台可用
```
## AI辅助注释指南
### 为AI提供的注释模板
当需要AI帮助补充注释时请使用以下模板
```gdscript
# [AI_COMMENT_REQUEST]
# 请为以下函数添加详细注释,包括:
# - 功能描述
# - 参数说明
# - 返回值说明
# - 使用示例
# - 注意事项
func complex_function(param1: String, param2: int) -> Dictionary:
# 复杂的业务逻辑...
pass
```
### AI注释补充规则
1. **保持一致性** - 遵循项目现有的注释风格
2. **关注业务逻辑** - 重点解释业务含义,而非语法
3. **提供上下文** - 说明函数在整个系统中的作用
4. **标注复杂度** - 对复杂算法提供额外说明
### 示例AI补充前后对比
**补充前:**
```gdscript
func calculate_damage(base_damage: int, armor: int, resistance: float) -> int:
var final_damage = base_damage
final_damage -= armor
final_damage *= (1.0 - resistance)
return max(1, final_damage)
```
**AI补充后**
```gdscript
# 计算最终伤害值
#
# 根据基础伤害、护甲值和抗性计算实际造成的伤害
# 伤害计算公式: (基础伤害 - 护甲) × (1 - 抗性)
#
# 参数:
# base_damage: int - 基础伤害值
# armor: int - 目标护甲值 (减少固定伤害)
# resistance: float - 目标抗性 (0.0-1.0, 减少百分比伤害)
#
# 返回值:
# int - 最终伤害值 (最小为1确保至少造成1点伤害)
#
# 使用示例:
# var damage = calculate_damage(100, 20, 0.3) # 结果: 56
#
# 注意事项:
# - 护甲为负值时会增加伤害
# - 抗性超过1.0时可能导致负伤害但会被限制为1
func calculate_damage(base_damage: int, armor: int, resistance: float) -> int:
var final_damage = base_damage
final_damage -= armor # 减去护甲值
final_damage *= (1.0 - resistance) # 应用抗性
return max(1, final_damage) # 确保最小伤害为1
```
## 注释最佳实践
### 什么时候需要注释
**必须添加注释的情况:**
- 复杂的算法和业务逻辑
- 非显而易见的设计决策
- 临时解决方案和已知问题
- 公共API和接口函数
- 性能敏感的代码段
- 平台特定或版本特定的代码
**不需要注释的情况:**
- 显而易见的代码 (`var count = 0 # 计数器` ❌)
- 重复函数名的注释 (`func get_name() -> String: # 获取名称` ❌)
- 过时或错误的注释
### 注释维护原则
```gdscript
# ✅ 好的注释 - 解释为什么这样做
# 使用二分查找提高大数组的查询效率
# 当数组长度超过100时线性查找性能会显著下降
func binary_search(array: Array, target: Variant) -> int:
# ❌ 坏的注释 - 重复代码内容
# 遍历数组查找目标值
func linear_search(array: Array, target: Variant) -> int:
```
### 团队协作注释
```gdscript
# 多人协作时的注释规范
class_name NetworkManager
# @author: 张三 - 网络连接模块
# @author: 李四 - 数据同步模块
# @reviewer: 王五 - 代码审查
# @last_modified: 2024-12-24
# 网络连接状态枚举
#
# 定义了客户端与服务器的连接状态
# 状态转换: DISCONNECTED -> CONNECTING -> CONNECTED -> DISCONNECTED
enum ConnectionState {
DISCONNECTED, # 未连接
CONNECTING, # 连接中
CONNECTED, # 已连接
RECONNECTING # 重连中 - @added by 李四 2024-12-20
}
```
## 注释检查清单
在提交代码前,请检查以下项目:
### 文件级别检查
- [ ] 文件头注释完整(文件名、作用、主要功能)
- [ ] 依赖关系说明清楚
- [ ] 作者和创建时间已填写
### 函数级别检查
- [ ] 公共函数有完整的参数和返回值说明
- [ ] 复杂函数有使用示例
- [ ] 特殊情况和注意事项已标注
### 代码级别检查
- [ ] 复杂逻辑有行内注释说明
- [ ] 魔法数字有常量定义和注释
- [ ] TODO/FIXME 标记有明确的处理计划
### 质量检查
- [ ] 注释内容准确,与代码一致
- [ ] 中文表达清晰,无错别字
- [ ] 注释格式符合项目规范
## 注释工具和插件
### Godot编辑器设置
```
# 在 Godot 编辑器中设置注释快捷键
# 编辑器设置 -> 快捷键 -> 注释/取消注释: Ctrl+/
```
### 推荐的注释插件
- **GDScript Language Server** - 提供注释语法高亮
- **Code Formatter** - 自动格式化注释
- **Documentation Generator** - 自动生成API文档
---
## 总结
良好的注释是代码质量的重要组成部分。遵循本规范可以:
1. **提高代码可读性** - 帮助团队成员快速理解代码
2. **降低维护成本** - 减少后期修改和调试时间
3. **促进知识传承** - 保留设计思路和业务逻辑
4. **支持AI辅助开发** - 为AI提供更好的上下文信息
记住:**好的注释解释为什么,而不是做什么。**