在Lua第三篇中介绍了,如何在cocos2dx中使用Lua创建自定义类供Lua脚本调用使用,当时出于Himi对Lua研究不够深入,所以当时使用了笨方法手动添加的方式进行的,那么本篇将介绍利用tolua++快速将我们自定义的c2dx类嵌入,供 lua脚本使用。
首先介绍整个过程:
之前我们的过程: 自定义类->手动到LuaCoco2d.cpp中手动添加binding->lua使用
现在我们的过程是: 自定义类->使用tolua++工具编译到LuaCoco2d.cpp中->lua使用
下面进行详细步骤讲解:
步骤一:首先自定义类(这里Himi自定义类名 “MySprite”)
MySprite.h
//
//  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
//
//  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
/*
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 & 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
class
MySprite :
public
CCSprite{
static
MySprite* createMS(
const
char
* fileName);
};
在pkg中我只是定义了创建函数而已,至于更多的函数就交给大家自定义啦,另外我们注意书写pkg时是需要几条规则的,其实在tolua++这个文件夹中我们也能看到有一个名字叫 README 的文件,打开如下:
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测试我们的自定义类
-- 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__
)
运行截图如下: