??xml version="1.0" encoding="utf-8" standalone="yes"?>嫩草影院久久国产精品,国产午夜免费高清久久影院,国产精品日韩欧美久久综合http://www.shnenglu.com/iwangchuchu/阔天空zh-cnTue, 06 May 2025 20:24:33 GMTTue, 06 May 2025 20:24:33 GMT60[转]lg工厂 -----3D游戏开?/title><link>http://www.shnenglu.com/iwangchuchu/archive/2010/04/23/113341.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Fri, 23 Apr 2010 08:06:00 GMT</pubDate><guid>http://www.shnenglu.com/iwangchuchu/archive/2010/04/23/113341.html</guid><wfw:comment>http://www.shnenglu.com/iwangchuchu/comments/113341.html</wfw:comment><comments>http://www.shnenglu.com/iwangchuchu/archive/2010/04/23/113341.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/iwangchuchu/comments/commentRss/113341.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/iwangchuchu/services/trackbacks/113341.html</trackback:ping><description><![CDATA[<div>狭义的游戏对象是指游戏世界中所能看到及可交互的对象Q如玩家、怪物、物品等Q我们这里也主要讨论q类对象在服务器上的l织及实现?/div> <div>   <p>  在大部分的MMOG中,游戏对象的类型都大同异Q主要有物品、生物、玩家等。比如在wow中,通过服务器发下来的GUID我们可以了解刎ͼ游戏中有9大类对象Q包括物?Item)、背?Container)、生?Unit)、玩?Player)、游戏对?GameObject)、动态对?DynamicObject)、尸?Corpse){?/p> <p>  在mangos的实CQ对象用类l承的方式,由Object基类定义游戏对象的公有接口及属性,包括GUID的生成及理、构造及更新UpdateData数据的虚接口、设|及获取对象属性集的方法等。然后分Z两类z对象Q一是ItemQ另一是WorldObject。Item即物品对象,WorldObject֐思义Qؓ世界对象Q即可添加到游戏世界场景中的对象Q该对象cd定义了纯虚接口,也就是不可被实例化,主要是在Object对象的基上又d了坐标设|或获取的相x口?/p> <p>  Itemcd又派兵出了一cBag对象Q这是一U特D的物品对象Q其本nh物品的所有属性及ҎQ但又可作ؓ新的容器cdQƈh自己Ҏ的属性和ҎQ所以实C采用了派生。mangos在实现时对Bag的类型定义做了点技巧,Item的类型ؓ2QBag的类型ؓ6Q这样在通过位的方式来表C类型时QBagcd也就同时属于Itemcd了。虽然只是很的一个技巧,但在很多地方却带来了极大的便利?/p> <p>  从WorldObjectz出的cd有好几U了QUnit、GameObject、DynamicObject和Corpse。Unit为所有生物类型的基类Q同WorldObject一P也不可被实例化。它定义了生物类型的公有属性,如种族、职业、性别、生命、魔法等Q另外还提供了相关的一些操作接口。游戏中实际的生物对象类型ؓCreatureQ从UnitzQ另外还有一cL生对象Player为玩家对象。Player与Creature在实C最大的区别是玩家的操作由客L发来的消息驱动,而Creature的控制是p己定义的AI对象来驱动,另外Player内部q包括了很多的逻辑pȝ实现?/p> <p>  另外q有两类Ҏ的CreatureQPet和TotemQ其对象cd仍然q是生物c,只是实现上与会有些特D的东西需要处理,所以在mangos中将其作为独立的zc,只是实现上的一点处理。另外在GameObject中也实现有派生对象,最l的l承关系图比较简单,׃ȝ地去d了?/p> <p>  从我所了解的早期游戏实现来看,大部分的游戏对象l构都是采用的类DU方式。可能与早期寚w向对象的理解有关Q当面向对象的概念刚出来Ӟ大家认ؓl承是面向对象的全部,所以处处皆对象Q处处皆l承?/p> <p>  cd现的是一U封装,虽然从云风那里出来的弃C++而{投C的声韛_能会影响一部分人,但是Q用什么语a本n是个h喜好及团队整体情况决定的。我们所要的也是最l的实现l果Q至于中间的步骤Q完全看个h。还是用云风的话_q只是一U信仰问题,我依焉用我所熟悉的C++Q下面的描述也是如此?/p> <p>  随着面向对象技术的深入Q以及泛型等概念的相l提出,软gE序l构斚w的趋势也有了很大改变。C++大师们常说的话中有一句是q样说的Q尽是采用组合而不是ѝ游戏对象的实现也有cM的{变,向于以l合的方式来实现游戏对象cdQ也是实现一个通用的entitycdQ然后以脚本定义的方式组合出不同的实际游戏对象类型?/p> <p>  描述的有些抽象,具体实现下一来仔细探讨下?br><br><br>在游戏编E精_四有三文章讲C实体以及实体理的实现方案,其中一文章说C实体理pȝ的四大要素:定义实体怎样沟通的实体消息Q实C实体cM码和数据的实体代码,l护已经注册在案的实体类列表Q和用来创徏、管理、发送消息的实体理器?/p> <p>  关于实体消息的内容之前讨Z件机制的时候做q一点说明,其实q也是按接口调用和按消息驱动的区别Q现在mangos的做法是完全的接口调用,所以引擎内部就没有M的实体消息。实体代码实现和实体理器是我们重点要讨论的内容?/p> <p>  另有一文章也提到了用类l箋的方式实现游戏对象的两大问题Q一是它要求pȝ中的所有对象都必须从一个v点衍生而成Q也是说所有对象类在编译的时候已l确定,q可能是一个不受欢q的限制Q如果开发者决定添加新的对象类Q则必须要对基类有所了解Q方能支持新cR另一个问题在于所有的对象c都必须实现同样的一些底层函数?/p> <p>  对于W二个问题,可以通过接口l承的方式来避免基类的方法太多。在mangos的实C采用了cM的方法,从Object虚基cL生的Unit和WorldObject仍然q是不可实例化的c,q两U对象定义了不同的属性和ҎQ分来实C同类型的对象。在游戏内部可以Ҏ对象的实际类型来Object指针向下转型为Unit或WorldObjectQ以调用需要的接口。方法虽然不够OOQ也q能解决问题。但是第一个问题是始终无法避免的?/p> <p>  所以我们便有了通用实体q么一个概念,其主要方法是原来基cȝ接口q行分类Q分C个个不同的子cMQ然后以对象l合的方式来生成我们所需要的实际游戏对象cd。这个组合的q程可以通过脚本定义的方式,q样便可以在q行时生成ؓ同的对象cdQ也p决了上面提到的第一个问题?/p> <p>  通用实体的实现方法在目前的游戏引擎及开源代码中也可以看到媄子。一个是BigWorldQ从提供的资料来看,其引擎只提供了一个entity游戏对象Q然后由游戏内容实现者通过xml和python脚本来自由定义不同类型的entitycdQ每U类型可有不同的property和不同的Ҏ。这样原来由基类定义的接口完全{Ud脚本定义Q具有非常强的灵zL?/p> <p>  另外q有一个是CEL中的entity实现。按照CEL的描qͼentity可以是游戏中的Q意对象,包括玩家可交互的对象Q如钥匙、武器等Q也可以包括不能直接交互的对象,如游戏世界,甚至d链中的一部分{。entity本nq没有Q何特性,具体的功能实现需要靠附加property来完成。简单来_property才定义了entity可以做什么,至于该怎么做,那又是依靠behavior来定义。所以,最l在CEL中一个游戏对象其实是由entityl合了多个property及多个behavior而生成的?/p> <p>  但是CEL中的property与BigWorld中的property意义不大一P在CEL中可定义的property其实是引擎内部要先提供的Q比如其CZ中所丄pcobject.mesh、pcmove.linear、pctools.inventory{,而BigWorld中的property是完全的自由定制。从q个角度来讲Q其实可以把CEL中的property看作是游戏的逻辑pȝQ也是我们上面所描述的,接口分类后所定义的子cR?/p> <p>  由引擎内部提供可选择的property与BigWorld所采用的完全自由定制property其实本质上是相同的。在用BigWorld实现的游戏中Q也不可能ؓ每种游戏对象cd都完全从头定义propertyQ基于代码利用的原则Q也会先定义一些小c,然后在entitycd定义时以自定义property的方式来包含q些类。当Ӟ我没有用过BigWorldQ上面的描述也只是基于游戏实现的大原则所做出来的?/p> <p>  描述的依然有些抽象,我们可以用wow及mangos代码来说明一下。mangos中ؓobject定义了一个属性集合,Ҏ对象cd的不同,q个属性集的大及保存数据也会有差异,另外游戏对象内部含有处理不同游戏逻辑的系l,如RestSystem、FloodFilterSystem、VariousSystem{等Q在player.h中以接口l的方式q行定义?/p> <p>  如果要将q种l构改ؓ我们描述的通用entitypȝQ可以让object只提供property注册和删除的接口Q这里的property定义与CEL中的相同Q放在mangos中也是上面说的RestSystem、FloodFilterSystem、VariousSystemq些。然后也通过xml文g的方式定义我们所需要的游戏对象cdQ如player,creature,item{,不同的对象类型可以选择加蝲不同的propertyQ加载的原则是需要哪些功能就加蝲哪些property?/p> <p>  对象的定义按上面的方法完成后Q对象的实现也需要做一些修攏V以前客L的消息是直接交由player来处理,AI也是直接调用creature的接口来完成一些功能,现在通用的entity内部已经没有M可用的方法,所有的实现都{Cproperty中,所以需要由各个property实现自己来注册感兴趣的事件及消息Qentity实现一个消息的转发Q{l对此感兴趣的property来处理。其余的实现没有什么不同了?/p> <p>  当然Q我们再做一Ҏ展,让property不光由引擎来提供Q用脚本本n也能定义propertyQƈ且可以通过xml来注册这些propertyQ这样便实现了与BigWorld一L完全自由Ҏ。这其实也就是将很多用C++实现的功能{Ud了python中,q种做法可作为参考,但不一定对所有h合适,臛_在我看来Q这L实现也基本只能由E序员来做,所以让E序员选择自己最擅长的语a可能会更易于开发和调试?/p> <p>有关游戏对象实现的描qͼ前面两篇文章中说的不甚清楚,主要是一直都要引用网上能够找到的资料来进行描qͼ以避免与公司引v不必要的ȝ。所以语a有些拼凑的感觉,丄例子也很不恰当,今天正好看到了游戏编E精_五和六上的两篇文章Q内定w差不多,<<Zlg的对象管?gt;>?lt;<Zlg的游戏对象系l?gt;>Q说的也是我上两文章想要描q的内容Q所以再补一,引用其中的部分文字进行明的说明?/p> <p> </p> <p>  传统的游戏对象管理系l采用承的方式来实玎ͼ例如Q所有的子类都从CObjectz。大多数情况下,直接z的也是抽象类Q其中带一些功能而另一些子cd不带q些功能Q比如可控制/不可控制Q可动画/不可动画{。mangos的实C基本是q种情况Q从Object直接z的Unit和WorldObject都是不可直接实例化的cR?/p> <p>  传统Ҏ的问题在于无法应寚w求的变化Q如要求武器也有动画效果时就无法处理了。如果硬要是q样做,那随着需求的啬,很多的方法会被放到基cMQ最l的l果是承树变得来头重脚轻,q样的类会失它的内聚性,因ؓ它们试图为所有对象完成所有的事?/p> <p>  是说到最后,基类会有一个很长的接口列表Q而很多的游戏对象cdҎ不需要实现其中的一些甚臛_部分接口Q但是按照这U结构却又必d实现。以至于于实C个非常庞大的对象Q而且惌修改一点功能会Dpȝ的大调整?/p> <p>  我们希望的系l是可以现有的功能l合到新的对象中Qƈ且在新的功能添加到现有的对象中时不需要重构大量的代码和调整承树的结构?/p> <p>  实现的方法就是从lg来创Z个对象。组件是一个包含所有相x据成员和Ҏ的类Q它完成某个特定的Q务。把几个lgl合在一起就可以创徏一个新的对象。如把Entitylg、Renderlg和Collectablelgl合在一L成了一个Spoon对象。Entitylg让我们可以把对象攑ֈ游戏世界中,Renderlg让我们可以ؓ对象指定一个模型进行渲染,而Collectablelg让我们可以拾取这个对象?/p> <p>  关于lg的实玎ͼ所有的lg都从一个基lg接口zQ可U其为IComponent。每个组件也有自q接口定义Qƈ且这个接口也需要从IComponentzQ类gq样QIComponent -- ICmpRender -- CCmpRender</p> <p>  q里的每个组件也是我在上一中所说的由引擎提供的属性,或者说在BigWorld中自己实现然后定义的属性,或者用mangos中的定义Q就是一个个的SystemQ虽然mangosq没有将其完全做成组Ӟ但是通过其代码注释可以看刎ͼ接口也是按功能组q行了分c,如果要拆分成lg也是比较方便的?/p> <p>  lg之间的通信有两U方法,一是用lgID查询到组件接口指针,然后调用接口ҎQ二是用消息的方式Q向对象中所有组件发消息。在初始化的时候,每一个组件类型都会告诉对象管理器应该接收什么样的消息?/p> <p>  查询接口的方法也是直接的方法调用,只不q接口不是全部在基类中,所以必d查询到指定的lg然后才能调用其接口。消息的使用前面已经说过多次Q其实现Ҏ也有q说明?/p> <p>  最后是关于游戏对象功能的扩展和游戏对象的定义。需要扩展功能也是需要实C个新的组Ӟ或者修改现在组件。在大多数情况下Q扩展都不会引vl构的很大调_受媄响的最多只是用到该组件的部分代码?/p> <p>  游戏对象定义可采用完全数据驱动的方式Q用xml或者脚本语a来定义对象类型,以及每个cd需要加载的lg。对象类型注册到对象理器后Q由理器提供创建指定类型的对象的方法。数据驱动的方式能够让策划自由定义游戏对象类型,q且随时可自由创建新的对象类型?/p> </div> <img src ="http://www.shnenglu.com/iwangchuchu/aggbug/113341.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-23 16:06 <a href="http://www.shnenglu.com/iwangchuchu/archive/2010/04/23/113341.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转【游戏开发】MMORPG服务器架?/title><link>http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113221.html</link><dc:creator>avatar</dc:creator><author>avatar</author><pubDate>Wed, 21 Apr 2010 15:17:00 GMT</pubDate><guid>http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113221.html</guid><wfw:comment>http://www.shnenglu.com/iwangchuchu/comments/113221.html</wfw:comment><comments>http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/iwangchuchu/comments/commentRss/113221.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/iwangchuchu/services/trackbacks/113221.html</trackback:ping><description><![CDATA[<p>一个比较抽象的MMORPG服务器架构,单描q?<br>d分配服务器:游戏区唯一入口点,Ҏd服务器负载和排队情况Q分配登录玩家到指定d服务器中q行dQ?br>d服务器:处理玩家验证w䆾合法性,及游戏选游戏世界操作,控制服务器h敎ͼ<br>数据服务器:处理玩家数据dQ保存和~存的地方; <br>世界服务器:整个游戏旉的中心管理数据的服务器; <br>游戏服务器:处理玩家主逻辑的服务器Q?<br>道具服务器:处理所有直接道L关逻辑的服务器Q管理道L产生消亡Q交易,合成Q升U,{操作;<br>|关服务器:提供l玩家与游戏服务器的中{服务器,玩家一旦登录游戏,始终处于一个网x务器Q?br>聊天服务器:提供更丰富的聊天形式Q消息优化,转发?br>中心验证服务器:与登录服务器通信Q主要进行玩家n份验证,及反馈用户信息?br>中心计费服务器:充|扣费Q交易操作的处理?/p> <p><br>本文来自CSDN博客Q{载请标明出处Q?a ><u><font color=#0000ff>http://blog.csdn.net/olncy/archive/2008/12/15/3520572.aspx</font></u></a></p> <div id="z393x1l" class=tit><font color=#ff0000 size=4><strong>一个高性能MMORPG|络游戏的架构实?/strong></font></div> <div id="1l9z999" class=date> <p><a ><u><font color=#0000ff>http://hi.baidu.com/ahidef/blog/item/197a458ecc3b03f3503d9238.html</font></u></a></p> </div> <p> <table class=FCK__ShowTableBorders style="TABLE-LAYOUT: fixed"> <tbody> <tr> <td> <div id="zz9xxt3" class=cnt> <p>一、服务器l模型的选型<br>       考虑到近q来计算机硬件技术的飞速发展,物理服务器的性h比得C很大的提高,l合目需要通过服务器组l数万玩家提供高质量服务的商业要求,l过研究Ҏ数种服务器模型后Q决定采取了上图所C的服务器组模型?/p> <p> </p> <div forimg="1"><img class=blogimg src="http://hiphotos.baidu.com/ahidef/pic/item/4f3d7935f072bf91d1a2d3f6.jpg" border=0 small="0"><br> <p>二、MMORPG服务器系l架?/p> <p>       MMORPG大型|游服务器是使用高性能|络I/O模型配合消息队列q接各服务线E的一个非常稳定的高性能|游pȝ。其中消息队列系Z׃n内存自行开发完成。在单服务器标准工作环境下进行测试,一台双 XEON 服务器可以非常轻村֜辑ֈ?,500用户每秒处理5,000hQ每U处理请求数可超q?25,000?/p> <div forimg="1"> <p><img class=blogimg src="http://hiphotos.baidu.com/ahidef/pic/item/41baad303fa6be3feac4aff1.jpg" border=0 small="0"></p> <p>三、MMORPG的实?/p> <p>       首先Q在基础斚wQ与规划现实中的城市一P得先搭徏起一pd的房屋、道路及出口、管U和诸多NPC人物{构成的基本要素和活动空_通过在服务器?Server side)取得预先设计好的l合地理、NPC人物、技能等一pd的初始化数字数据(具体文档片段误附gA.地图数据文gCZ和附件B.司机 NPC 数据文gCZ)Q然后依靠程序将数字数据和游戏逻辑有机地协调v来,最lŞ成一套完整的虚拟游戏基础I间?/p> <p> </p> <p>       在确定了地图数据生成规则后,可以用编辑器L~辑游戏场景。依赖于q样良好的基设施Q才能在其他游戏逻辑的配合下实现完整的故事情节。同时服务器端负责将属于用户各自的游戏逻辑数据通过验证后发送到合法的用户客L机器里,完成客户端游戏逻辑的徏立和数据同步。担负服务器与客L通讯的是自定义格式的数据通讯包Q它像数字经般诏I着整个游戏的始l。数据封包与如下4部分消息有关Q它们分别ؓ场景消息, 同步消息Q主角消息和界面消息?/p> <p>   </p> <p>       A.主角消息包括客户端所控制的角色的所有动作,包括走\Q聊天、交易、战斗等?br>   </p> <p>       B.场景消息包括昼夜兴替、气候变化,一定的旉在场景里出现某些东西{,q类消息h的特Ҏ所有消息的发v者都是服务器Q广播对象则是场景里的所有玩家?br>   </p> <p>       C.同步消息是针对发起对象是某个玩家Q经q服务器q播l所有看得见他的玩家Q该消息也包括所有的动作Q该U消息是服务器广播给客户端的Q主角消息则一般是客户端主动发l服务器端?br>   </p> <p>       D.界面消息是服务器发给客户端的聊天消息和各U属性及状态变化的信息?/p> <p> </p> <p>       值得一谈的q有处于|络游戏中比较重要的服务器同客户端消息广播和同步问题。其中一U方法是采取在国际上被称?Mutual synchronizationQ相互同步)Q是一U对未来|络的前景的良好预测出来的解x案来解决保每个玩家在各自客L上看到的东西大体是一L同步问题?/p> <p> </p> <p>       首先客户端需要在d游戏的时候徏立很多张q播列表Q这些列表在客户端后台和服务器端要保持不定时同步。其中要建立多张列表Q是因ؓ要广播的cd包括全局信息、本C息和q程信息{等Q这些列表都是在客户端登陆的时候根据服务器发过来的消息建立好的。在建立列表的同Ӟq需要获得每个列表中q播对象的传输时_q且要维护一张完整的用户状态列表在后台Q也是进行不定时的和服务器进行同步,Ҏ本地的用L态表Q可以一部分决策由客L来决定,当客L发送这部分决策的时候,则直接将最l决{发送到各个q播列表里面的客LQƈ对其旉q行校对Q以保证每个客户端在收到的消息的旉是和本地旉q行校对q的Q再采用预测补偿计算提前量的ҎQ计出提前量,Ҏ计算量确定实际行走速度Q将会同步变得非常的^滑?/p> <p> </p> <p>       其中Q广播的重点在于如何计出q播的对象,首先在服务器端的q接l构里面增加一个广播对象的队列Q该队列在客L登陆服务器的时候由服务器传输给合法的客LQ然后由客户端自己来l护q个队列Q当有h走出客户端视野的时候,由客Ld要求服务器给那个对象发送消q消息?/p> <p> </p> <p>       当有q视野的情况Q则先需要客L在每ơ给服务器发送更C|的消息的时候,服务器都l该q接出一个视野范_然后在需要广播的时候,循环整张地图上的玩家Q找到坐标在其视野范围内的玩家从而完成广播的全过E?/p> <p> </p> <p>       其次是虚拟对象系l。其中主要会涉及到NPC的概念,其是广泛应用的A Star法{在提供NPC的h工智能决{方面有着重要的作用。NPC使用一U是被动触发事g和是d触发事g的方式由计算机来实现对NPC做何U决{。A Star法是典型的启发式搜烦的应用,其普通原理是先设计一个Rule() 函数Q来莯一个点的代P然后每次搜烦的时候把下一步可能到辄所有点都经qRule() 函数评h一下,获取两到三个代h比较的点,l箋搜烦Q直臛_Ch的一个点。最明显的应用是NPC在实现自动选择d目标和逃跑时的实现。实现自动选择d目标Ӟ首先获得地图上距该NPC附近的敌人列表,设计相应Rule() 函数Q根据敌人的强弱、远q,判断出几个评估数据,然后选择代h最的敌hq行dd。逃跑则是在主动事仉面检查自qHPQ如果HP低于某个|而敌人正q战d的时候,则触发逃跑函数Q在逃跑函数里面也是对周围的所有的敌hl织成列表,然后设计Rule() 函数Q先分析选择出对你构成威胁最大的敌hQ该函数q需要判断敌人的q动速度Q战斗力强弱Q最后得Z个主要敌人,然后针对该主要敌行\径的Rule() 的函数的设计Q搜索的范围只可能是和主要敌人相反的方向Q然后再Ҏ该几个方向上的敌人的强弱来计代P做出最后的选择Q如果幸q的话,可以?0%的机率逃往没有 NPC L的邻q地图中厅R?/p> <p> </p> <p>       最后,׃脚本是RPG游戏的灵,自然脚本~译器就扮演了十分重要的C。在Z~译的服务器端程序中Q是无法在程序的q行q程中构Z些东西的Q所以必通过脚本~译器提供一些简单的语法和文法解析的功能Q进行一pd的逻辑判断和@环,以提高服务器端的灉|E度。可使用cM汇编语言的那U结构来实现脚本~译器,讄一些条件蟩转和循环来实现逻辑判断和@环。提供一些通用指oQ如判断、@环、四则运、寻址{等Q针对不同的脚本采用不同的解析方法,对NPCqNPC固定的脚本,对ItemqItem固定的脚本,解析完以后就把结果生成底层该对象的结构便于用?/p> <p> </p> <p>       l过以上的徏设步骤,一个完整的MMORPG|络游戏pȝp逐步建立h了?/p> <p>ZZ <a class=ln ><u><font color=#0000ff>MDNA|络游戏整体架构~程</font></u></a></p> </div> </div> </div> </td> </tr> </tbody> </table> </p> <img src ="http://www.shnenglu.com/iwangchuchu/aggbug/113221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/iwangchuchu/" target="_blank">avatar</a> 2010-04-21 23:17 <a href="http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【游戏开发】LuaForWindows 环境配置http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113219.htmlavataravatarWed, 21 Apr 2010 15:15:00 GMThttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113219.htmlhttp://www.shnenglu.com/iwangchuchu/comments/113219.htmlhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113219.html#Feedback0http://www.shnenglu.com/iwangchuchu/comments/commentRss/113219.htmlhttp://www.shnenglu.com/iwangchuchu/services/trackbacks/113219.htmlLuaForWindows 环境配置

