_Lua与网络游戏.ppt

上传人:仙人指路1688 文档编号:2530312 上传时间:2023-02-20 格式: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连接运算符:.,Lua的基本语法,基本类型n

2、il一个变量没赋值前默认值是nil,给变量赋nil可以删除该变量,相当于C+中的Nullboolean 只有false和nil为假,其他值都为真number 数值型,相当于int,long,short,double等string 用法a aa,function function(a,b)return a+b endthread 线程,协同函数table 1,2,3,4 x=2,y=3userdata 用户数据 允许Lua变量存储定制的 C+数据,Lua中唯一的数据结构:Table,Lua的tables实现了类似Python里面Tuple的功能,不仅可以通过数字下标检索数据,还可以通过别的类型的

3、值检索数据。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中的函数,Function 函数名(参数1,参数2)函数体End函数名=Function(参数1,参数2)函数体EndExample

4、:Function PrintHelloWorld()Print“Hello,world”EndPrintHelloWorld=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=nilinsert=function(v)list=lnext=list,data=vEndprintlist=function()local l=list while l do print(l.data

5、)l=l.lnext endEnddel_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 endend,Lua中的面向对象,Lua没有类的概念,但可以用其他方法模拟Lua中面向对象是用元表这种机制来模拟的 元表是什么?,Lua面向对象的模拟,继承 通过改变表的元表来继承其他表的行为多态 Lua行为的规则是:如果表中含此行为,就用当前表的行为,如果没有,就从元表中查找行为,依次递归,Lua面向对象-元表,可通过函数getmeta

6、table查询任何值的元表。可通过函数setmetatable替换表的元表。,面向对象的实例,Account是账号类,它将是Lua中所有Account实例的元表 Account=balance=0;Function Account:WithDraw(v)取款函数 self.balance=self.balance-v;EndFunction Account:new(o)产生Account对象,一个实例 o=o or setmetatable(o,self)设置元表 self._index=self return o;End Function Account:despoit(v)存款函数 sel

7、f.balance+=v;End,Lisa=Account:new();-创建Lisa这个Account实例John=Account:new();-创建john这个Account实例t1=getmetatable(lisa);t2=getmetatable(john);Lisa:withDraw(100)John:Deposit(200)Lisa,john相当于C+中的对象实例,Lisa 和 john 是Account类下的不同的对象实例Lisa,john其实还是Lua中的table,他们因为有共同的元表,所有可以看成同一类的tableLisa:withDraw(100)的调用过程,从Lisa

8、表中查找,找不到函数的声明,因为又有元表,所有从元表中的中查找,在所指向的表中找到了withDraw的声明,所有调用成功,Lua与C+,Lua的C库提供一系列API:*管理全局变量*管理tables*调用函数*定义新函数*垃圾收集器GC*载入并执行Lua程序任何Lua可以实现的功能,都可以通过Lua的C API实现,这对于优化程序的运行速度 有帮助.经常调用的共用的Lua程序片断可以转成C程序,以提高效率.连Lua都是C写的,Lua与C+交互的基本过程,lua_State*L=lua_open();/创建Lua脚本虚拟机luaL openlibs(L);./加载Lua运行库(内置的Lua函数)

9、/加载Lua文件到虚拟机 luaL loadfile(L,”test.lua”);lua_pcall(L,0,LUA_MULTRET,0);交互lua_close(L);,Lua与C的差异,Lua是动态类型,而C是静态类型的Lua使用垃圾收集,而C要求显示释放 需要一个中间的东西供两个不同的环境协调工作,Lua与C+交互:栈,一个抽象的栈在Lua与C打交道栈中的每一条记录都可以保存任何Lua值。几乎所有的交互API函数都用到了栈 栈是由Lua来管理的严格的LIFO规则来操作栈。当调用Lua时,它只会改变栈顶部分。但通过Lua的API,可以查询栈上的任何元素,甚至是在任何一个位置插入和删除元素。

