【COCOS2DX-LUA 脚本开发之四】使用tolua++编译pk创建自定义类

简介:

此篇基本【COCOS2DX(2.X)_LUA开发之三】在LUA中使用自定义精灵(LUA脚本与自创建类之间的访问)及LUA基础讲解

在Lua第三篇中介绍了,如何在cocos2dx中使用Lua创建自定义类供Lua脚本调用使用,当时出于Himi对Lua研究不够深入,所以当时使用了笨方法手动添加的方式进行的,那么本篇将介绍利用tolua++快速将我们自定义的c2dx类嵌入,供 lua脚本使用。

首先介绍整个过程:

之前我们的过程: 自定义类->手动到LuaCoco2d.cpp中手动添加binding->lua使用

现在我们的过程是: 自定义类->使用tolua++工具编译到LuaCoco2d.cpp中->lua使用

下面进行详细步骤讲解:

步骤一:首先自定义类(这里Himi自定义类名 “MySprite”)

MySprite.h

 


  
  
  1. // 
  2. //  MySprite.h 
  3. //  mtet 
  4. // 
  5. //  Created by Himi on 13-4-7. 
  6. // 
  7. // 
  8.   
  9. #ifndef __mtet__MySprite__ 
  10. #define __mtet__MySprite__ 
  11.   
  12. #include "cocos2d.h" 
  13. using namespace cocos2d; 
  14.   
  15. class MySprite : public CCSprite{ 
  16. public
  17.     static MySprite* createMS(const char* fileName); 
  18. }; 
  19. #endif /* defined(__mtet__MySprite__) */ 
 

 

MySprite.cpp

 


  
  
  1. 10 
  2. 11 
  3. 12 
  4. 13 
  5. 14 
  6. 15 
  7. 16 
  8. 17 
  9. 18 
  10. 19 
  11. // 
  12. //  MySprite.cpp 
  13. //  mtet 
  14. // 
  15. //  Created by Himi on 13-4-7. 
  16. // 
  17. // 
  18.   
  19. #include "MySprite.h" 
  20. MySprite* MySprite::createMS(const char* fileName){ 
  21.     MySprite* sp = new MySprite(); 
  22.     if(sp && sp->initWithFile(fileName)){ 
  23.         sp->setPosition(ccp(100,100)); 
  24.         sp->autorelease(); 
  25.         return sp; 
  26.     } 
  27.     CC_SAFE_DELETE(sp); 
  28.     return NULL; 
 

步骤二:利用tolua++编译我们创建的pkg,将自定义类嵌入LuaCocos2d.cpp中

首先我们到cocos2dx引擎目录下找到tools下的tolua++文件夹。

然后你看到很多的pkg文件,你可以使用文本打开,就会发现都是Cocos2dx引擎封装的类、函数定义,如下CCSprite.pkg

 

  
  
  1. /* 
  2. typedef enum { 
  3.     //! Translate with it's parent 
  4.     CC_HONOR_PARENT_TRANSFORM_TRANSLATE =  1 << 0, 
  5.     //! Rotate with it's parent 
  6.     CC_HONOR_PARENT_TRANSFORM_ROTATE    =  1 << 1, 
  7.     //! Scale with it's parent 
  8.     CC_HONOR_PARENT_TRANSFORM_SCALE     =  1 << 2, 
  9.     //! Skew with it's parent 
  10.     CC_HONOR_PARENT_TRANSFORM_SKEW      =  1 << 3, 
  11.   
  12.     //! All possible transformation enabled. Default value. 
  13.     CC_HONOR_PARENT_TRANSFORM_ALL       =  CC_HONOR_PARENT_TRANSFORM_TRANSLATE | CC_HONOR_PARENT_TRANSFORM_ROTATE | CC_HONOR_PARENT_TRANSFORM_SCALE | CC_HONOR_PARENT_TRANSFORM_SKEW, 
  14.   
  15. } ccHonorParentTransform; 
  16. */ 
  17. class CCSprite : public CCNode 
  18.     void setDirty(bool bDirty); 
  19.     bool isDirty(void); 
  20.   
  21.     ccV3F_C4B_T2F_Quad getQuad(void); 
  22.   
  23.     CCRect getTextureRect(void); 
  24.     //bool isUsesBatchNode(void); 
  25.     bool isTextureRectRotated(void); 
  26.   
  27.     void setAtlasIndex(unsigned int uAtlasIndex); 
  28.     unsigned int getAtlasIndex(void); 
  29.     //void setUsesSpriteBatchNode(bool bUsesSpriteBatchNode); 
  30.     void setTextureAtlas(CCTextureAtlas *pobTextureAtlas); 
  31.     CCTextureAtlas* getTextureAtlas(void); 
  32.     //void setSpriteBatchNode(CCSpriteBatchNode *pobSpriteBatchNode); 
  33.     //CCSpriteBatchNode* getSpriteBatchNode(void); 
  34.     //void setHonorParentTransform(ccHonorParentTransform eHonorParentTransform); 
  35.     //ccHonorParentTransform getHonorParentTransform(void); 
  36.     void setBlendFunc(ccBlendFunc blendFunc); 
  37.     ccBlendFunc getBlendFunc(void); 
  38.   
  39.     CCPoint getOffsetPosition(void); 
  40.   
  41.     void ignoreAnchorPointForPosition(bool newValue); 
  42.     void setFlipX(bool bFlipX); 
  43.     void setFlipY(bool bFlipY); 
  44.     bool isFlipX(void); 
  45.     bool isFlipY(void); 
  46.   
  47.     void removeChild(CCNode* pChild, bool bCleanUp); 
  48.     void removeAllChildrenWithCleanup(bool bCleanup); 
  49.     void reorderChild(CCNode* pChild, int zOrder); 
  50.     void addChild(CCNode* pChild); 
  51.     void addChild(CCNode* pChild, int zOrder); 
  52.     void addChild(CCNode* pChild, int zOrder, int tag); 
  53.     void sortAllChildren(); 
  54.     //void setPosition(CCPoint pos); 
  55.     void setRotation(float rotation); 
  56.     void setSkewX(float sx); 
  57.     void setSkewY(float sy); 
  58.     void setScale(float fScale); 
  59.     void setScaleX(float fScaleX); 
  60.     void setScaleY(float fScaleY); 
  61.     void setVertexZ(float fVertexZ); 
  62.     void setAnchorPoint(const CCPoint & anchor); 
  63.     void setVisible(bool bVisible); 
  64.   
  65.     void setOpacity(GLubyte opacity); 
  66.     GLubyte getOpacity(void); 
  67.   
  68.     void setColor(ccColor3B color3); 
  69.     ccColor3B getColor(void); 
  70.     void setOpacityModifyRGB(bool bValue); 
  71.     bool isOpacityModifyRGB(void); 
  72.   
  73.     void setTexture(CCTexture2D *texture); 
  74.     CCTexture2D* getTexture(void); 
  75.   
  76.     void updateTransform(void); 
  77.     //void useSelfRender(void); 
  78.     void setTextureRect(CCRect rect); 
  79.     void setTextureRect(CCRect rect, bool rotated, CCSize size); 
  80.     void setVertexRect(CCRect rect); 
  81.     //void useBatchNode(CCSpriteBatchNode *batchNode); 
  82.     void setDisplayFrame(CCSpriteFrame *pNewFrame); 
  83.     bool isFrameDisplayed(CCSpriteFrame *pFrame); 
  84.     CCSpriteFrame* displayFrame(void); 
  85.     void setBatchNode(CCSpriteBatchNode* pBatchNode); 
  86.     CCSpriteBatchNode* getBatchNode(); 
  87.     void setDisplayFrameWithAnimationName(const char *animationName, int frameIndex); 
  88.   
  89.     static CCSprite* createWithTexture(CCTexture2D *pTexture); 
  90.     static CCSprite* createWithTexture(CCTexture2D *pTexture, CCRect rect); 
  91.     static CCSprite* createWithSpriteFrame(CCSpriteFrame *pSpriteFrame); 
  92.     static CCSprite* createWithSpriteFrameName(const char *pszSpriteFrameName); 
  93.     static CCSprite* create(const char *pszFileName, CCRect rect); 
  94.     static CCSprite* create(const char *pszFileName); 
  95.     static CCSprite* create(); 
  96. }; 

 

