_Lua与网络游戏.ppt

上传人:来看看 文档编号:3650670 上传时间:2019-09-19 格式:PPT 页数:35 大小:270KB
返回 下载 相关 举报
_Lua与网络游戏.ppt_第1页
第1页 / 共35页
_Lua与网络游戏.ppt_第2页
第2页 / 共35页
_Lua与网络游戏.ppt_第3页
第3页 / 共35页
_Lua与网络游戏.ppt_第4页
第4页 / 共35页
_Lua与网络游戏.ppt_第5页
第5页 / 共35页
点击查看更多>>
资源描述

《_Lua与网络游戏.ppt》由会员分享,可在线阅读,更多相关《_Lua与网络游戏.ppt(35页珍藏版)》请在三一文库上搜索。

1、Lua与网络游戏,管传淇,Lua与现在的游戏,现在有哪些游戏用Lua 暴雪 魔兽世界 UBI 孤岛惊魂(Far Cry) 网易 大话系列 完美 神鬼传奇,降龙之剑 金山 剑网3 畅游 天龙八部 巨人 征途,巨人 主要运用在哪些方面 UI插件 客户端的图像控制 任务系统 AI系统 伤害计算,Lua的特点,Lua在这脚本语言中是运行时速度最快而且占内在最少的。 集成Lua只会增加极少的内存占用率 Lua容易地通过C/C+ 集成在软件里 快,轻巧,表达式 算法运算符: 二元运算符:+-*/ (加减乘除幂) 一元运算符: -(负值) 关系运算符: = = = 逻辑运算符: and or not 连接运

2、算符: ,Lua的基本语法,基本类型 nil 一个变量没赋值前默认值是nil,给变量赋nil可以删除该变量,相当于C+中的Null boolean 只有false和nil为假,其他值都为真 number 数值型, 相当于int,long,short,double等 string 用法a “aa“ , function function(a,b) return a + b end thread 线程,协同函数 table 1,2,3,4 x=2, y=3 userdata 用户数据 允许Lua变量存储定制的 C+数据,Lua中唯一的数据结构:Table,Lua的tables实现了类似Python

3、里面Tuple的功能, 不仅可以通过数字下标检索数据,还可以通过别的类型的值检索数据。 Lua中除了nil以外的类型都可以作为tables的索引下标. tables没有固定的大小,你可以根据需要动态的调整他的大小. tables是Lua主要的也是唯一的数据结构, 可以通过他实现传统数组, 符号表, 集合, 队列,以及其他的数据结构,Table实例,a = a“x” = 10 a20 = “great“ myPolygon = color=“blue”, thickness=2, npoints=4; x=0,y=0, x=-10, y=0, x=-5,y=4, x=0,y=4 ,Lua中的函数

4、,Function 函数名(参数1,参数2) 函数体 End 函数名 = Function(参数1,参数2) 函数体 End Example: Function PrintHelloWorld() Print “Hello,world” End PrintHelloWorld = function() Print “Hello,world” end,Lua 的控制结构,If then else end if a =10 for var = exp1,exp2,exp3 do for I = 0 , 10, 1 do print i end,一个链表的实现,list=nil insert=fun

5、ction(v) list=lnext=list,data=v End printlist=function() local l=list while l do print(l.data) l=l.lnext end End del_elem=function(v) local l=list while l=nil do if l.lnext.data=v then l.lnext=l.lnext.lnext break; end l=l.lnext end end,Lua中的面向对象,Lua没有类的概念,但可以用其他方法模拟 Lua中面向对象是用元表这种机制来模拟的 元表是什么?,Lua面向

6、对象的模拟,继承 通过改变表的元表来继承其他表的行为 多态 Lua行为的规则是:如果表中含此行为,就用当前表的行为,如果没有,就从元表中查找行为,依次递归,Lua面向对象-元表,可通过函数getmetatable查询任何值的元表。 可通过函数setmetatable替换表的元表。,面向对象的实例,Account是账号类,它将是Lua中所有Account实例的元表 Account = balance =0; Function Account:WithDraw(v)取款函数 self.balance = self.balance-v; End Function Account:new(o)产生Ac

7、count对象,一个实例 o = o or setmetatable(o,self)设置元表 self._index = self return o; End Function Account:despoit(v)存款函数 self.balance += v; End,Lisa = Account:new(); -创建Lisa这个Account实例 John = Account:new();-创建john这个Account实例 t1 = getmetatable(lisa); t2 = getmetatable(john); Lisa:withDraw(100) John:Deposit(20

8、0) Lisa,john相当于C+中的对象实例,Lisa 和 john 是Account类下的不同的对象实例 Lisa,john其实还是Lua中的table,他们因为有共同的元表,所有可以看成同一类的table Lisa:withDraw(100)的调用过程,从Lisa表中查找,找不到函数的声明,因为又有元表,所有从元表中的中查找,在所指向的表中找到了withDraw的声明,所有调用成功,Lua与C+,Lua的C库提供一系列API: * 管理全局变量 * 管理tables * 调用函数 * 定义新函数 * 垃圾收集器GC * 载入并执行Lua程序 任何Lua可以实现的功能, 都可以通过Lua的

