lua入门
一、为何要用lua本章介绍热更新与lua的关系,知道了lua有什么作用才能在之后的学习里更有动力~
1、为何需要热更新
开发者开发游戏时,通常会使用c#或者c++等
体量庞大的语言,因为其功能库多,使用方便,能够构造出复杂的系统。但身为一门编译型语言,编译的过程在移动平台无法完成,运行之前需要通过开发者编译后打包,才能分发给玩家游玩。
假如你开发了一款游戏,刚上架应用市场,BUG反馈铺天盖地。
你改好了BUG后重新打包,上传应用市场。而玩家又得从应用市场将整个游戏重新下载安装。本来就被BUG折磨的玩家望着一个小时的下载时间,果断弃坑。
为了拉高玩家留存率,提升活跃度,让游戏死得不那么快,我们需要一个小巧轻便的更新方式,避开c#的编译。
2、为何热更需要lua
要解释这个问题得先明白编译性语言与脚本语言的区别:
[*]编译性语言
[*]编译性语言在编译后,可脱离环境运行
[*]需要通过虚拟机编译成汇编代码,才能供各个平台执行。随着打包的完成,程序不能进行修改。
[*]写好的代码->编译成.dll扩展程序->平台执行
[*]脚本语言
[*]脚本语言必须安装对应的脚本环境
[*]脚本语言在有虚拟机的情况下,可以直接解释执行。lua代码在运行时才编译,不运行时和文本无异。
[*]写好代码->平台中的虚拟机执行
所以热更新的方式有很多种,编译性语言和脚本语言都可以。
可以把c#代码编译成独立的dll,上传服务器,玩家启动游戏时从服务器上下载dll文件,达到热跟新的目的。但这样的更新容易给系统带来安全隐患,部分系统不允许这样的热更,为了安全起见,不能给程序太强的能力。
这个时候lua就能发挥其优势了,身为脚本语言,lua在运行时才会被动态解释,在没运行时就是一个普通的资源文件。可以很方便的传输,且不容易被平台禁止。
3、lua如何实现热更
前文说到,脚本语言需要在环境内内嵌虚拟机,在游戏运行时动态解析脚本。对于lua的解析,市面上有许多解决的框架,比如tolua、xlua、ulua、slua等等,有了这些框架,就不用担心虚拟机运作的问题,可以很方便的使用lua脚本进行热更新的处理了。
二、lua入门
对为何要使用lua有了一定的了解,接下来是lua的基础使用。鉴于网络上的教程众多,这里只列举lua特性,对其特点进行归纳,做一个简洁的版本。如果需要更系统的学习,可以去菜鸟网学习Lua 教程 | 菜鸟教程 (runoob.com)
1、lua语法
(1)变量定义
lua是弱类型语言,不需要为变量定义数据结构,只需要为变量赋值即可。
按照变量的作用域来划分,lua有三种数据类型:全局变量、局部变量、表中的域。
[*]全局变量:变量默认为全局变量,除非明确声明为局部变量。
[*]局部变量:变量指定类型为local时,其范围约束在函数范围内。
[*]表字段:这是一种特殊类型的变量,可以保存除nil之外的任何内容,包括函数。
function test()
a = 5 --全局变量
local b = 6 --局部变量
end
text()
print(a,b) --5,nil
(2)数据类型
lua的变量有8个基本类型:nil、boolean、number、string、userdata、function、thread 和 table,可以通过type()函数查看变量的数据类型。
print(type(nil)) --> nil
print(type("Hello world")) --> string
print(type(10)) --> number
print(type(print)) --> function
print(type(true)) --> boolean
local a = {}
print(type(a)) --> table(3)运算符
算数运算符
运算符描述+两个操作数相加-第一个数减去第二个数)*两个操作数相乘/两个操作数相除%取余^幂运算-否定/复数关系运算符
运算符描述==检查两个操作数是否相等~=检查两个操作数是否不等>大于<小于>=大于等于<=小于等于逻辑运算符
运算符描述and逻辑与or逻辑或not逻辑非字符串运算符
运算符描述...链接两个字符串#返回字符串长度(4)流程控制
(1)循环
lua提供了三种循环语句while、for、repeat,当然,常用的还是前面两种
while
当condition判断为true时,执行do、end之间的语句
while(condition)
do
statements
endfor
for var=exp1,exp2,exp3
do
statements
end初始值exp1,结束值exp2,步长exp3(默认为1)
lua也可以通过迭代器进行遍历(图中为ua自带的迭代器函数ipairs)
for k, v in pairs(t) do
print(k, v)
end(2)分支/判断
if/elseif
lua的判断语句需要在if/elseif后需要加上then,else不需要then。整套判断流程完毕后,在末尾添加end。
a = 0
if(a>10) then
print(&#34;a大于10&#34;)
elseif(0>a and 10<a) then
print(&#34;a介于0到10之间&#34;)
else
print(&#34;a小于10&#34;)
end2、lua组织结构
(1)table表
在lua中,表是一个重要又特殊的一个存在。既能充当数据结构做列表,又能保存数据与方法充当类的功能。
lua就是用table来解决模块(module)、包(package)和对象(object)的。
[*]table的构造
table的构造非常简单,通过一对中括号即可完成表的初始化
--初始化表
mytable = {}
[*]赋值取值
表可以通过多种方式赋值取值,lua的表特别自由,一个类型包含了一般语言中列表、字典、类的操作方式,来操作lua表中的数据。
--赋值
mytable.wow = &#34;哇&#34; --通过“.属性”的方式赋值
mytable[&#34;hah&#34;] = &#34;哈&#34; --通过中括号的方式赋值
mytable = &#34;哈&#34; --通过索引的方式赋值
--取值
print(mytable.wow) --通过“.属性”的方式取值
print(mytable[&#34;hah&#34;]) --通过列表的方式取值
print(mytable) --通过索引的方式赋值如果没有指定键值对,则会用索引由索引做键,如果指定了键则以指定的值为准。
虽然表提供了很多赋值取值的方法,但是赋值取值之间方法要对应。如果通过“.属性”的方法赋值,则取值的时候也要通过“.属性”的方式取值
[*]table中的方法
序号方法用途1table.concat (table,sep,start,end)连接table,指定table的数组部分从start位置到end位置的所有元素, 元素间以分隔符(sep)隔开。2table.insert (table, pos,value)在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾.4table.remove (table , pos)返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起。5table.sort (table)对table进行升序排序。(2)模块与包
[*]模块
lua中的模块类似一个封装库,可以以API接口的形式在其他地方调用。模块的创建方式非常简单,创建一个table,并将需要导出的常量、函数放入其中,最后返回这个table
-- 文件名为 module.lua
-- 定义一个名为 module 的模块
module = {}
-- 定义一个常量
module.constant = &#34;这是一个常量&#34;
-- 定义一个函数
function module.func1()
io.write(&#34;这是一个公有函数!\n&#34;)
end
--返回moudle
return module
[*]require
lua可以通过require函数来加载其他模块,执行 require 后会返回一个由模块常量或函数组成的 table,并且还会定义一个包含该 table 的全局变量。
require(&#34;module&#34;)
print(module.constant)
module.func1()
[*]C包
lua与c结合,c语言写出的模块称之为c包。lua通过loadlib函数链接c包,这个函数需要库的绝对路径与初始化函数。通过返回一个初始化函数作为lua的一个函数,这样就可以在lua文件中调用。
local path = &#34;/usr/local/lua/lib/libluasocket.so&#34;
local f = assert(loadlib(path, &#34;luaopen_socket&#34;))
f()-- 真正打开库
(3)元表
lua中提供了一种方式,可以让我们改变table的行为——添加一张元表,通过重写元表中的元方法改变表的行为,每种行为都有对应的元方法。
处理元表的两个重要函数:
mytable = {} -- 普通表
mymetatable = {} -- 元表
setmetatable(mytable,mymetatable) -- 把 mymetatable 设为 mytable 的元表
getmetatable(mytable) --返回元表对象
[*]元函数
__index元方法
Lua 查找一个表元素时的规则,其实就是如下 3 个步骤:
[*]在表中查找,如果找到,返回该元素,找不到则继续
[*]判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
[*]判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。
该部分内容来自作者寰子:Lua查找表元素过程(元表、__index方法是如何工作的)_lua获取元素位置_寰子的博客-CSDN博客
cup={water=100}
setmetatable(cup,{__index={fire=10}})
print(cup.water)
print(cup.fire)元方法还有很多,感兴趣的读者可以自行搜索捏~
页:
[1]