from: http://bbs.luaer.cn/read-Lua-tid-233.html


环境Qlua for windows (lfW)
主页Q?a >http://luaforwindows.luaforge.net/

lua for windows其实是一整套Lua的开发环境,它包括:
Lua InterpreterQLua解释器)
Lua Reference ManualQLua参考手册)
Quick Lua Tour QLua快速入门)
Examples QLua范例Q?br>Libraries with documentation Q一些Lua库和文档Q?br>SciTE Q一个很的多用途编辑器Q已l对Lua做了Ҏ讄Q?/p>

其它详细的内容请到luaforge的主上查看?/p>

之所以推荐这套环境是因ؓ它整合了在windows学习和开发Lua所需要的所有东?/p>

Q对于新手来说是非常体脓的,附带的SciTE只要l过单配|就能够很方便的~?/p>

写LuaE序Q编译,q行Q调试。它q是附带自动提示和代码自动补全功能的哦,

对于用惯VC + VA的开发h员来_实在是太亲切了?/p>

下面介绍一下整个lfWQ?br>下蝲lfwQ最新的版本?.1.3.13Q直接安装,注意最后一步会询问SciTE~辑?/p>

是否使用“黑色”风格Q我比较喜欢黑色底色Q所以在q里打钩Q之后l?br>安装完成后,学习Lua所需要的一切环境就全部安装完毕Q十分简单?/p>

