Lua学习笔记
0.LUA的作用浅析
现阶段我理解中Lua主要两个用途:一个是拿来写部分引擎脚本(Script),一个是给服务器更新用(主要是热更新)后续我计划手写一次Lua热更新
0.1用于游戏开发的LUA
为什么要在游戏领域使用LUA?
比如Cocos2d这种用的脚本语言就是Lua,而不是Unity或UE用的C#/C++
除开Lua作为轻量级动态解释型语言带来的低门槛,精简的特性以外,开发中如果只用C/C++这种高效率但同时高复杂性、高风险的编译型语言,极易产生BUG,而且对于开发人员的要求非常高。
从语言的的抽象层面来说C/C++的抽象低更加适合于底层逻辑的支持,而Lua脚本抽象层次高,更适合游戏逻辑实现。脚本语言运行在虚拟机之上,而虚拟机运行在游戏逻辑之上,作为一种解释型语言,程序员可以随时修改并及时体现在游戏之中,快速完成开发。C/C++却做不到,对一个巨大的游戏工程,每次修改都需要重新编译,成本很高。设想一下,如果所有的功能都是使用C/C++实现的话,那么对开发人员来说简直是一场灾难。
所以,个人理解下,Cocos这种着重于上手快,且多用于小游戏开发的整体用Lua,而Unity/UE这种团队大工程则不主要使用Lua。
0.2用于服务器热更新的LUA
某游戏公频有人开广告等独轮车需要禁用聊天功能或出现某种恶性BUG,简单几行代码就可完成。但停机维护的成本又太高,对于游戏来说,通常每个服就是单独的进程,也做不到像分布式环境下,关掉一部分机器,先升级一部分,再升级另一部分的无缝升级。这时候如果有热更就可以迅速的把Bug修复方案通过热更新进行修复,不会对用户任何的影响。
Unity中的Lua实现热更新
https://www.cnblogs.com/imteach/p/11257275.html
热更新原理
https://blog.csdn.net/peter_teng/article/details/52751231
1.1从菜鸟教程开始学LUA
EnimLife = 10
if (EnimLife == 5) then
io.write("Wow the enim is nearly to die","\n")
elseif (EnimLife >6) and (EnimLife <10) then
io.write("Sec Section","\n")
else
io.write("Bingo","\n")
end
-- Out:Bingo
print(type(a))
-- Out:nil
--对于全局变量和 table,nil 还有一个"删除"作用,
--给全局变量或者 table 表里的变量赋一个 nil 值,等同于把它们删掉
tab1 = {key = "val1",key = "val2","val3"}
-- 这里的table(表) 是一个关联数组
for k,v in pairs(tab1) do
print(k .. " - " .. v)
end
tab1.key1 =nil
for k,v in pairs(tab1) do
print(k .. " - " .. v)
end
if false or nil then
print("false和nil至少有一个是true")
else
print("都false")
end
-- Lua认为false和nil为假,true和非nil为真。
if 0 then
-- Lua中0为true判断
print("0是ture")
else
print("0是false")
end
-- 行字符串
string = "this's str1"
-- 块字符串
html = [[
]]
-- 运算中的字符串处理
print("2" + 6)
-- 8.0
print("2" + "6")
-- 8.0
print("2 + 6")
-- 2 + 6
-- 普通for循环
for i =1,10 do--外部定义的索引(循环次数)
i = 10-- 这里修改for里面的内部索引i不会应先for外部定义的循环次数
--但是修改了i的值 最终循环十次不变 但是每次输出的值都变为10
print({"one time,i:"..1})
end
-- Lua 中的重要数据结构 表 和Cpp中的容器概念一样
-- tab是数组和哈希表的混合体
-- Table是由数组(array)和哈希表(node)两部分组成
-- 哈希表是一个由Node组成的数组,Node包括Key和Value
-- luatab就和hashtab一样有键值对 具体底层原来挺繁琐的 不提
a = {}
a["key"] = "value"
key = 10 -- 这里键是key
a[key] = 22 --a[key]指的是a表中键名叫key的值 这里已经是值了
a[key] = a[key] + 11
for k,v in pairs(a) do
print(k .. " : " .. v)
end
--[[
补充下前置知识 迭代器本身是变量 由它去访问容器中的元素 拿CPP举例
详见:http://c.biancheng.net/view/338.html 后面专门写博客讲一下
Lua中使用封装好的迭代器进行泛型迭代 pairs和ipairs都是迭代器
python中 for value in sequence: 循环是一种隐式迭代 for语句中隐含了迭代器
]]
local tab1 ={}
local tab2 = {"one","two","three"}
-- 这里补充一下泛型for循环
-- 泛型 for 循环通过一个迭代器函数(ipairs)来遍历所有值(也可说是用来迭代数组)
-- 类似 JEE 中的 <c:foreach>
for i,v in ipairs(a) do
--[[
这里iparis和pairs函数还有区别 详细说一下
pairs可以遍历表中所有的key,并且除了迭代器本身以及遍历表本身还可以返回nil;
但是ipairs则不能返回nil,只能返回数字0,
如果遇到nil则退出。它只能遍历到表中出现的第一个不是整数的key
pairs 能迭代所有键值对 ipairs 可以想象成 int+pairs,只会迭代键为数字的键值对
]]
print(i,v)
end
-- Out:one \n two \b three
-- 再补充一下ipairs迭代器
tab = {1,2,a= nil,"d"}
for i,v in ipairs(tab) do
print(i,v)
end
--[[
Out:
1 1
2 2
3 d
]]
-- 实现套嵌循环
j = 2
for i=2,10 do
for j=2,(i/j), 2 do--for里面三个部分对应init,max/min value,step
if(not(i%j)) then
break
end
if(j>(i/j))then
print("i 的值为:",i)
end
end
end
-- 函数
function max(num1,num2)
if (num1>num2) then
result = num1
else
result =num2
end
return result
end
-- 回调函数(和JS的一样)
myprint = function (param)
print("这是打印函数- ##",param,"##")
end
function add(num1,num2,functionPrint)
result = num1+num2
functionPrint(result)
end
myprint(10)
add(2,5,myprint)
-- lua中没有 != ,要表示不等于用~=
-- lua中if逻辑 !(a&b) 用 not(a and b)
if(not(a and b)) then
print("")
else
print("")
end
-- ..用于连接两个字符串
-- #用于返回长度 '' "" [[]]都可以用于表达字符串
a = "hello"
b = 'world'
print("连接字符串a和b",a..b)
print("world的长度",#b)
-- 数组
array = {"Arr","Lua"}
for i = 0,2 do
print(array[i])
end
--[[ Out:
nil(Lua从1开始,如果指定索引从0开始理所当然得到空值)
Lua
Tutorial
]]
-- 填充一个多维数组
array = {}--初始化
for i=1,3 do
array[i] = {}--不给这行的话 一维数组初始化不了 返回一个nil值报错
for j=1,3 do
array[i][j] = i*j
end
end
-- 访问这个数组
for i=1,3 do
for j=1,3 do
print(array[i][j])
end
end
-- array = {}
for i=1,3 do
array[i] = i*2 --对array我必须先array = {}初始化
--不然报错attempt to index a nil value 这里nil值的出现推测是索引值出问题了
end
-- 也就是说对二维数组 我的初始化两次
array = {}--先在一维初始化
for i=1,3 do
array[i] = {}-- 这里还得把array[1]...array[3]全初始化一遍
--才能在二维装东西 声明二维,每一个一维数组里面的一个元素都是一个数组;
for j=1,3 do
array[i][j] = i*j
end
end
-- JS也这样
-- 迭代器
Lua
COPY
重点在于C#和LUA的交互
C和Lua语言之间存在的差异,第一种是Lua使用了垃圾回收机制 ,而C语言需要显式的释放内存。第二种C语言是静态类型(在编译时可以确定变量类型,像int x这种),Lua是动态类型(编译时无法确定变量类型,不用注明变量类型)。为了解决这些问题 ,C与Lua的通信引入了虚拟栈结构
现有框架主要是Tolua(用于成熟的项目比较多,比如客户端逻辑大多lua实现,背包之类的UI使用lua也不会太在意消耗性能,AI等逻辑还是C#做,网易雷火是这样的),tolua等热更新方案提供了C#与Lua的互相调用机制
如我上面所说,除开热更新以外,ToLua提供的交互机制使得我们可以在unity中通过Lua脚本编写游戏逻辑(方法详见ref:https://zhuanlan.zhihu.com/p/42472089/)
另外可以考虑用cocos2d写个JS的微信小游戏
ref:
用Lua写轻量级服务器
游戏碰撞检测总结(Ver 1.0)

浙公网安备 33010602011771号