使用tolua++编译pkg,从而创建自定义类让Lua脚本使用
本站文章均为李华明Himi原创,转载务必在明显处注明:(作者新浪微博:@李华明Himi )
转载自【黑米GameDev街区】
原文链接: http://www.himigame.com/lua-game/1259.html
☞ 点击订阅 ☜ 本博客最新动态!及时将最新博文通知您!
此篇基本【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
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 && sp->initWithFile(fileName)){
sp->setPosition(ccp(100,100));
sp->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
} 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 & 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 < -->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 LuaCocos 2 d.cpp Cocos 2 d.pkg
This will generate the bindings file and patch it with come cocos 2 dx
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,今天就到这,希望大家多多探讨,有问题请及时留言。