9、C API实现, 这对于优化程序的运行速度 有帮助. 经常调用的共用的Lua程序片断可以转成C程序, 以提高效率. 连Lua都是C写的,Lua与C+交互的基本过程,lua_State* L = lua_open();/创建Lua脚本虚拟机 luaL openlibs(L);. /加载Lua运行库(内置的Lua函数) /加载Lua文件到虚拟机 luaL loadfile(L,”test.lua”); lua_pcall( L, 0, LUA_MULTRET, 0 ); 交互 lua_close(L);,Lua与C的差异,Lua是动态类型, 而C是静态类型的 Lua使用垃圾收集,而C要求显示释放

10、需要一个中间的东西供两个不同的环境协调工作,Lua与C+交互:栈,一个抽象的栈在Lua与C打交道 栈中的每一条记录都可以保存任何Lua值。 几乎所有的交互API函数都用到了栈 栈是由Lua来管理的 严格的LIFO规则来操作栈。当调用Lua时,它只会改变栈顶部分。但通过Lua的API,可以查询栈上的任何元素,甚至是在任何一个位置插入和删除元素。 无论你何时想要从Lua请求一个值,调用Lua,被请求的值将会被压入栈。无论你何时想要传递一个值给Lua,首先将这个值压入栈,然后调用Lua,Lua与C+交互:栈,API用索引来访问栈中的元素。 在栈中的第一个元素(也就是第一个被压入栈的)有索引1,下一个

11、有索引2,以此类推。也可以用栈顶作为参照来存取元素,利用负索引。在这种情况下,-1指出栈顶元素(也就是最后被压入的),-2指出它的前一个元素,以此类推。 例如,调用lua_tostring(L, -1)以字符串的形式返回栈顶的值。,Lua与C+交互:栈,API有一系列压栈的函数,它将每种可以用C来描述的Lua类型压栈:空值(nil)用lua_pushnil,数值型(double)用lua_pushnumber,布尔型(在C中用整数表示)用lua_pushboolean,C语言风格(以”结束)的字符串用lua_pushstring,用户的自定义数据用lua_pushuserdata void l

