Lua规范
一、基本功能语法
1、for循环
对于数组的循环,严格使用ipair;对于table的循环,严格使用pair
循环中变量的命名,使用小写+下划线格式,
for key_a, value_b in ipairs(t) do
-- body
end
2、函数
全局函数声明
function UtilsTipsWarning(content,...)
-- body
end
成员函数声明
成员函数声明使用冒号函数":",不允许使用点函数"."
function CUnityGameObject:LoadAsyn()
-- body
end
静态函数声明
静态函数声明使用点函数".",不允许使用冒号函数":",业务逻辑代码应当减少静态函数声明
function Application.OpenMask(transparent)
-- body
end
local函数声明
对于一些仅在当前lua文件中使用的函数,可以使用local函数声明,可以避免命名冲突导致函数覆盖等问题
local function _OpenMessageBox(message,options)
--body
end
3、类
类的声明
使用Core.declare_class(),第一个参数是基类,第二个参数是全局类名。
注意事项:全局类名字符串不允许重复
CPrompt = Core.declare_class({},"CPrompt")
类的构造函数与析构函数
构造函数名为ctor,析构函数为dtor,都是用冒号函数":"
function CPrompt:ctor(...)
-- body
end
function CPrompt:dtor()
-- body
end
类的成员函数
见第1节 成员函数声明
类的属性
function CPrompt:ctor(key)
self._key = key
end
类的实例化
使用点方法访问类的new()方法,可传入自定义参数,在类的构造方法ctor中可以接收到对应的参数
local _prompt = CPrompt.new("key")
类的继承
子类声明方式见 类的声明
子类与基类的构造函数调用顺序:基类ctor() -> 子类ctor()
子类与基类的ctor接受到的参数一致
CPromptBagEnter = Core.declare_class(CPrompt,"CPromptBagEnter")
二、文件结构分布(旧,仅供参考)
有部分文件夹不存在在以下列表,正常业务逻辑不会在除下面列表之外的文件夹中添加
Assets/Lua:所有lua文件
Client:客户端所有lua文件
battle_client:战斗客户端
const:常量文件
data:业务数据
drama:drama代码,部分需要用到drama地方使用
game_state:游戏状态
game_object:客户端3d显示对象
include:客户端文件导入
manager:客户端系统管理器
prompt:红点代码
sdk:sdk代码
utils:客户端工具函数
share:客户端与服务器共享的lua文件
battle:共享战斗代码
common:共享业务逻辑代码
core:共享基础代码
sensitive:敏感词
zdb:配置表数据
三、命名规范
命名规范分为命名方式以及命名习惯两部分
1、文件
方式:全部小写,下划线分割 ui_bag_main.lua
常用文件命名习惯
2、常量
全局常量
在GameConst全局标下定义,要求注释
GameConst.TowerUpComingLayerNum = 3 --- 显示未通关的占星塔层数数量
GameConst.RankingPlayerListNum = 5 --- 排行榜某一成就达成的排名限定数量
local常量
对于不需要全局使用的常量,允许在当前文件开头定义本地常量,以“_”开头和分隔,要求注释
local _attack_interval = 1.4 --- 攻击间隔
local _damage_delay = 0.5 --- 攻击后 怪物受击延迟
local _attack_times_range = {2,5} --- 攻击几次怪物死亡
local _duration_die = 1 --- 怪物死亡动画时间
3、变量
全局变量
不允许使用全局变量
本地变量
全部小写,以“_”开头和分隔
local _a_b = 1
参数
全部小写,以“”分隔,不需要用””开头
function Test(param)
-- body
end
类的私有成员变量
全部小写,以“_”开头和分隔
function ClassA:ctor()
self._private_a = 1
end
类的共有成员变量
全部小写,以"_"分隔
function ClassA:ctor()
self.public_a = 1
end
4、枚举
全局枚举
全局枚举在game_enum.lua中定义,以大写字母E开头,驼峰命名,并且每一个枚举项都要赋值
枚举项名全大写,以"_"分割
EFeatureLockType = {}
EFeatureLockType.NONE = 0
EFeatureLockType.HIDE = 1
EFeatureLockType.GRAY = 2
本地枚举
对于只需要本地使用的枚举,允许只在当前文件内定义,table需要是local的,不允许是全局的,以"_E"开头,驼峰命名,并且每一个枚举项都要赋值
---@class _EHungupBattleState
local _EHungupBattleState = {}
_EHungupBattleState.NONE = 0
_EHungupBattleState.IDLE = 1
_EHungupBattleState.PREPARE = 2
_EHungupBattleState.WALKING = 3 --- 走路入场
_EHungupBattleState.FIGHTING = 4 --- 攻击中
_EHungupBattleState.ENEMY_DYING = 5 --- 怪物死亡中
_EHungupBattleState.PREPARE_ENEMY = 6 --- 准备怪物中
_EHungupBattleState.WALKING_ENEMY = 7 --- 怪物入场中
5、函数
基本原则:函数都用驼峰命名,私有的用_开头,共有的不需要
全局函数
function TestA(...)
-- body
end
本地函数
以"_"开头,驼峰命名
local function _TestA(...)
-- body
end
类的private函数
以"_"开头,驼峰命名
---@private
function ClassA:_FuncPrivate()
-- body
end
类的public函数
驼峰命名
---@public
function ClassA:FuncPublic()
-- body
end
6、类
类名
以大写字母"C"开头,驼峰命名
---@class CPrompt
CPrompt = Core.declare_class({},"CPrompt")
类的属性
属性都用小写加’‘的格式
private属性在开头加一个’'标记
function CPrompt:ctor()
-- 类的private属性
self._private_a = 1
-- 类的public属性
self.public_a = 1
end
类的成员函数
成员函数都使用驼峰命名,私有函数以’_'开头
---私有函数
---@private
function CPrompt:_PrivateFunc()
-- body
end
---共有函数
---@public
function CPrompt:PublicFunc()
-- body
end
四、注释
项目中使用EmmyLua来完成类似静态语言的引用跳转功能,EmmyLua的使用教程请移步EmmyLua官方文档
规范的使用EmmyLua能让阅读代码的人事半功倍
这里主要强调EmmyLua注释的使用在项目中的使用规范
函数相关注释的使用
使用param标注所有参数类型
---@param race enum.ERace
---@param sort func
---@return CHeroInfo[]
function CMgrHero:GetAll(race,sort)
-- body
end
类注释的使用
使用class标注类名与父类
使用field标注成员属性的类型
---@class CPrompt
---@field _key string
CPrompt = Core.declare_class({},"CPrompt")
---@param key string
function CPrompt:ctor(key)
self._key = key
end
---@class CPromptBag : CPrompt
---@field _tbl_num table<number,number>
CPromptBag = Core.declare_class(CPrompt,"CPromptBag")
function CPromptBag:ctor()
self._tbl_num = {}
end
C#代码规范
后续添加