下面可以试是否安装成功
打开SciTEQ新Z个文Ӟ输入一行lua代码Q?/p>

print("hello,lua")

然后保存为hello.luaQ注意保存文件时要加文g名后~.luaQ否则可能不能正?/p>

的运行?br>按F5Q如果SciTE的输出窗口出?br>>lua -e "io.stdout:setvbuf 'no'" "hello.lua"
hello,lua
>Exit code: 0
字样则代表整个lua开发环境安装成功?/p>

如果对SciTE默认的配色方案或者字体不满意Q点凅ROptions】菜单中的【Open

Global Options File】,则可以看到SciTE环境的全局配置文g。里面可以修?/p>

的包括字体,颜色Q窗口布局{等Q修改相应的值即可。如果找不到自己惌?/p>

改的目Q可以再到【Options】的【Open black.properties】(如果使用的是

白色背景Q这里则是white.propertiesQ文件中查找Q这里存储的是更加细致的

属性配|。修改这两个文gQ基本上p够满_部分学习或是开发者的个h?/p>

好。还有一点,在Global Options File中,查找command.help.*.luaQ后面对?/p>

的是在编辑器中按下F1键弹出的chm格式的lua手册文g路径Q这里需要修改一?/p>

Q把文g路径Ҏ就可以了(5.1.3版本g没这个问题了Q?/p>

整个环境q附带一个QuickLuaTourQ是一个用Lua写的一个基于控制台的小教程Q?/p>

很易于理解?/p>

基本上整个环境就是这P之后可以开始学习Lua了?/p>

avatar 2010-04-21 23:15 发表评论
]]>
【推荐】强大的代码阅读工具Understandhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113218.htmlavataravatarWed, 21 Apr 2010 15:14:00 GMThttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113218.htmlhttp://www.shnenglu.com/iwangchuchu/comments/113218.htmlhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113218.html#Feedback0http://www.shnenglu.com/iwangchuchu/comments/commentRss/113218.htmlhttp://www.shnenglu.com/iwangchuchu/services/trackbacks/113218.html【推荐】强大的代码阅读工具Understand
4 个附?/div>
_http://www.scitools.com/products/understand/

Understand软g的功能主要定位于代码的阅ȝ解。界面貌似是用Qt开发的?br>
具备如下Ҏ:
1、支持多语言QAda, C, C++, C#, Java, FORTRAN, Delphi, Jovial, and PL/M Q؜合语a的project也支?br>2、多q_Q?Windows/Linux/Solaris/HP-UX/IRIX/MAC OS X
3?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">代码语法高亮?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">代码折叠、交叉蟩转、书{基本阅读功能?br>4、可以对整个project的architecture、metricsq行分析q输出报表?br>5、可以对代码生成多种图(butterfly graph、call graph、called by graph、control flow graph、UML class graph{)Q在图上点击节点可以跌{到对应的?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">代码位置?br>6、提供Perl API便于扩展。作囑օ部是用Perl插g实现的,直接d分析好的数据库作图?br>7、内|的目录和文件比较器?br>8、支持project的snapshotQƈ能和自家的TrackBack集成便于监视project的变化?br>
技巧(官网的FAQ里有Q:

1、设|字体和颜色风格

修改默认字体QTools -> Options -> Editor -> Default style
修改颜色Q?Tools -> Options -> Editor -> Styles

2、生成UMLcd、调用树?br>
默认安装的插件不支持q两U图Q需要从官网下蝲插g?br>_http://www.scitools.com/perl_scripts/uperl/uml_class.upl
_http://www.scitools.com/perl_scripts/uperl/invocation.upl
攑ֈsti/conf/scripts/local目录下?br>然后重新q行Q执?project-> project graphical views -> xxxx可以生成q两U图?br>
3、更改图的字?br>
直接修改对应的脚本文Ӟ\Program Files\STI\conf\scripts目录下)Q在do_load( )函数的对应位|加入如下的讄Q?br>
$graph->default("fontname","Consolas","node");
$graph->default("fontsize","10","node");
$graph->default("fontname","Consolas","edge");
$graph->default("fontsize","10","edge");

注意Q有的脚本中的作囑֏量名不是 $graph 而是 $g?br>
另外一?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">代码可视化理?strong style="COLOR: black; BACKGROUND-COLOR: #99ff99">工具Q?http://www.sgvsarc.com/prod_crystalrevs_screenshots.htm


avatar 2010-04-21 23:14 发表评论
]]>转【游戏开发】利用CEGUI+Lua实现灉|的游戏UI框架http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113217.htmlavataravatarWed, 21 Apr 2010 15:13:00 GMThttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113217.htmlhttp://www.shnenglu.com/iwangchuchu/comments/113217.htmlhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113217.html#Feedback0http://www.shnenglu.com/iwangchuchu/comments/commentRss/113217.htmlhttp://www.shnenglu.com/iwangchuchu/services/trackbacks/113217.html

利用CEGUI+Lua实现灉|的游戏UI框架

      在上一文章中Q介l了一U基于组件方式的游戏UI架构设计ҎQ在q里Q笔者将介绍如何利用CEGUI和Lua来实现这U灵zȝ框架?/p>

       CEGUI是一个兼容OpenGL、DirectX的优U开源GUI库,关于她的介绍以及如何在Direct3D中用她Q可以参?a >http://blog.csdn.net/Lodger007/archive/2007/07/02/1675141.aspx一文。Lua是一U强大的脚本语言Q她使用栈作为数据接口,能够很容易地与其它语a交互Q关于她的介l可以参?a >http://www.lua.org/Q以及笔者以前翻译的三篇pd文章QLua入门Q?a >http://blog.csdn.net/Lodger007/archive/2006/06/26/836466.aspxQ、调用Lua函数Q?a >http://blog.csdn.net/Lodger007/archive/2006/06/26/836897.aspxQ、在Lua中调用C++函数Q?a >http://blog.csdn.net/Lodger007/archive/2006/06/26/837349.aspxQ?/div>
       在实CQ作为UIlg理器的GUISystem是一个单Ӟq样Q你能够很方便地在Q何地方用其全局唯一的对象。下面是Singleton和GUISystem的实C码:


avatar 2010-04-21 23:13 发表评论
]]>[转]c++调用lua脚本1Q^台windowsQ?http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113193.htmlavataravatarWed, 21 Apr 2010 15:00:00 GMThttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113193.htmlhttp://www.shnenglu.com/iwangchuchu/comments/113193.htmlhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113193.html#Feedback0http://www.shnenglu.com/iwangchuchu/comments/commentRss/113193.htmlhttp://www.shnenglu.com/iwangchuchu/services/trackbacks/113193.html    环境VC++6.0
    lua  sdk 5.1


   在调用前 先认识几个函数?br>1Q?调用lua_open()创Z个指向Lua解释器的指针?
