【COCOS2DX-LUA 脚本开发笔记之一】如何使用tolua++将c++方法注册给lua

      之前使用c++做了个实时战斗的页游,期间用到了lua作为服务端脚本,好处更多的还是支持热更新,但是那时的注册却是比较麻烦的,现在用cocos2dx,没想到tolua++这么方便。感谢himi的实例。

     1、创建自定义类

MySprite.h
//
//  MySprite.h
//  HelloLua
//
//  Created by FengZi on 13-11-6.
//
//

#ifndef __HelloLua__MySprite__
#define __HelloLua__MySprite__

#include "cocos2d.h"

using namespace cocos2d;

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

#endif /* defined(__HelloLua__MySprite__) */


MySprite.cpp
//
//  MySprite.cpp
//  HelloLua
//
//  Created by FengZi on 13-11-6.
//
//

#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;
    }
    return NULL;
}


   
     2、使用tolua++编译新创建的pkg

首先我们到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 CCNodeRGBA
{
	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 ,然后将自定义的MySprite类定义到pkg中,如下:

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 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++的工具,如下图:

【COCOS2DX-LUA 脚本开发笔记之一】如何使用tolua++将c++方法注册给lua_第1张图片 


 

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


 【COCOS2DX-LUA 脚本开发笔记之一】如何使用tolua++将c++方法注册给lua_第2张图片

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

 最后,我们要将我们定义的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下很方便

在LuaCocossd.h中包含自定义头文件

#ifndef __LUACOCOS2D_H_
#define __LUACOCOS2D_H_

#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}

#include "MySprite.h"


#endif

TOLUA_API int tolua_Cocos2d_open(lua_State* tolua_S);

#endif // __LUACOCOS2D_H_


3、测试

require "AudioEngine" 

-- for CCLuaEngine traceback
function __G__TRACKBACK__(msg)
    print("----------------------------------------")
    print("LUA ERROR: " .. tostring(msg) .. "\n")
    print(debug.traceback())
    print("----------------------------------------")
end

local function main()
    -- run
    local sceneGame = CCScene:create()
    sceneGame:addChild(MySprite:createMS("Icon-144.png"))
    CCDirector:sharedDirector():runWithScene(sceneGame)
end

--xpcall(main, __G__TRACKBACK__)
main()


运行截图如下:

【COCOS2DX-LUA 脚本开发笔记之一】如何使用tolua++将c++方法注册给lua_第3张图片


你可能感兴趣的:(【COCOS2DX-LUA 脚本开发笔记之一】如何使用tolua++将c++方法注册给lua)