没错,我们也会按照类似方式进行创建我们自定义类的pkg文件。

我们自定义一个文件(文本、xcode等都可以),后缀 .pkg ,然后将Himi自定义的MySprite类定义到pkg中,如下:

注意:只要自定义类.h中的内容,至于cpp的实现,binding后lua自动调用你类的函数

MySprite.pkg

 


  
  
  1. class MySprite : public CCSprite{ 
  2.     static MySprite* createMS(const char* fileName); 
  3. }; 
 

在pkg中我只是定义了创建函数而已,至于更多的函数就交给大家自定义啦,另外我们注意书写pkg时是需要几条规则的,其实在tolua++这个文件夹中我们也能看到有一个名字叫 README 的文件,打开如下:

 


  
  
  1. 1. Generating the lua<-->C bindings with tolua++ 
  2.   
  3.     Build scripts for windows (build.bat) and unix (build.sh) are provided 
  4.     to generate the relevant files after modifying the .pkg files.  These 
  5.     scripts basically run the following command: 
  6.   
  7.         tolua++.exe -L basic.lua -o LuaCocos2d.cpp Cocos2d.pkg 
  8.   
  9.     This will generate the bindings file and patch it with come cocos2dx 
  10.     specific modifications. 
  11.   
  12.     On POSIX systems you can also just run "make" to build the bindings 
  13.     if/when you change .pkg files. 
  14.   
  15. 2. Writing .pkg files 
  16.   
  17.     1) enum keeps the same 
  18.     2) remove CC_DLL for the class defines, pay attention to multi inherites 
  19.     3) remove inline keyword for declaration and implementation 
  20.     4) remove public protect and private 
  21.     5) remove the decalration of class member variable 
  22.     6) keep static keyword 
  23.     7) remove memeber functions that declared as private or protected 
 

 

这个文件声明了书写pkg的规则,不多赘述。

书写好我们的pkg之后,将pkg文件放置此tolua++文件夹下即可,然后配置我们tolua++工具。

继续在tolua++文件夹中解压tolua++.Mac.zip 文件,会得到一个tolua++的工具,如下图:

 

QQ20130407-2

 

解压出工具之后,我们还要在tolua++文件夹中,配置tolua++路径,打开“build.sh”文件,如下:

1

 

这里 TOLUA 是tolua++工具的位置(路径后面要架上 /tolua++  表示这个工具),最下面配置的是编译后的luaCocos2d.cpp文件导出的位置,Himi这里配置到桌面,配置如下:

QQ20130407-4

 

 最后,我们要将我们定义的pkg文件注册到 tolua++文件夹下的Cocos2d.pkg中,如下:

QQ20130407-7

 

如上步骤都OK后,我们就可以使用“终端”,先cd到tolua++的文件夹下,然后使用“make”命令执行tolua++工具。

(如果这里终端不能正常执行, 请继续修改tolua++文件夹下的: makefile  ,将其路径配置一下即可。)

终端正常执行后,会在一开始指定的目录生成LuaCocos2d.cpp 文件,且其中已经binding好了自定义类,将生成的LuaCocos2d.cpp替换到你项目的/libs/lua/cocos2dx_support下的LuaCocos2d.cpp 文件。

Himi建议生成的LuaCocos2d.cpp 文件路径直接设置你的项目的/libs/lua/cocos2dx_support下很方便

注意:这时候LuaCoco2d.cpp中虽然已经binding了我们的自定义类,但是没有引用我们的头文件,所以我们还需要在LuaCocos2d.h中倒入我们自定义类.h 。