2Q?luaL_openlibs()函数加蝲Lua库?
3Q?使用luaL_dofile()加蝲脚本q运行脚本?
4Q?lua_close()来关闭Lua指向解释器的指针?br> 
5Q?调用lua_getglobal()add()函数压入栈顶Qadd()为lua函数?br>6Q?W一个参数xQ通过调用lua_pushnumber()入栈?br>7Q?再次调用lua_pushnumber()第二个参数入栈?br>8Q?使用lua_call()调用Lua函数?br>9Q?调用lua_tonumber()从栈取得函数的q回倹{?br>10Q?lua_pop()U除栈顶的倹{?br>

代码
add.lua
1function add ( x, y )
2    return x + y
3end
4

main.cpp
#include <stdio.h>

extern "C" {
#include 
"lua.h"
#include 
"lualib.h"
#include 
"lauxlib.h"
}


/* the Lua interpreter */
lua_State  
* L;

int luaadd ( int x, int y )
{
    
int sum;
    
    
//函数?/span>
    lua_getglobal(L, "add");
    
    
//W一个参数压?/span>
    lua_pushnumber(L, x);
    
    
//W二个参数压?/span>
    lua_pushnumber(L, y);

    
//调用函数
    lua_call(L, 21);
    
    
//得到q回?/span>
    sum = (int)lua_tonumber(L, -1);
    lua_pop(L, 
1);
    
    
return sum;
}


int main ( int argc, char *argv[] )
{
    
int sum;
    
    
//创徏一个指向Lua解释器的指针?/span>
    L = lua_open();
    
    
//函数加蝲Lua?/span>
    luaL_openlibs(L);

    
//加蝲脚本
    luaL_dofile(L,"add.lua");
    
    
//调用函数
    sum = luaadd( 1011);
    
    
// print the result 
    printf( "The sum is %d\n", sum );
    
    
//关闭 释放资源    
    lua_close(L);
    
    
return 0;
}



注意问题Q?br>1.工程头文件lua.h{,~译器能扑ֈQ可以通过工具来设|头文g路径?br>2. dlua5.1.lib到Object/library modules列表中?

试l果
The sum is 21

关于lua的认?br>http://www.shnenglu.com/expter/archive/2008/12/24/70224.html

avatar 2010-04-21 23:00 发表评论
]]>
转经典塔防游戏TowersTrap-[lua复刻版本,附全部lua源代码]http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113192.htmlavataravatarWed, 21 Apr 2010 14:57:00 GMThttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113192.htmlhttp://www.shnenglu.com/iwangchuchu/comments/113192.htmlhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113192.html#Feedback10http://www.shnenglu.com/iwangchuchu/comments/commentRss/113192.htmlhttp://www.shnenglu.com/iwangchuchu/services/trackbacks/113192.html囄Q?
Click Here To EnLarge
l典塔防游戏TowersTrap

q是个很l典的塔防游戏,非常耐玩Q?喜欢的朋友可以试试?

游戏介绍Q?玩过兽的朋友应该对q个不陌生了Q游戏中只有一个出口,游戏有多个难度选择Q玩家必d"?到达出口之前消灭它们?br>
操作介绍Q先定塔的cdQ然后在图中L位置放下。点d建造的塔后塔的上下会出现数字,分别是升U和出售的h钱,升塔也很重要哦~


安装说明Q?
1.下蝲安装游戏引擎love2d
http://www.love2d.org/download
2.下蝲游戏文g
http://219.136.249.30/svn_readonly/towerstrap/dist/towerstrap.love

3.游戏下蝲CQ意目录后(注意,love2d引擎不支持中文目?,双击towerstrap.love文g可以开始游戏了

源代码:
svn:
http://219.136.249.30/svn_readonly/towerstrap/
交流请加qq?阿兜明@83086500


avatar 2010-04-21 22:57 发表评论
]]>
Lua脚本语法说明Q修订)http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113190.htmlavataravatarWed, 21 Apr 2010 14:55:00 GMThttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113190.htmlhttp://www.shnenglu.com/iwangchuchu/comments/113190.htmlhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113190.html#Feedback0http://www.shnenglu.com/iwangchuchu/comments/commentRss/113190.htmlhttp://www.shnenglu.com/iwangchuchu/services/trackbacks/113190.html
  Lua 的语法比较简单,学习h也比较省力,但功能却q不弱?br>  所以,我只单的归纳一下Lua的一些语法规则,使用h方便好查可以了。估计看完了Q就懂得怎么写LuaE序了?br>
  在Lua中,一切都是变量,除了关键字?br>
I.  首先是注?br>  写一个程序,L不了注释的?br>  在Lua中,你可以用单行注释和多行注释?br>  单行注释中,q箋两个减号"--"表示注释的开始,一直gl到行末为止。相当于C++语言中的"http://"?br>  多行注释中,?--[["表示注释开始,q且一直gl到"]]"为止。这U注释相当于C语言中的"/*...*/"。在注释当中Q?[["?]]"是可以嵌套的Q?span style="COLOR: red">在lua5.1中,中括号中间是可以加若q个"="LQ如 [==[ ... ]==]Q,见下面的字符串表C明?br>
II.  Lua~程
  l典?Hello world"的程序L被用来开始介l一U语a。在Lua中,写一个这LE序很简单:
  print("Hello world")
  在Lua中,语句之间可以用分?Q?隔开Q也可以用空白隔开。一般来_如果多个语句写在同一行的话,L用分号隔开?br>  Lua 有好几种E序控制语句Q如Q?br>