10、无论你何时想要从Lua请求一个值,调用Lua,被请求的值将会被压入栈。无论你何时想要传递一个值给Lua,首先将这个值压入栈,然后调用Lua,Lua与C+交互:栈,API用索引来访问栈中的元素。在栈中的第一个元素(也就是第一个被压入栈的)有索引1,下一个有索引2,以此类推。也可以用栈顶作为参照来存取元素,利用负索引。在这种情况下,-1指出栈顶元素(也就是最后被压入的),-2指出它的前一个元素,以此类推。例如,调用lua_tostring(L,-1)以字符串的形式返回栈顶的值。,Lua与C+交互:栈,API有一系列压栈的函数,它将每种可以用C来描述的Lua类型压栈:空值(nil)用lua_push

11、nil,数值型(double)用lua_pushnumber,布尔型(在C中用整数表示)用lua_pushboolean,C语言风格(以”结束)的字符串用lua_pushstring,用户的自定义数据用lua_pushuserdata void lua_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

12、(lua_State*L,void*p);.例:lua_pushboolean(L,false);lua_pushnumber(L,200);lua_pushstring(L,”hello,world”);,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 为栈中的索引实例:

13、if(lua_isstring(L,-1)print(“string”);if(lua_isnumber(L,-2)print(“number”);if(lua_isboolean(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_tolstr

14、ing)(lua_State*L,int idx,size_t*len);lua_CFunction(lua_tocfunction)(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_g

15、ettop(lua_State*L);void lua_settop(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_p

16、ushstring(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的访问APIvoid(lua_gettable)(lua_State*L,int idx);void(lua_getfield)(lua_State*L

17、,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,world”)Lua_settable(L,-3);/设置此时处于-3处的表字段为100

18、的字段对应的数据位”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压入 栈顶Lua_setglobal(L,”Data”);/将栈顶的值设置为全局表中Data字段的值,C

19、+访问Lua,请求LUA函数入栈。将函数需要的参数入栈,入栈顺序按照参数被声明的顺序。告知LUA虚拟机入栈参数的个数、函数返回值的个数,并调用此LUA函数。从栈定获得返回值,先返回的先入栈,然后将返回值显式出栈。,C+访问Lua 函数 实例,func.lua-变量定义width=1;height=2;-lua函数定义,实现加法functionsum(a,b)returna+b;end-lua函数定义,实现字符串相加functionmystrcat(a,b)returna.b;end-lua函数定义,通过调用c代码中的csum函数实现加法functionmysum(a,b)returncsum(

20、a,b);end,intmain(intargc,char*argv)lua_State*l=luaL_newstate();/创建lua运行环境intret=luaL_loadfile(l,func.lua);/加载lua脚本文件if(ret!=0)err_return(-1,luaL_loadfilefailed);ret=lua_pcall(l,0,0,0);if(ret!=0)err_return(-1,lua_pcallfailed:%s,lua_tostring(l,-1);lua_getglobal(l,width);/获取lua中定义的变量lua_getglobal(l,hei

21、ght);printf(height:%ldwidth:%ldn,lua_tointeger(l,-1),lua_tointeger(l,-2);lua_pop(l,2);/恢复lua的栈inta=11;intb=12;lua_getglobal(l,sum);/调用lua中的函数sumlua_pushinteger(l,a);lua_pushinteger(l,b);ret=lua_pcall(l,2,1,0);if(ret!=0)err_return(-1,lua_pcallfailed:%s,lua_tostring(l,-1);printf(sum:%d+%d=%ldn,a,b,lua

22、_tointeger(l,-1);lua_pop(l,1);constcharstr1=hello;constcharstr2=world;lua_getglobal(l,mystrcat);/调用lua中的函数mystrcatlua_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运行环境return0;,Lua访问C+,将C的函数包装成Lu

23、a环境认可的函数将包装好的函数注册到Lua环境中Lua调用C函数时,C函数从栈中获取参数,并将计算结果压入栈,并返回压入栈的结果的数量 从Lua脚本中调用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;,包装成L

24、ua可访问的函数类型(从普通的C函数 包装成Lua可访问的Int(lua_Cfunction*)(lua_state*)型函数)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_PrintHelloWorldLua_pushcfunction(L,l_AddSum);Lua_setglobal(L,”AddSum”);/global“AddSum”=l_AddSumTest.lua中使用 PrintHelloWorld();AddSum(3,5);,Thank YOU!,Q&A,

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

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号