12、ua_pushnil (lua_State *L); void lua_pushboolean (lua_State *L, int bool); void lua_pushnumber (lua_State *L, double n); void lua_pushstring (lua_State *L, const char *s); void lua_pushuserdata(lua_State *L, void* p); . 例: lua_pushboolean(L,false); lua_pushnumber(L, 200); lua_pushstring(L,”hello,worl

13、d”);,Lua与C+交互:栈,API提供了一套lua_is*函数来检查一个元素是否是一个指定的类型,*可以是任何Lua类型。因此有lua_isnumber,lua_isstring,lua_istable以及类似的函数。所有这些函数都有同样的原型: int lua_is (lua_State *L, int index); 如lua_isnumber和lua_isstring index 为栈中的索引 实例: if( lua_isstring(L,-1) ) print(“string”); if(lua_isnumber(L,-2) print(“number”); if( lua_isb

14、oolean(L,-3) print(“bool”):,Lua与C+交互:栈,为了从栈中获得值,这里有lua_to*函数: lua_Number (lua_tonumber) (lua_State *L, int idx); lua_Integer (lua_tointeger) (lua_State *L, int idx); int (lua_toboolean) (lua_State *L, int idx); const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); lua_CFunction (lua_tocf

15、unction) (lua_State *L, int idx); void* (lua_touserdata) (lua_State *L, int idx); index 为栈中的索引 实例: char* szStr = lua_tostring(L,-1); int num = lua_tonumber(L,-2); bool bSuc = lua_toboolean(L,-3);,Lua与C+交互:栈,除开上面所提及的C与堆栈交换值的函数外,API也提供了下列函数来供程序员人工控制堆栈情况: int lua_gettop (lua_State *L); void lua_settop

16、(lua_State *L, int index); void lua_pushvalue (lua_State *L, int index); void lua_remove (lua_State *L, int index); void lua_insert (lua_State *L, int index); void lua_replace (lua_State *L, int index); index 为栈中的索引,简单的栈操作,lua_pushboolean(L, 1); lua_pushnumber(L, 10); lua_pushnil(L); lua_pushstring(

17、L, “hello”); 堆栈顺序: 1,10,nil,”hello” lua_pushvalue(L, -4); 堆栈顺序: 1,10,nil,”hello” ,1 lua_replace(L, 3); 堆栈顺序: 1,10,1,”hello” lua_settop(L, 6); 堆栈顺序: 1,10,1,”hello” ,nil,nil lua_remove(L, -3); 堆栈顺序: 1,10,1,nil,nil,Lua与C+交互:访问表,栈中对Table的访问API void (lua_gettable) (lua_State *L, int idx); void (lua_getfi

18、eld) (lua_State *L, int idx, const char *k); void (lua_settable) (lua_State *L, int idx); void (lua_setfield) (lua_State *L, int idx, const char *k); lua中定义的全局变量存放在一个全局表中, 通过void lua_getglobal (lua_State *L, const char *name)获取,简单的表的访问实例,假设栈的-1处是一个表 Lua_pushnumber(L,100); Lua_pushstring(L,”hello,wor

19、ld”) Lua_settable(L,-3);/设置此时处于-3处的表字段为100的字段对应的数据位”hello,world” 假设栈的-2处是一个表 lua_getfield(L,-2,”Data”);/获取-2处表字段为Data的数据,并压入栈顶 假设栈的-3处是一个表 Lua_pushnumber(L,999); lua_setfield(L,-3,”Val”);/将栈顶数据赋值给处于-3处的Table的Val字段。并将栈顶数据弹出栈 Lua_getglobal(L,”Data”);/获取全局表中的Data的值,并将值压入栈 Lua_pushnumber(L,888); /将888压入

20、 栈顶 Lua_setglobal(L,”Data”);/将栈顶的值设置为全局表中Data字段的值,C+访问Lua,请求LUA函数入栈。 将函数需要的参数入栈,入栈顺序按照参数被声明的顺序。 告知LUA虚拟机入栈参数的个数、函数返回值的个数,并调用此LUA函数。 从栈定获得返回值,先返回的先入栈,然后将返回值显式出栈。,C+访问Lua 函数 实例,func.lua -变量定义 width=1 ; height=2 ; -lua函数定义,实现加法 function sum(a,b) return a+b ; end -lua函数定义,实现字符串相加 function mystrcat(a,b)

21、return ab ; end -lua函数定义,通过调用c代码中的csum函数实现加法 function mysum(a,b) return csum(a,b) ; end,int main(int argc,char* argv) lua_State * l = luaL_newstate() ; /创建lua运行环境 int ret = luaL_loadfile(l,“func.lua“) ; /加载lua脚本文件 if ( ret != 0 ) err_return(-1,“luaL_loadfile failed“) ; ret = lua_pcall(l,0,0,0) ; if

22、( ret != 0 ) err_return(-1,“lua_pcall failed:%s“,lua_tostring(l,-1) ; lua_getglobal(l,“width“); /获取lua中定义的变量 lua_getglobal(l,“height“); printf(“height:%ld width:%ldn“,lua_tointeger(l,-1),lua_tointeger(l,-2) ; lua_pop(l,2) ; /恢复lua的栈 int a = 11 ; int b = 12 ; lua_getglobal(l,“sum“); /调用lua中的函数sum lua

23、_pushinteger(l,a) ; lua_pushinteger(l,b) ; ret = lua_pcall(l, 2,1,0) ; if ( ret != 0 ) err_return(-1,“lua_pcall failed:%s“,lua_tostring(l,-1) ; printf(“sum:%d + %d = %ldn“,a,b,lua_tointeger(l,-1) ; lua_pop(l,1) ; const char str1 = “hello“ ; const char str2 = “world“ ; lua_getglobal(l,“mystrcat“); /调

24、用lua中的函数mystrcat lua_pushstring(l,str1) ; lua_pushstring(l,str2) ; ret = lua_pcall(l,2,1,0) ; printf(“mystrcat:%s%s = %sn“,str1,str2,lua_tostring(l,-1) ; lua_pop(l,1) ; lua_close(l) ; /释放lua运行环境 return 0 ; ,Lua访问C+,将C的函数包装成Lua环境认可的函数 将包装好的函数注册到Lua环境中 Lua调用C函数时, C函数从栈中获取参数,并将计算结果压入栈,并返回压入栈的结果的数量 从Lua

25、脚本中调用C+函数,函数必须定义Lua_CFunction类型。格式如下: Int (lua_Cfunction*)(lua_state*),Lua访问C+ 实例,将C函数包装成Lua可使用的函数类型 lua_Cfunction 注册包装好的函数到Lua的表中 像使用普通的Lua函数那样使用注册函数 void PrintHelloWorld() printf(“hello,world”); Int AddSum( int a, int b ) return a + b; ,包装成Lua可访问的函数类型 (从普通的C函数 包装成Lua可访问的Int (lua_Cfunction*)(lua_st

26、ate*)型函数) Static int l_PrintHelloWorld(lua_state* L) PrintHelloWorld(); Static int l_AddSum(lua_state* L) int b = lua_tonumber(L,-1); int a = lua_tonumber(L,-2); int sum = a +b; lua_pushnumber(L,sum);-将返回值压入堆栈 return 1; -有返回值,要告诉解释器,函数向堆栈压入了几个返回值 ,将包装函数注册到Lua中( lua中定义的变量和函数存放在一个全局table中) lua_pushcfunction(L, l_PrintHelloWorld); Lua_setglobal(L,”PrintHelloWorld”);/global“PrintHelloWorld” = l_PrintHelloWorld Lua_pushcfunction(L, l_AddSum); Lua_setglobal(L,”AddSum”);/global“AddSum” = l_AddSum Test.lua中使用 PrintHelloWorld(); AddSum(3,5);,Thank YOU!,Q & A,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/环境 > 装饰装潢


经营许可证编号:宁ICP备18001539号-1