控制语句 格式 CZ
If if 条g then ... elseif 条g then ... else ... end
if 1+1=2 then print("true")
elseif 1+2~=3 then print("true")
else print("false"end

While while 条g do ... end
while 1+1~=2 do print("true"end

Repeat repeat ... until 条g
repeat print("Hello"until 1+1~=2

For for 变量=初? l点? 步进 do ... end
for i = 1102 do print(i) end

For for 变量1, 变量2, ... 变量n in 表或枚D函数 do ... end
for a,b in mylist do print(a, b) end


  注意一下,for的@环变量L只作用于for的局部变量;当省略步q值时Qfor循环会?作ؓ步进倹{?br>  使用break可以用来中止一个@环?br>  相对C语言来说QLua有几个地Ҏ明显不同的,所以面要特别注意一下:

  Q?strong>语句?/strong>
    语句块在C中是?{"?}"括v来的Q在Lua中,它是用do ?end 括v来的。比如:
    do print("Hello") end
    可以?函数 中和 语句?/strong> 中定局部变量?br>
  Q?strong>赋D?/strong>
    赋D句在Lua被强化了。它可以同时l多个变量赋倹{?br>    例如Q?br>    a,b,c,d=1,2,3,4
    甚至是:
    a,b=b,a  -- 多么方便的交换变量功能啊?br>    在默认情况下Q变量L认ؓ是全局的。假如需要定义局部变量,则在W一ơ赋值的时候,需要用local说明。比如:
    local a,b,c = 1,2,3  -- a,b,c都是局部变?br>
  Q?strong>数D?/strong>
    和C语言一P支持 +, -, *, /。但Luaq多了一?^"。这表示指数乘方q算。比?^3 l果?, 2^4l果?6?br>    q接两个字符Ԍ可以?.."q处W。如Q?br>    "This a " .. "string." -- {于 "this a string"

  Q?strong>比较q算
比较W号 < > <= >= == ~=
含义 大于 于或等?/td> 大于或等?/td> 相等 不相{?/td>

    所有这些操作符Lq回true或false?br>    对于TableQFunction和Userdatacd的数据,只有 == ?~=可以用。相{表CZ个变量引用的是同一个数据。比如:
    a={1,2}
    b
=a
    
print(a==b, a~=b)  --输出 true, false
    a={1,2}
    b
={1,2}
    
print(a==b, a~=b)  --输出 false, true


  Q逻辑q算
    and, or, not
    其中Qand ?or 与C语言区别特别大?br>    在这里,请先CQ在Lua中,只有false和nil才计ؓfalseQ其它Q何数据都计算为trueQ?也是trueQ?br>    and ?or的运结果不是true和falseQ而是和它的两个操作数相关?br>    a and bQ如果a为falseQ则q回aQ否则返回b
    a or bQ如?a 为trueQ则q回aQ否则返回b

    丑և个例子:
     print(4 and 5--输出 5
     print(nil and 13--输出 nil
     print(false and 13--输出 false
     print(4 or 5--输出 4
     print(false or 5--输出 5

    在Lua中这是很有用的特性,也是比较令hh的特性?br>    我们可以模拟C语言中的语句Qx = a? b : cQ在Lua中,可以写成Qx = a and b or c?br>    最有用的语句是Q?x = x or vQ它相当于:if not x then x = v end ?br>
  Q运符优先U,从低到高序如下Q?br>
     or
     and
     <     >     <=    >=    ~=    ==
     .. (字符串连?
     +     -
     *     /     %
     not   #(lua5.1 取长度运?/span>)     - (一元运?
     ^
和C语言一P括号可以改变优先U?br>
III.  关键?br>  关键字是不能做ؓ变量的。Lua的关键字不多Q就以下几个Q?br>    
and break do else elseif
end false for function if
in local nil not or
repeat return then true until while

IV.  变量cd
  怎么定一个变量是什么类型的呢?大家可以用type()函数来检查。Lua支持的类型有以下几种Q?br>
Nil I|所有没有用过的变量,都是nil。nil既是|又是cd?/td>
Boolean 布尔|只有两个有效|true和false
Number 数|在Lua里,数值相当于C语言的double
String 字符Ԍ如果你愿意的话,字符串是可以包含"\0"字符的(q和C语言L?\0"l尾是不一LQ?/td>
Table 关系表类型,q个cd功能比较强大Q请参考后面的内容?/td>
Function 函数cdQ不要怀疑,函数也是一U类型,也就是说Q所有的函数Q它本n是一个变量?/td>
Userdata 嗯,q个cd专门用来和Lua的宿L交道的。宿主通常是用C和C++来编写的Q在q种情况下,Userdata可以是宿ȝL数据cdQ常用的有Struct和指针?/td>
Thread U程cdQ在Lua中没有真正的U程。Lua中可以将一个函数分成几部䆾q行?/span>如果感兴的话,可以ȝ看Lua的文档?br>现在回过头来看看Q倒觉得不是线E类型。反而象是用来做遍历的,象是Iterator函数?br>如:
function range(n)
  local
= 0
  
while(i < n) do
    coroutine.yield( i )
    i = i + 1
  
end
end
可惜的是要l运行,需要coroutine.resume函数Q有炚w肋。请指教?br>

V.  变量的定?br>  所有的语言Q都要用到变量。在Lua中,不管在什么地方用变量,都不需要声明,q且所有的q些变量L全局变量Q除非我们在前面加上"local"。这一点要特别注意Q因为我们可能想在函数里使用局部变量,却忘了用local来说明?br>  至于变量名字Q它是大写相关的。也是_A和a是两个不同的变量?br>  定义一个变量的Ҏ是赋倹{?Q?操作是用来赋值的
  我们一h定义几种常用cd的变量吧?br>  A.  Nil
    正如前面所说的Q没有用过的变量的|都是Nil。有时候我们也需要将一个变量清除,q时候,我们可以直接l变量赋以nil倹{如Q?br>
    var1=nil  -- h?nbsp;nil 一定要写

  B.  Boolean
    布尔值通常是用在进行条件判断的时候。布值有两种Qtrue ?false。在Lua中,只有false和nil才被计算为falseQ而所有Q何其它类型的|都是true。比?Q空串等{,都是true。不要被 C语言的习惯所误导Q?在Lua中的的确是true。你也可以直接给一个变量赋以Booleancd的|如:
    theBoolean = true

  C.  Number
    在Lua中,是没有整数类型的Q也不需要。一般情况下Q只要数g是很大(比如不超q?00,000,000,000,000Q,是不会生舍入误差的。在WindowsXP能跑的当今主PC上,实数的运ƈ不比整数慢?br>    实数的表C方法,同C语言cMQ如Q?br>    4 0.4 4.57e-3 0.3e12 5e+20

  D.  String
    字符ԌL一U非常常用的高cd。在Lua中,我们可以非常方便的定义很长很长的字符丌Ӏ?br>    字符串在Lua中有几种Ҏ来表C,最通用的方法,是用双引h单引h括v一个字W串的,如:
    "That's go!"
    ?br>    'Hello world!'

    和C语言相同的,它支持一些{义字W,列表如下Q?br>    \a  bell
    \b  back space
    \f  form feed
    \n  newline
    \r  carriage return
    \t  horizontal tab
    \v  vertical tab
    \\  backslash
    \"  double quote
    \"  single quote
    \[  left square bracket
    \]  right square bracket

    ׃q种字符串只能写在一行中Q因此,不可避免的要用到转义字符。加入了转义字符的串Q看h实在是不敢恭l_比如Q?br>    "one line\nnext line\n\"in quotes\", "in quotes""
    一大堆?\"W号让h看v来很倒胃口。如果你与我有同感,那么Q我们在Lua中,可以用另一U表C方法:?[["?]]"多行的字符串括h。(lua5.1: 中括号中间可以加入若q个"="P?[==[ ... ]==]Q详见下面示?/span>Q?br>    CZQ下面的语句所表示的是完全相同的字W串Q?br>
= 'alo\n123"'
= "alo\n123\""
= '\97lo\10\04923"'
= [[alo
123"
]]
= [==[
alo
123"
]==]

    值得注意的是Q在q种字符串中Q如果含有单独用的"[["?]]"׃然得?\["?\]"来避免歧义。当Ӟq种情况是极会发生的?br>
  E.  Table
    关系表类型,q是一个很强大的类型。我们可以把q个cd看作是一个数l。只是C语言的数l,只能用正整数来作索引Q在Lua中,你可以用Lcd来作数组的烦引,除了nil。同P在C语言中,数组的内容只允许一U类型;在Lua中,你也可以用Q意类型的值来作数l的内容Q除了nil?br>    Table的定义很单,它的主要特征是用"{"?}"来括起一pd数据元素的。比如:
    T1 = {}  -- 定义一个空?/span>
    T1[1]=10  -- 然后我们可以象C语言一h使用它了?/span>

    T1["John"]={Age=27, Gender="Male"}
    q一句相当于Q?br>    T1
["John"]={}  -- 必须先定义成一个表Q还记得未定义的变量是nilcd?/span>
    T1["John"]["Age"]=27
    T1
["John"]["Gender"]="Male"
    当表的烦引是字符串的时候,我们可以写成Q?br>    T1.John
={}
    T1.John.Age
=27
    T1.John.Gender
="Male"
    ?br>    T1.John{Age
=27, Gender="Male"}
q是一个很强的Ҏ?br>
    在定义表的时候,我们可以把所有的数据内容一起写?{"?}"之间Q这样子是非常方便,而且很好看。比如,前面的T1的定义,我们可以q么写:
    T1=
    {
      
10,  -- 相当?nbsp;[1] = 10
      [100] = 40,
      John
=  -- 如果你原意,你还可以写成Q["John"] =
      {
        Age
=27,   -- 如果你原意,你还可以写成Q["Age"] =27
        Gender=Male   -- 如果你原意,你还可以写成Q["Gender"] =Male
      },
      
20  -- 相当?nbsp;[2] = 20
    }

    看v来很漂亮Q不是吗Q我们在写的时候,需要注意三点:
    W一Q所有元素之_L用逗号"Q?隔开Q?br>    W二Q所有烦引值都需要用"["?]"括v来;如果是字W串Q还可以L引号和中括号Q?br>    W三Q如果不写烦引,则烦引就会被认ؓ是数字,q按序自动?往后编Q?br>
    表类型的构造是如此的方便,以致于常常被人用来代曉K|文件。是的,不用怀疑,它比ini文g要漂亮,q且强大的多?br>
  F.  Function
    函数Q在Lua中,函数的定义也很简单。典型的定义如下Q?br>
    function add(a,b)  -- add 是函数名字,a和b是参数名?/span>
     return a+b  -- return 用来q回函数的运行结?/span>
    end

    h意,return语言一定要写在end之前。假如我们非要在中间放上一句returnQ那么就应该要写成:do return end?br>    q记得前面说q,函数也是变量cd吗?上面的函数定义,其实相当于:
    add = function (a,b) return a+end
当重新给add赋值时Q它׃再表C个函C。我们甚臛_以赋laddL数据Q包括nil Q这P赋gؓnilQ将会把该变量清除)。Function是不是很象C语言的函数指针呢Q?br>
    和C语言一PLua的函数可以接受可变参C敎ͼ它同h?..."来定义的Q比如:
    function sum (a,b,)
如果惛_?..所代表的参敎ͼ可以在函C讉Karg局部变量(表类型)得到 (lua5.1: 取消argQƈ直接?..."来代表可变参CQ本质还是arg)?br>    ?sum(1,2,3,4)
    则,在函CQa = 1, b = 2, arg = {3, 4}  (lua5.1:  a = 1, b = 2, ... = {3, 4})
    更可늚是,它可以同时返回多个结果,比如Q?br>
    function s()
      
return 1,2,3,4
    
end
    a,b,c,d 
= s()  -- 此时Qa = 1, b = 2, c = 3, d = 4

    前面说过Q表cd可以拥有Lcd的|包括函数Q因此,有一个很强大的特性是Q拥有函数的表,哦,我想更恰当的应该说是对象吧。Lua可以使用面向对象~程了。不信?举例如下Q?br>
    t =
    {
     Age 
= 27
     
add = function(self, n) self.Age = self.Age+end
    }
    
print(t.Age)  -- 27
    t.add(t, 10)
    
print(t.Age)  -- 37

    不过Qt.add(t,10) q一句实在是有点土对吧?没关p,在Lua中,我们可以写成Q?br>
    t:add(10)    -- 相当?nbsp;t.add(t,10)

  G.  Userdata ?Thread
    q两个类型的话题Q超Z本文的内容,׃打算l说了?br>
VI.  l束?br>  p么结束了吗?当然不是Q接下来Q我们需要用Lua解释器,来帮助理解和实践了。相信这样会更快的对Lua上手了?br>  pC语言一PLua提供了相当多的标准函数来增强语言的功能。用这些标准函敎ͼ可以很方便的操作各种数据cdQƈ处理输入输出。有兌斚w的信息,我们可以参考《Programming in Lua 》一书,也可以在|络上直接观看电子版Q网址为:http://www.lua.org/pil/index.html
  
备注Q本文的部䆾内容摘、译自lua随机文档?br>相关链接Q?br>1. Lua 官方|站Q?http://www.lua.org
2. Lua Wiki|站Q你可以在这里找到很多相关的资料Q如文档、教E、扩展,以及C/C++的包装等Q?http://lua-users.org/wiki/
3. Lua 打包下蝲Q包括各U^台和~译器的工程文g如vs2003,vs2005Q:http://luabinaries.luaforge.net/download.html

q是我编译好的Lua5.02的解释器Q?a >http://files.cnblogs.com/ly4cn/lua.zip


avatar 2010-04-21 22:55 发表评论
]]>
Lua 脚本 C++ 装?LuaWrapper http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113186.htmlavataravatarWed, 21 Apr 2010 14:46:00 GMThttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113186.htmlhttp://www.shnenglu.com/iwangchuchu/comments/113186.htmlhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113186.html#Feedback0http://www.shnenglu.com/iwangchuchu/comments/commentRss/113186.htmlhttp://www.shnenglu.com/iwangchuchu/services/trackbacks/113186.html

转蝲Q?http://www.d2-life.com/LBS/blogview.asp?logID=41

  使用Lua作脚本,主要是因为它y玲珑Q体U小Q运行快Q,而且它的语法又比较简单明了。不q,使用LuaAPILua引擎集成到程序中Q确实有一些不方便——用落木随风|友的话来说Q就?p用汇~?。当Ӟ现在你不用再q么辛苦了,因ؓ你可以用LuaWrapper For C++。用这个工P在C++中集成Lua脚本是轻而易丄事。你原有的C++函数和类Q几乎不需要Q何改变,可以与Lua脚本׃n?br>

作者: 沐枫 Q第二h生成员)
版权所有{载请注明原出?br>主页Q第二h?http://www.d2-life.com
   http://www.d2-life.com/LBS/blogview.asp?logID=41

Z么要用Lua作脚本?
  使用Lua作脚本,主要是因为它y玲珑Q体U小Q运行快Q,而且它的语法又比较简单明了。不q,使用LuaAPILua引擎集成到程序中Q确实有一些不方便——用落木随风|友的话来说Q就?p用汇~?。当Ӟ现在你不用再q么辛苦了,因ؓ你可以用LuaWrapper For C++。用这个工P在C++中集成Lua脚本是轻而易丄事。你原有的C++函数和类Q几乎不需要Q何改变,可以与Lua脚本׃n?br>  我们接下来,用实例来说明Q如何用LuaWrapper来集成Lua脚本C的程序中厅R?br>
1.  创徏Lua引擎
  LuaWrap lua; 或?LuaWrap* lua = new LuaWrap;
  创徏一个LuaWrap对象Q就是创Z个Lua脚本引擎。ƈ且根据Lua的特性,你可以创ZQ意多个Lua引擎Q甚臛_以分布在不同的线E当中?br>
2.  装蝲q执行脚本程?br>  你可以从~冲Z装蝲Lua脚本Q?br>  lua.LoadString(
    "print('Hello World')"
  );
  当然Q你也可以从文g中装入,q执行Lua脚本Q?br>  Lua.LoadFile("./test.lua");
  Lua的脚本,可以是源代码Q也可以l过~译后的中间代码。也怽对编译后的中间代码更感兴——如果你不希望让源代码赤裸裸的袒露在大家的眼前?br>
3.  获取和设|Lua变量
  能够获取和设|脚本变量的内容Q是一个最基本的功能。你可以使用GetGlobal和SetGlobal函数来做到这一点:
  (1)  获取变量Q?br>    int a = lua.GetGlobal<int>("a");
    LuaTable table = lua.GetGlobal<LuaTable>("t");
    q里Q?lt;> 里头的类型,是惌的变量的cd?br>  (2)  讄变量Q?br>    lua.SetGlobal("a", a);
    lua.SetGlobal("t", table);

4.  调用Lua函数
  使用Call函数Q就可以很简单的从你的程序中调用Lua函数Q?br>  lua.Call<void>("print", "Hello World");
  int sum = lua.Call<int>("add", 2, 3);
  q里Q?lt;> 里头的类型是q回值的cd?br>
5.  如何让Lua也能调用C++的函?br>  _N的地Ҏ了。假如有下面q样的一个函敎ͼ
  int add(int a, int b)
  {
    return a + b;
  }
  如果惌它能够让Lua使用Q只需它注册到Lua引擎当中可以了Q?br>  lua.RegisterFunc("add", int(int,int), add);
  q样QLua中就可以用直接用了Q?br>  QLua脚本Qsum = add(1, 3)

  (*) RegisterFunc的功能,是让你把C++的函数注册到Lua中,供Lua脚本使用?br>    W一个参敎ͼ是想要在Lua中用的函数名?br>    W二个参敎ͼ是C++中函数的原型Q?C++允许函数重蝲的,你可以用函数原型,来选择需要注册到Lua引擎中的那个函数?br>    W三个参敎ͼ是C++中函数的指针了?br>
6.  如何能让C++的类在Lua中?br>  我们先看看下面这个C++c:
class MyArray
{
  std::vector<double> array;
public:
  void setvalue(int index, double value);
  double getvalue(int index);
  int size();
  const char* ToString();
};

  你准备要让Lua能够自由讉Kq操作这个类。很单,你只需增加几个宏定义就可以了:

class MyArray
{
  std::vector<double> array;
public:
  void setvalue(int index, double value);
  double getvalue(int index);
  int size();
  const char* ToString();
  // 一?class 作ؓ一?Lua 对象是很Ҏ的,只需要增加以下宏定义?br>  DEFINE_TYPENAME("My.array");
  BEGIN_REGLUALIB("array")
      LUALIB_ITEM_CREATE("new", MyArray )  // 创徏MyArray 
      LUALIB_ITEM_DESTROY("del", MyArray )  // 消除MyArray?br>  END_REGLUALIB()
  BEGIN_REGLUALIB_MEMBER()
    LUALIB_ITEM_FUNC("size", int (MyArray*), &MyArray::size)
    LUALIB_ITEM_FUNC("__getindex", double(MyArray*, int), &MyArray::getvalue)  
    LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &MyArray::setvalue)
    LUALIB_ITEM_FUNC("__tostring", const char* (MyArray*), &MyArray::ToString)
    LUALIB_ITEM_DESTROY("__gc", MyArray )   // 垃圾攉时消除对象用?br>  END_REGLUALIB_MEMBER()
};

  只要有了q些宏定义,q个cd是可以在Lua中用的cMQ我们就可以在Lua中注册这个类了:
  lua.Register<MyArray>()

  q样注册以后Q我们在Lua中就可以使用q个cMQ?br>  a = array.new()  -- 创徏对象Q相当于 a = new Myarray
  a[1] = 10  -- 调用__newindexQ也是C++中的 a->setvalue(1, 10)
  a[2] = 20  -- 调用__newindexQ也是C++中的 a->setvalue(2, 20)
  print(
    a,  -- 调用 __tostringQ也是C++中的 a->ToString()
    a:size(), -- 相当于C++中的 a->size()
    a[1], -- 调用__getindexQ也是C++中的a->getvalue(1)
    a[2]) --调用__getindexQ也是C++中的a->getvalue(2)
  array.del(a)  -- 清除对象Q相当于 delete a
  a = nil  -- 清空 aQ很象C++中的 a = NULL

  当然Q你也可以不用delq个对象Q而是{待Lua帮你自动q行垃圾回收。在Luaq行垃圾回收Ӟ它会自动调用q个对象?__gc Q相当于 delete?br>
  那么Q在C++中要创徏MyArray对象Qƈ且传递给Lua全局变量怎么办?p前面讲过的一P使用SetGlobalQ?br>  MyArray* a = new MyArray;
  lua.SetGlobal("a", a);
  要获取该对象Q同LQ应该用GetGlobalQ?br>  MyArray* a = lua.GetGlobal<MyArray>("a");
  
  对于传递给Lua的对象,pLua来管理该对象的生存周期好了。如果你非要删除它的话,你可以用DelGlobalObjectQ?br>  lua.DelGlobalObject<MyArray>("a");
  不过q么做的话,你应当明白你在做什么,因ؓ在Lua的脚本中Q可能已l在多处引用了这个对象了。删除了其中一个,导致其它引用对象失效,从而可能引致系l崩溃?br>
  (1)  DEFINE_TYPENAME("My.array");
    定义cd的名U。在Lua中,q个cd名称是唯一用来识别C++cd的,你必Mؓ不同的对象给予不同的名称?br>
  (2)  BEGIN_REGLUALIB("array") ... END_REGLUALIB()
    你可以ؓ一个对象定义一个程序库Q?array"是E序库的名字。在E序库中定义的函数是全局函数Q在Lua中,使用该函敎ͼ需要在函数前加上库的名字,如:array.newQ)。通常Q程序库会包含创建对象的Ҏ。如Q?br>    LUALIB_ITEM_CREATE("new", MyArray )  // 创徏MyArray

    q样子,你才能在Lua中创建MyArrayQ?br>    a = array.new()
  
    你也可以选择增加一个删除对象操作:
    LUALIB_ITEM_DESTROY("del", MyArray )   // 删除MyArray
    q样Q你可以直接删除一个对象了Q?br>    array.del(a)

  (3)  BEGIN_REGLUALIB_MEMBER() ...END_REGLUALIB_MEMBER()
    在此处,你可以定义对象的成员函数Q也可以重蝲对象的操作符——是的,pC++的operator重蝲。例如:
    LUALIB_ITEM_FUNC("__newindex", void (MyArray*, int, double), &MyArray::setvalue)
    是重蝲 operator[] 操作W。Lua中可重蝲的操作符q有许多Q如Q?br>
    __getindexQ操作符[]Q支持读取访问,?v = a[10]
    __newindexQ操作符[]Q支持赋D问,?a[10] = 1.22
    __tostringQ将变量转换成字串__addQ等同于operator +
    __addQ操作符 Q?br>    __subQ操作符 -
    __mulQ操作符 ×
    __divQ操作符 ÷
    __powQ操作符 ^ (乘方)
    __unmQ一元操作符 -
    __concatQ操作符 .. (字符串连?
    __eqQ操作符 == (a ~= b{h?not a == b)
    __ltQ操作符 < (a > b {h?b < a)
    __leQ操作符 <= (a >= b {h?b <= aQ要注意的是Q如果没有定?__le"Q则Lua会试a<=b 转换?not (b < a) )

    __gcQ在垃圾回收时调用此函数Q相当于C++的析构函数。强烈徏议定义此操作W,以免造成内存泄漏{情c比如:
    LUALIB_ITEM_DESTROY("__gc", MyArray )   // 垃圾攉时消除对象用?br>
    (? q里要说明一下,在lua中,讉K索引操作W是__indexQ不是__getindexQ在luaWrapper库中Qؓ了方便用,其映射为__getindexQ同Ӟ对__index的定义将会被忽略?br>
    p么简单。假如你已经有现成的c,而你没有修改该类的权力,如何其加入到Lua中呢Q答案就是,l承它,把zcd入到Lua中?br>
l束?br>  LuaWrapper 需要用到boost库的支持Qboost/type_traits.hpp, boost/function.hpp, boost/bind.hppQ它使用了C++的模杉K份特化,因此QC++~译器如果不支持此特性,无法编译。目前支持此Ҏ的~译器已l有很多。在VisualStudo产品pd中,只有VC7.1能支持此Ҏ,因此Q您如果正在使用VisualStudioQ请认你用的是VisualStudio2003?br>  如果你觉?LuaWrapper For C++ 能够帮助你,我会感觉很荣q。我很愿意将q个E序库分享给大家。顺便一提的是,如果你在使用q程中发现BUGQ或是有好的Q希望您能与我联pR你在用过E中Q请不要删除文g中的|名信息Q如果你修改了程序库Q请您在修改的文件中加入您的修改说明。当Ӟ我会非常Ƣ迎您能修改后的程序回馈给我。我会l优化ƈ完善它?br>



avatar 2010-04-21 22:46 发表评论
]]>
【{贴】?Lua ~写可嵌入式脚本 http://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113184.htmlavataravatarWed, 21 Apr 2010 14:44:00 GMThttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113184.htmlhttp://www.shnenglu.com/iwangchuchu/comments/113184.htmlhttp://www.shnenglu.com/iwangchuchu/archive/2010/04/21/113184.html#Feedback0http://www.shnenglu.com/iwangchuchu/comments/commentRss/113184.htmlhttp://www.shnenglu.com/iwangchuchu/services/trackbacks/113184.html

使用 Lua ~写可嵌入式脚本

Lua 提供了高U抽象,却又没失Mg的关?/p>
此作为电子邮件发?src="http://www.ibm.com/i/v14/icons/em.gif"

此作为电子邮件发?/font>



U别: 初

Martin Streicher (martin.streicher@linux-mag.com), 首席~辑, Linux Magazine

2006 q?6 ?12 ?/p>

虽然~译性编E语a和脚本语a各自h自己独特的优点,但是如果我们使用q两U类型的语言来编写大型的应用E序会是什么样子呢QLua 是一U嵌入式脚本语言Q它非常,速度很快Q功能却非常强大。在创徏其他配置文g或资源格式(以及与之对应的解析器Q之前,请尝试一?Lua?/blockquote>

管诸如 Perl、Python、PHP ?Ruby 之类的解释性编E语a日益?Web 应用E序q泛地采U?—?它们已经长期用来实现自动化系l管理Q?—?但是诸如 C、C++ 之类的编译性编E语a依然是必需的。编译性编E语a的性能是脚本语a所无法企及的(只有手工调优的汇~程序的性能才能过它)Q有些Y?—?包括操作pȝ和设备驱动程?—?只能使用~译代码来高效地实现。实际上Q当软g和硬仉要进行无~地q接操作ӞE序员本能地׃选择 C ~译器:C 非常基础Q距?“原始金属材料非常q?#8221; —?卛_以操作硬件的很多Ҏ?—?q且 C 的表现力非常强大Q可以提供高U编E结构,例如l构、@环、命名变量和作用域?/p>

然而,脚本语言也有自己独特的优炏V例如,当某U语a的解释器被成功移植到一U^C以后Q用这U语a~写的大量脚本就可以不加M修改在这U新q_上运?—?它们没有诸如pȝ特定的函数库之类的依赖限制。(我们可以考虑一?Microsoft® Windows® 操作pȝ上的许多 DLL 文g?UNIX® ?Linux® 上的很多 libcsQ。另外,脚本语言通常都还会提供高U编E构造和便利的操作,E序员可以用这些功能来提高生效率和灵zL。另外,使用解释语言来编E的E序员工作的速度更快Q因不需要编译和链接的步骤。C 及其cM语言中的 “~码、编译、链接、运?#8221; 周期~减成了更ؓ紧凑?“~写脚本、运?#8221;?/p>

Lua 新特?/font>

与其他脚本语a一PLua 也有自己的一些特性:

  • Lua cd?/strong>?Lua 中,值可以有cdQ但是变量的cd都是动态决定的?em>nil、布型、数?/em> ?字符?/em> cd的工作方式与我们期望的一栗?
    • Nil 是gؓ nil 的一U特D类型,用来表示没有倹{?
    • 布尔型的值可以是 true ?false 帔R。(Nil 也可以表C?falseQQ何非 nil 的值都表示 true。)
    • Lua 中所有的数字都是双精度的Q不q我们可以非常简便地~写一些代码来实现其他数字cdQ?
    • 字符串是定长字符数组。(因此Q要在一个字W串后面附加上字W,必须对其q行拯。)
  • 表、函?/em> ?em>U程 cd都是引用。每个都可以赋值给一个变量,作ؓ参数传递,或作回g函数中返回。例如,下面是一个存储函数的例子Q?br>
    -- example of an anonymous function
                                    -- returned as a value
                                    -- see http://www.tecgraf.puc-rio.br/~lhf/ftp/doc/hopl.pdf
                                    function add(x)
                                    return function (y) return (x + y) end
                                    end
                                    f = add(2)
                                    print(type(f), f(10))
                                    function  12
                                    

  • Lua U程?/strong>U程是通过调用内嵌函数 coroutine.create(f) 创徏的一?em>协同例程 (co-routine)Q其?f 是一?Lua 函数。线E不会在创徏时启动;相反Q它是在创徏之后使用 coroutine.resume(t) 启动的,其中 t 是一个线E。每个协同例E都必须使用 coroutine.yield() 偶尔获得其他协同例程的处理器?
  • 赋D句?/strong>Lua 允许使用多种赋D句,可以先对表达式进行求|然后再进行赋倹{例如,下面的语句:

    i = 3
                                    a = {1, 3, 5, 7, 9}
                                    i, a[i], a[i+1], b = i+1, a[i+1], a[i]
                                    print (i, a[3], a[4], b, I)
                                    

    会生?4 7 5 nil nil。如果变量列表的个数大于值列表的个数Q那么多出的变量都被赋gؓ nilQ因此,b 是 nil。如果值的个数多于变量的个敎ͼ那么多出的值部分就会简单地丢弃。在 Lua 中,变量名是大小写敏感的Q这可以解释Z?I 的值是 nil?
  • 块(ChunkQ?/strong> ?/em> 可以是Q?Lua 语句序列。块可以保存到文件中Q或者保存到 Lua E序中的字符串中。每个块都是作ؓ一个匿名函C来执行的。因此,块可以定义局部变量和q回倹{?
  • 更酷的东ѝ?/strong>Lua h一个标?清理垃圾攉器。在 Lua 5.1 中,垃圾攉器是以增量方式工作的。Lua h完整的词法闭包(q与 Scheme cMQ而与 Python 不同Q。Lua h可靠的尾部调用语义(同样Q这也与 Scheme cMQ而与 Python 不同Q?

?Programming in Lua ?Lua-users wiki Q链接请参见后面?参考资?/font> 部分Q中可以扑ֈ更多 Lua 代码的例子?/p>

在所有的工程d中,要在~译性语a和解释性语a之间作出选择Q就意味着要在q种环境中对每种语言的优~点、权重和折中q行评测Qƈ接受所带来的风险?/p>



回页?/font>


在两个世界之间最好地q行混合

如果您希望充分利用这两个世界的优点,应该怎样办呢Q是选择最好的性能q是选择高强大的抽象?更进一步说Q如果我们希望对处理器密集且依赖于系l的法和函C及与pȝ无关且很ҎҎ需要而进行修改的单独逻辑q行优化Q那又当如何呢?

寚w性能代码和高U编E的需要进行^衡是 LuaQ一U可嵌入式脚本语aQ要解决的问题。在需要时我们可以使用~译后的代码来实现底层的功能Q然后调?Lua 脚本来操作复杂的数据。由?Lua 脚本是与~译代码独立的,因此我们可以单独修改q些脚本。?LuaQ开发周期就非常cM?“~码、编译、运行、编写脚本、编写脚本、编写脚?...”?/p>

例如QLua Web 站点 “使用” 面Q请参见 参考资?/font>Q列ZL市场上的几个计算机游戏,包括 World of Warcraft 和(家用版的Q?em>DefenderQ它们集?Lua 来实现很多东西,从用L面到敌h的h工智能都可以。Lua 的其他应用程序包括流行的 Linux 软g更新工具 apt-rpm 的扩展机Ӟq有 “Crazy Ivan” Robocup 2000 冠军联赛的控刉辑。这个页面上的很多推荐感a都对 Lua 的小巧与杰出性能赞不l口?/p>



回页?/font>


开始?Lua

Lua 5.0.2 版本是撰写本文时的最新版本,不过最q刚刚发布了 5.1 版本。您可以?lua.org 上下?Lua 的源代码Q在 Lua-users wikiQ链接请参见 参考资?/font>Q上可以扑ֈ预先~译好的二进制文件。完整的 Lua 5.0.2 核心文g中包括了标准库和 Lua ~译器,不过只有 200KB 大小?/p>

如果您用的?Debian LinuxQ那么可以以用户的n份运行下面的命o来快速安?Lua 5.0Q?/p>
# apt-get install lua50
                            

本文中给出的例子都是?Debian Linux Sarge 上运行的Q用的?Lua 5.0.2 ?2.4.27-2-686 版本?Linux 内核?/p>

在系l上安装?Lua 之后Q我们可以首先来试用一下单独的 Lua 解释器。(所有的 Lua 应用E序必须要嵌入到宿主应用E序中。解释器只是一U特D类型的宿主Q对于开发和调试工作来说非常有用。)创徏一个名?factorial.lua 的文Ӟ然后输入下面的代码:

-- defines a factorial function
                            function fact (n)
                            if n == 0 then
                            return 1
                            else
                            return n * fact(n-1)
                            end
                            end
                            print("enter a number:")
                            a = io.read("*number")
                            print(fact(a))
                            

factorial.lua 中的代码 —?更确切地说是M Lua 语句序列 —?都称Z?em>?/em>Q这在上面的 Lua Ҏ?/font> 中已l进行了介绍。要执行刚才创徏的代码块Q请q行命o lua factorial.luaQ?/p>
$ lua factorial.lua
                            enter a number:
                            10
                            3628800
                            

或者像在其他解释性语a中一P我们可以在代码顶部添加一?“标识W?#8221;Q?code>#!Q,使这个脚本变成可执行的,然后像单独命令一hq行q个文gQ?/p>
$ (echo '#! /usr/bin/lua'; cat factorial.lua) > factorial
                            $ chmod u+x factorial
                            $ ./factorial
                            enter a number:
                            4
                            24
                            





回页?/font>


Lua 语言

Lua hC脚本语言中的很多便利Q作用域Q控制结构,q代器,以及一l用来处理字W串、生及攉数据和执行数学计操作的标准库。在 Lua 5.0 Reference Manual 中有?Lua 语言的完整介l(请参?参考资?/font>Q?/p>

?Lua 中,只有?/em> hcdQ而变量的cd是动态决定的。Lua 中的基本cdQ|?8 U: nilQ布型Q数字,字符Ԍ函数Q线E,?/em> 以及 用户数据。前 6 U类型基本上是自描述的(例外情况请参见上面的 Lua Ҏ?/font> 一节)Q最后两个需要一点解释?/p>

Lua ?/font>

?Lua 中,表是用来保存所有数据的l构。实际上Q表?Lua ?em>惟一?/em> 数据l构。我们可以将表作为数l、字典(也称?em>散列 ?em>联合数组Q、树、记录,{等?/p>

与其他编E语a不同QLua 表的概念不需要是异构的:表可以包含Q何类型的l合Q也可以包含cLl元素和cd典元素的混合体。另外,M Lua ?—?包括函数或其他表 —?都可以用作字典元素的键倹{?/p>

要对表进行浏览,请启?Lua 解释器,q输入清?1 中的黑体昄的代码?/p>
清单 1. 体验 Lua ?/strong>
$ lua
                            > -- create an empty table and add some elements
                            > t1 = {}
                            > t1[1] = "moustache"
                            > t1[2] = 3
                            > t1["brothers"] = true
                            > -- more commonly, create the table and define elements
                            > all at once
                            > t2 = {[1] = "groucho", [3] = "chico", [5] = "harpo"}
                            > t3 = {[t1[1]] = t2[1], accent = t2[3], horn = t2[5]}
                            > t4 = {}
                            > t4[t3] = "the marx brothers"
                            > t5 = {characters = t2, marks = t3}
                            > t6 = {["a night at the opera"] = "classic"}
                            > -- make a reference and a string
                            > i = t3
                            > s = "a night at the opera"
                            > -- indices can be any Lua value
                            > print(t1[1], t4[t3], t6[s])
                            moustache   the marx brothers classic
                            > -- the phrase table.string is the same as table["string"]
                            > print(t3.horn, t3["horn"])
                            harpo   harpo
                            > -- indices can also be "multi-dimensional"
                            > print (t5["marks"]["horn"], t5.marks.horn)
                            harpo   harpo
                            > -- i points to the same table as t3
                            > = t4[i]
                            the marx brothers
                            > -- non-existent indices return nil values
                            > print(t1[2], t2[2], t5.films)
                            nil     nil     nil
                            >  -- even a function can be a key
                            > t = {}
                            > function t.add(i,j)
                            >> return(i+j)
                            >> end
                            > print(t.add(1,2))
                            3
                            > print(t['add'](1,2))
                            3
                            >  -- and another variation of a function as a key
                            > t = {}
                            > function v(x)
                            >> print(x)
                            >> end
                            > t[v] = "The Big Store"
                            > for key,value in t do key(value) end
                            The Big Store
                            

正如我们可能期望的一PLua q提供了很多q代器函数来对表q行处理。全局变量 table 提供了这些函敎ͼ是的QLua 包就是表Q。有些函敎ͼ例如 table.foreachi()Q会期望一个从 1Q数?1Q开始的q箋整数范围Q?/p>
> table.foreachi(t1, print)
                            1 moustache
                            2 3
                            

另外一些函敎ͼ例如 table.foreach()Q会Ҏ个表q行q代Q?/p>
> table.foreach(t2,print)
                            1       groucho
                            3       chico
                            5       harpo
                            > table.foreach(t1,print)
                            1       moustache
                            2       3
                            brothers        true
                            

管有些q代器对整数索引q行了优化,但是所有P代器都只单地处理 (key, value) 寏V?/p>

现在我们可以创徏一个表 tQ其元素?{2, 4, 6, language="Lua", version="5", 8, 10, 12, web="www.lua.org"}Q然后运?table.foreach(t, print) ?table.foreachi(t, print)?/p>

用户数据

׃ Lua 是ؓ了嵌入到使用另外一U语aQ例?C ?C++Q编写的宿主应用E序中,q与宿主应用E序协同工作Q因此数据可以在 C 环境?Lua 之间q行׃n。正?Lua 5.0 Reference Manual 所_userdata cd允许我们?Lua 变量中保存Q意的 C 数据。我们可以认?userdata 是一个字节数l?—?字节可以表示指针、结构或宿主应用E序中的文g?/p>

用户数据的内Ҏ自于 CQ因此在 Lua 中不能对其进行修攏V当Ӟ׃用户数据源自?CQ因此在 Lua 中也没有对用h据预定义操作。不q我们可以用另外一U?Lua 机制来创建对 userdata q行处理的操作,q种机制UCؓ 元表QmetatableQ?/em>

元表

׃表和用户数据都非常灵z,因此 Lua 允许我们重蝲q两U类型的数据的操作(不能重蝲其他 6 U类型)?em>元表 是一个(普通的QLua 表,它将标准操作映射成我们提供的函数。元表的键值称?em>事gQ|换而言之就是函敎ͼUCؓ元方?/em>?/p>

函数 setmetatable() ?getmetatable() 分别对对象的元表q行修改和查询。每个表?userdada 对象都可以具有自q元表?/p>

例如Q添加操作对应的事g?__add。我们可以推断这D代码所做的事情么?

-- Overload the add operation
                            -- to do string concatenation
                            --
                            mt = {}
                            function String(string)
                            return setmetatable({value = string or ''}, mt)
                            end
                            -- The first operand is a String table
                            -- The second operand is a string
                            -- .. is the Lua concatenate operator
                            --
                            function mt.__add(a, b)
                            return String(a.value..b)
                            end
                            s = String('Hello')
                            print((s + ' There ' + ' World!').value )
                            

q段代码会生下面的文本Q?/p>
Hello There World!
                            

函数 String() 接收一个字W串 stringQ将其封装到一个表Q?code>{value = s or ''}Q中Qƈ元?mt 赋值给q个表。函?mt.__add() 是一个元ҎQ它字W串 b d到在 a.value 中找到的字符串后?b ơ。这行代?print((s + ' There ' + ' World!').value ) 调用q个元方法两ơ?/p>

__index 是另外一个事件?code>__index 的元Ҏ每当表中不存在键值时׃被调用。下面是一个例子,它记?(memoize) 函数的|

-- code courtesy of Rici Lake, rici@ricilake.net
                            function Memoize(func, t)
                            return setmetatable(
                            t or {},
                            {__index =
                            function(t, k)
                            local v = func(k);
                            t[k] = v;
                            return v;
                            end
                            }
                            )
                            end
                            COLORS = {"red", "blue", "green", "yellow", "black"}
                            color = Memoize(
                            function(node)
                            return COLORS[math.random(1, table.getn(COLORS))]
                            end
                            )
                            

这D代码放?Lua 解释器中Q然后输?print(color[1], color[2], color[1])。您会看到cM?blue black blue 的内宏V?/p>

q段代码接收一个键?nodeQ查?node 指定的颜艌Ӏ如果这U颜色不存在Q代码就会给 node 赋一个新的随机选择的颜艌Ӏ否则,p回赋l?node 的颜艌Ӏ在前一U情况中Q?code>__index 元方法被执行一ơ以分配一个颜艌Ӏ后一U情冉|较简单,所执行的是快速散列查找?/p>

Lua 语言提供了很多其他功能强大的Ҏ,所有这些特性都有很好的文档q行介绍。在到问题或希望与专家q行交谈Ӟ误?Lua Users Chat Room IRC ChannelQ请参见 参考资?/font>Q获得非常热心的支持?/p>



回页?/font>


嵌入和扩?/font>

除了语法单ƈ且具有功能强大的表结构之外,Lua 的强大功能其可以与宿主语言混合使用。由?Lua 与宿主语a的关p非常密切,因此 Lua 脚本可以对宿主语a的功能进行扩充。但是这U融合是双赢的:宿主语言同时也可以对 Lua q行扩充。D例来_C 函数可以调用 Lua 函数Q反之亦然?/p>

Lua 与宿主语a之间的这U共生关pȝ核心是宿主语a是一?em>虚拟堆栈。虚拟堆栈与实际堆栈cMQ是一U后q先出(LIFOQ的数据l构Q可以用来时存储函数参数和函数l果。要?Lua 中调用宿主语a的函敎ͼ反之亦然Q,调用者会一些值压入堆栈中Qƈ调用目标函数Q被调用的函C弹出q些参数Q当然要对类型和每个参数的D行验证)Q对数据q行处理Q然后将l果攑օ堆栈中。当控制q回l调用程序时Q调用程序就可以从堆栈中提取回倹{?/p>

实际上在 Lua 中用的所有的 C 应用E序~程接口QAPIQ都是通过堆栈来进行操作的。堆栈可以保?Lua 的|不过值的cd必须是调用程序和被调用者都知道的,特别是向堆栈中压入的值和从堆栈中弹出的值更是如此(例如 lua_pushnil() ?lua_pushnumber()?/p>

清单 2 l出了一个简单的 C E序Q节选自 参考资?/font> ?Programming in Lua 一书的W?24 章)Q它实现了一个很但却功能完善的 Lua 解释器?/p>
清单 2. 一个简单的 Lua 解释?/strong>
 1 #include <stdio.h>
                            2 #include <lua.h>
                            3 #include <lauxlib.h>
                            4 #include <lualib.h>
                            5
                            6 int main (void) {
                            7   char buff[256];
                            8   int error;
                            9   lua_State *L = lua_open();   /* opens Lua */
                            10   luaopen_base(L);             /* opens the basic library */
                            11   luaopen_table(L);            /* opens the table library */
                            12   luaopen_io(L);               /* opens the I/O library */
                            13   luaopen_string(L);           /* opens the string lib. */
                            14   luaopen_math(L);             /* opens the math lib. */
                            15
                            16   while (fgets(buff, sizeof(buff), stdin) != NULL) {
                            17     error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
                            18             lua_pcall(L, 0, 0, 0);
                            19     if (error) {
                            20       fprintf(stderr, "%s", lua_tostring(L, -1));
                            21       lua_pop(L, 1);  /* pop error message from the stack */
                            22     }
                            23   }
                            24
                            25   lua_close(L);
                            26   return 0;
                            27 }
                            

W?2 行到W?4 行包括了 Lua 的标准函敎ͼ几个在所?Lua 库中都会使用的方便函C及用来打开库的函数。第 9 行创Z一?Lua 状?/em>。所有的状态最初都是空的;我们可以使用 luaopen_...() 函数库d到状态中Q如W?10 行到W?14 行所C?/p>

W?17 行和 luaL_loadbuffer() 会从 stdin 中以块的形式接收输入Qƈ对其q行~译Q然后将其放入虚拟堆栈中。第 18 行从堆栈中弹出数据ƈ执行之。如果在执行时出C错误Q就向堆栈中压入一?Lua 字符丌Ӏ第 20 行访问栈Ӟ栈顶的烦引ؓ -1Q作?Lua 字符Ԍ打印消息Q然后从堆栈中删除该倹{?/p>

使用 C APIQ我们的应用E序也可以进?Lua 状态来提取信息。下面的代码片段?Lua 状态中提取两个全局变量Q?/p>
..
                            if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0))
                            error(L, "cannot run configuration file: %s", lua_tostring(L, -1));
                            lua_getglobal(L, "width");
                            lua_getglobal(L, "height");
                            ..
                            width = (int) lua_tonumber(L, -2);
                            height = (int) lua_tonumber(L, -1);
                            ..
                            

请再ơ注意传输是通过堆栈q行的。从 C 中调用Q?Lua 函数与这D代码类|使用 lua_getglobal() 来获得函敎ͼ参数压入堆栈,调用 lua_pcall()Q然后处理结果。如?Lua 函数q回 n 个|那么W一个值的位置在堆栈的 -n 处,最后一个值在堆栈中的位置?-1?/p>

反之Q在 Lua 中调?C 函数也与之类伹{如果您的操作系l支持动态加载,那么 Lua 可以Ҏ需要来动态加载ƈ调用函数。(在必M用静态加载的操作pȝ中,可以?Lua 引擎q行扩充Q此时调?C 函数旉要重新编?Lua。)





回页?/font>


l束?/font>

Lua 是一U学习v来容易得难以|信的语aQ但是它单的语法却掩C了其强大的功能:q种语言支持对象Q这?Perl cMQ,元表使表cdh相当E度的可伸展性,C API 允许我们在脚本和宿主语言之间q行更好的集成和扩充。Lua 可以?C、C++、C#、Java™ ?Python 语言中用?/p>

在创建另外一个配|文件或资源格式Q以及相应的处理E序Q之前,请尝试一?Lua。Lua 语言及其C֌非常健壮Q具有创新精,随时准备好提供帮助?/p>



回页?/font>


参考资?

学习

获得产品和技?/strong>
  • 下蝲 Lua 5.0.2 ?Lua 5.1 源代码,从头开始编?Lua?

  • ?Lua-users wiki 上,览很多预先构徏的、可安装?Lua 二进制文件?

  • ?LuaForge 上可以找到大量的代码库,包括很多语言l定和专门的计算库?

  • 订购免费?SEK for Linux Q这有两?DVDQ包括最新的 IBM for Linux 试用软gQ包?DB2®、Lotus®、Rational®、Tivoli® ?WebSphere®?

  • 在您的下一个开发项目中采用 IBM 试用软gQ这可以?developerWorks 直接下蝲?


讨论






关于作?/font>

Martin Streicher ?Linux Magazine 的首席编辑。他在普渡大学获得了计算机硕士学位,?1982 q以来,׃直在使用 Pascal、C、Perl、Java 以及Q最q用的QRuby ~程语言~写c?Unix pȝ?/p>



avatar 2010-04-21 22:44 发表评论
]]>
Ըߺþþþþþþ| ˾þþþƷ| Ʒþþþþù| www.þ| þþþùպƷվ | þ99ھƷ| 鶹avþavʢav| ɫAVԾþþþþ| þ޾ƷƵ| þþþۺĻ| ξþ99ƷþþþþС˵| ĻƷѾþ5151| ˺ݺۺϾþ| þù˾Ʒ鶹| ɫͷվþ| 99þ99þþƷƬ| þˬˬƬAV| һaƬþëƬ| ҹƷþ| þþþƷ| 99ξþþŷƷվ| þþþavӰ| þþƷҹҹҹҹҹþ| Ůþþþþ| 99þþžžƷ| þþƷAVȫ| 99ȳ˾ƷȾþ | þþþþùƷ| ŮþþŮ| þþþþþĻ | þAVվ| ˸ŮѲžþþ| þþоƷ| þþWWW| þ99ƷþþþþҰ| 99þۺϺݺۺϾþֹ| ޾þþþþ| ŷһþۺ| ٸþþþþþþþ| þҹɫƷŷ| ˾þô߽AVɫɫ |