此篇基本
在Lua第三篇中介绍了,如何在cocos2dx中使用Lua创建自定义类供Lua脚本调用使用,当时出于Himi对Lua研究不够深入,所以当时使用了笨方法手动添加的方式进行的,那么本篇将介绍利用tolua++快速将我们自定义的c2dx类嵌入,供 lua脚本使用。
首先介绍整个过程:
之前我们的过程: 自定义类->手动到LuaCoco2d.cpp中手动添加binding->lua使用
现在我们的过程是: 自定义类->使用tolua++工具编译到LuaCoco2d.cpp中->lua使用
下面进行详细步骤讲解:
步骤一:首先自定义类(这里Himi自定义类名 “MySprite”)
MySprite.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // // MySprite.h // mtet // // Created by Himi on 13-4-7. // // #ifndef __mtet__MySprite__ #define __mtet__MySprite__ #include "cocos2d.h" using namespace cocos2d ; class MySprite : public CCSprite { public : static MySprite* createMS ( const char * fileName ) ; } ; #endif /* defined(__mtet__MySprite__) */ |
MySprite.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // // MySprite.cpp // mtet // // Created by Himi on 13-4-7. // // #include "MySprite.h" MySprite* MySprite :: createMS ( const char * fileName ) { MySprite* sp = new MySprite ( ) ; if ( sp & amp ; & amp ; sp - & gt ; initWithFile ( fileName ) ) { sp - & gt ; setPosition ( ccp ( 100 , 100 ) ) ; sp - & gt ; autorelease ( ) ; return sp ; } CC_SAFE_DELETE ( sp ) ; return NULL ; } |
步骤二:利用tolua++编译我们创建的pkg,将自定义类嵌入LuaCocos2d.cpp中
首先我们到cocos2dx引擎目录下找到tools下的tolua++文件夹。
然后你看到很多的pkg文件,你可以使用文本打开,就会发现都是Cocos2dx引擎封装的类、函数定义,如下CCSprite.pkg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /* typedef enum { //! Translate with it's parent CC_HONOR_PARENT_TRANSFORM_TRANSLATE = 1 << 0, //! Rotate with it's parent CC_HONOR_PARENT_TRANSFORM_ROTATE = 1 << 1, //! Scale with it's parent CC_HONOR_PARENT_TRANSFORM_SCALE = 1 << 2, //! Skew with it's parent CC_HONOR_PARENT_TRANSFORM_SKEW = 1 << 3, //! All possible transformation enabled. Default value. 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, } ccHonorParentTransform; */ class CCSprite : public CCNode { void setDirty ( bool bDirty ) ; bool isDirty ( void ) ; ccV3F_C4B_T2F_Quad getQuad ( void ) ; CCRect getTextureRect ( void ) ; //bool isUsesBatchNode(void); bool isTextureRectRotated ( void ) ; void setAtlasIndex ( unsigned int uAtlasIndex ) ; unsigned int getAtlasIndex ( void ) ; //void setUsesSpriteBatchNode(bool bUsesSpriteBatchNode); void setTextureAtlas ( CCTextureAtlas * pobTextureAtlas ) ; CCTextureAtlas* getTextureAtlas ( void ) ; //void setSpriteBatchNode(CCSpriteBatchNode *pobSpriteBatchNode); //CCSpriteBatchNode* getSpriteBatchNode(void); //void setHonorParentTransform(ccHonorParentTransform eHonorParentTransform); //ccHonorParentTransform getHonorParentTransform(void); void setBlendFunc ( ccBlendFunc blendFunc ) ; ccBlendFunc getBlendFunc ( void ) ; CCPoint getOffsetPosition ( void ) ; void ignoreAnchorPointForPosition ( bool newValue ) ; void setFlipX ( bool bFlipX ) ; void setFlipY ( bool bFlipY ) ; bool isFlipX ( void ) ; bool isFlipY ( void ) ; void removeChild ( CCNode* pChild , bool bCleanUp ) ; void removeAllChildrenWithCleanup ( bool bCleanup ) ; void reorderChild ( CCNode* pChild , int zOrder ) ; void addChild ( CCNode* pChild ) ; void addChild ( CCNode* pChild , int zOrder ) ; void addChild ( CCNode* pChild , int zOrder , int tag ) ; void sortAllChildren ( ) ; //void setPosition(CCPoint pos); void setRotation ( float rotation ) ; void setSkewX ( float sx ) ; void setSkewY ( float sy ) ; void setScale ( float fScale ) ; void setScaleX ( float fScaleX ) ; void setScaleY ( float fScaleY ) ; void setVertexZ ( float fVertexZ ) ; void setAnchorPoint ( const CCPoint & amp ; anchor ) ; void setVisible ( bool bVisible ) ; void setOpacity ( GLubyte opacity ) ; GLubyte getOpacity ( void ) ; void setColor ( ccColor3B color3 ) ; ccColor3B getColor ( void ) ; void setOpacityModifyRGB ( bool bValue ) ; bool isOpacityModifyRGB ( void ) ; void setTexture ( CCTexture2D * texture ) ; CCTexture2D* getTexture ( void ) ; void updateTransform ( void ) ; //void useSelfRender(void); void setTextureRect ( CCRect rect ) ; void setTextureRect ( CCRect rect , bool rotated , CCSize size ) ; void setVertexRect ( CCRect rect ) ; //void useBatchNode(CCSpriteBatchNode *batchNode); void setDisplayFrame ( CCSpriteFrame * pNewFrame ) ; bool isFrameDisplayed ( CCSpriteFrame * pFrame ) ; CCSpriteFrame* displayFrame ( void ) ; void setBatchNode ( CCSpriteBatchNode* pBatchNode ) ; CCSpriteBatchNode* getBatchNode ( ) ; void setDisplayFrameWithAnimationName ( const char * animationName , int frameIndex ) ; static CCSprite* createWithTexture ( CCTexture2D * pTexture ) ; static CCSprite* createWithTexture ( CCTexture2D * pTexture , CCRect rect ) ; static CCSprite* createWithSpriteFrame ( CCSpriteFrame * pSpriteFrame ) ; static CCSprite* createWithSpriteFrameName ( const char * pszSpriteFrameName ) ; static CCSprite* create ( const char * pszFileName , CCRect rect ) ; static CCSprite* create ( const char * pszFileName ) ; static CCSprite* create ( ) ; } ; |
没错,我们也会按照类似方式进行创建我们自定义类的pkg文件。
我们自定义一个文件(文本、xcode等都可以),后缀 .pkg ,然后将Himi自定义的MySprite类定义到pkg中,如下:
注意:只要自定义类.h中的内容,至于cpp的实现,binding后lua自动调用你类的函数
MySprite.pkg
1 2 3 | class MySprite : public CCSprite { static MySprite* createMS ( const char * fileName ) ; } ; |
在pkg中我只是定义了创建函数而已,至于更多的函数就交给大家自定义啦,另外我们注意书写pkg时是需要几条规则的,其实在tolua++这个文件夹中我们也能看到有一个名字叫 README 的文件,打开如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 1. Generating the lua & lt ; -- & gt ; C bindings with tolua ++ Build scripts for windows ( build . bat ) and unix ( build . sh ) are provided to generate the relevant files after modifying the . pkg files . These scripts basically run the following command : tolua ++ . exe - L basic . lua - o LuaCocos2d . cpp Cocos2d . pkg This will generate the bindings file and patch it with come cocos2dx specific modifications . On POSIX systems you can also just run "make" to build the bindings if / when you change . pkg files . 2. Writing . pkg files 1 ) enum keeps the same 2 ) remove CC_DLL for the class defines , pay attention to multi inherites 3 ) remove inline keyword for declaration and implementation 4 ) remove public protect and private 5 ) remove the decalration of class member variable 6 ) keep static keyword 7 ) remove memeber functions that declared as private or protected |
这个文件声明了书写pkg的规则,不多赘述。
书写好我们的pkg之后,将pkg文件放置此tolua++文件夹下即可,然后配置我们tolua++工具。
继续在tolua++文件夹中解压tolua++.Mac.zip 文件,会得到一个tolua++的工具,如下图:
解压出工具之后,我们还要在tolua++文件夹中,配置tolua++路径,打开“build.sh”文件,如下:
这里 TOLUA 是tolua++工具的位置(路径后面要架上 /tolua++ 表示这个工具),最下面配置的是编译后的luaCocos2d.cpp文件导出的位置,Himi这里配置到桌面,配置如下:
最后,我们要将我们定义的pkg文件注册到 tolua++文件夹下的Cocos2d.pkg中,如下:
如上步骤都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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | -- for CCLuaEngine traceback function __G__TRACKBACK__ ( msg ) print ( "----------------------------------------" ) print ( "LUA ERROR: " . . tostring ( msg ) . . "\n" ) print ( debug . traceback ( ) ) print ( "----------------------------------------" ) end local function main ( ) -- avoid memory leak collectgarbage ( "setpause" , 100 ) collectgarbage ( "setstepmul" , 5000 ) local cclog = function ( . . . ) print ( string . format ( . . . ) ) end require "hello2" cclog ( "result is " . . myadd ( 3 , 5 ) ) -- -- -- -- -- -- -- - -- create farm local function createLayerFarm ( ) local layerFarm = CCLayer : create ( ) local font = CCLabelTTF : create ( "Himi 使用tolua++ binding自定义类" , "Verdana-BoldItalic" , 20 ) font : setPosition ( ccp ( 220 , 260 ) ) layerFarm : addChild ( font ) local ms = MySprite : createMS ( "Icon.png" ) layerFarm : addChild ( ms ) return layerFarm end -- run local sceneGame = CCScene : create ( ) sceneGame : addChild ( createLayerFarm ( ) ) CCDirector : sharedDirector ( ) : runWithScene ( sceneGame ) end xpcall ( main , __G__TRACKBACK__ ) |
运行截图如下:
OK,今天就到这,希望大家多多探讨,有问题请及时留言。