步骤三:Lua测试我们的自定义类

 


  
  
  1. -- for CCLuaEngine traceback 
  2. function __G__TRACKBACK__(msg) 
  3.     print("----------------------------------------"
  4.     print("LUA ERROR: " .. tostring(msg) .. "\n"
  5.     print(debug.traceback()) 
  6.     print("----------------------------------------"
  7. end 
  8.   
  9. local function main() 
  10.     -- avoid memory leak 
  11.     collectgarbage("setpause", 100) 
  12.     collectgarbage("setstepmul", 5000) 
  13.   
  14.     local cclog = function(...) 
  15.         print(string.format(...)) 
  16.     end 
  17.   
  18.     require "hello2" 
  19.     cclog("result is " .. myadd(3, 5)) 
  20.   
  21.     --------------- 
  22.   
  23.     -- create farm 
  24.     local function createLayerFarm() 
  25.         local layerFarm = CCLayer:create() 
  26.   
  27.         local font = CCLabelTTF:create("Himi 使用tolua++ binding自定义类""Verdana-BoldItalic", 20) 
  28.         font:setPosition(ccp(220,260)) 
  29.         layerFarm:addChild(font) 
  30.   
  31.         local ms  = MySprite:createMS("Icon.png"
  32.         layerFarm:addChild(ms) 
  33.   
  34.         return layerFarm 
  35.     end 
  36.   
  37.     -- run 
  38.     local sceneGame = CCScene:create() 
  39.     sceneGame:addChild(createLayerFarm()) 
  40.     CCDirector:sharedDirector():runWithScene(sceneGame) 
  41. end 
  42.   
  43. xpcall(main, __G__TRACKBACK__) 
 

运行截图如下:

QQ20130407-6

 

OK,今天就到这,希望大家多多探讨,有问题请及时留言。

 








本文转自 xiaominghimi 51CTO博客,原文链接:http://blog.51cto.com/xiaominghimi/1173220,如需转载请自行联系原作者
目录
相关文章
|
1月前
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
Lua的面向对象编程、协同线程与协同函数的概念和使用,以及Lua文件I/O操作的基本方法。
28 4
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
|
1月前
|
缓存 分布式计算 NoSQL
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
大数据-43 Redis 功能扩展 Lua 脚本 对Redis扩展 eval redis.call redis.pcall
29 2
|
5月前
|
消息中间件 NoSQL Java
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
227 0
|
2月前
|
存储 JSON Ubuntu
如何使用 Lua 脚本进行更复杂的网络请求,比如 POST 请求?
如何使用 Lua 脚本进行更复杂的网络请求,比如 POST 请求?
|
3月前
|
存储 NoSQL Redis
Tair的发展问题之在Redis集群模式下,Lua脚本操作key面临什么问题,如何解决
Tair的发展问题之在Redis集群模式下,Lua脚本操作key面临什么问题,如何解决
|
5月前
|
NoSQL API Redis
使用Redis Lua脚本实现高级限流策略
使用Redis Lua脚本实现高级限流策略
198 0
|
6月前
|
存储 NoSQL Redis
Redis的Lua脚本有什么作用?
Redis Lua脚本用于减少网络开销、实现原子操作及扩展指令集。它能合并操作降低网络延迟,保证原子性,替代不支持回滚的事务。通过脚本,代码复用率提高,且可自定义指令,如实现分布式锁,增强Redis功能和灵活性。
248 1
|
6月前
|
缓存 NoSQL Java
【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性
【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性
226 0
|
5月前
|
JSON 监控 数据格式
使用Lua代码扩展上网行为管理软件的脚本功能
本文介绍了如何使用Lua脚本增强上网行为管理,包括过滤URL、记录用户访问日志、控制带宽和自动提交监控数据到网站。Lua是一种轻量级语言,适合编写扩展脚本。文中提供多个示例代码,如URL过滤器、用户活动日志记录器和带宽控制器,帮助用户根据需求定制网络管理功能。通过这些示例,用户可以快速掌握Lua在上网行为管理中的应用。
172 4
|
5月前
|
消息中间件 NoSQL Java
Spring Boot中使用Redis和Lua脚本实现延时队列
Spring Boot中使用Redis和Lua脚本实现延时队列