使用Cocos2D-X+Lua开发游戏,都会封装一些自定义的接口,供Lua逻辑端调用。参考cocos2d-x的lua项目大体明白是lua调用c++,是通过LuaCocos2d.cpp解析代码的,形成lua对c++接口的一个映射关系。 直接看LuaCocos2d.cpp 肯定不好下手,cocos2d-x提供了tolua++这个工具生成这种cpp文件的。 为了不影响源码,我们重新生成一个LuaGame.cpp文件,自定义精灵类SSSprite,添加精灵点击事件。
一、自定义类
在后面附件中有SSSprite.h与SSSprite.cpp文件。
二、生成解释文件
这样封装了点击的精灵类。然后使用tolua++工具生成解释文件LuaGame(cocos2d-x生成的是解释文件是LuaCocos2d),tolua++工具目录:\tools\tolua++
有window和mac,这边就用window的工具:tolua++.rar。解压到当前文件生成tolua++.exe
1 apk文件编写
规则如下:
1)enum keeps the same 保持枚举类型不变
2)remove CC_DLL for the class defines, pay attention to multi inherites 删除CC_DLL的类定义、改为多继承
3)remove inline keyword for declaration and implementation 删掉声明的inline关键词
4)remove public protect and private 删除访问限定
5)remove the decalration of class member variable 删除类的成员变量
6)keep static keyword 保留statiic关键词
7)remove memeber functions that declared as private or protected 成员函数声明为私人或受保护的都删掉
就是保留需要提供给lua的,不需要提供的就不添加了。可以参考当前目录下面的pkg文件。
LuaGame.pkg文件
这两个文件和tolua++.exe在同一个目录。
2 生成LuaGame文件
cmd -> cd 到tolua++.exe目录。输入命令:
tolua++.exe -tCocos2d -o LuaGame.cpp LuaGame.pkg
3、将生成的LuaGame.cpp文件放到工程目录下面,(LuaGame.cpp在案例源码中)
编写LuaGame.h文件
4.注意事项是 注册 tolua_LuaGame_open()
如果是生成的新接口是在LuaCocos2d.cpp里面就不用注册了,而我们新生成的luaGame需要注册的。
可以查看 CCLuaStack中 bool init(void) 不改动源码,我们直接写个注册接口
在AppDelegate::applicationDidFinishLaunching()中调用这个函数。
5 lua中调用
一、自定义类
在后面附件中有SSSprite.h与SSSprite.cpp文件。
二、生成解释文件
这样封装了点击的精灵类。然后使用tolua++工具生成解释文件LuaGame(cocos2d-x生成的是解释文件是LuaCocos2d),tolua++工具目录:\tools\tolua++
有window和mac,这边就用window的工具:tolua++.rar。解压到当前文件生成tolua++.exe
1 apk文件编写
规则如下:
1)enum keeps the same 保持枚举类型不变
2)remove CC_DLL for the class defines, pay attention to multi inherites 删除CC_DLL的类定义、改为多继承
3)remove inline keyword for declaration and implementation 删掉声明的inline关键词
4)remove public protect and private 删除访问限定
5)remove the decalration of class member variable 删除类的成员变量
6)keep static keyword 保留statiic关键词
7)remove memeber functions that declared as private or protected 成员函数声明为私人或受保护的都删掉
就是保留需要提供给lua的,不需要提供的就不添加了。可以参考当前目录下面的pkg文件。
下面是SSSprite.pkg文件 (回调函数的参数是LUA_FUNCTION)
1
2
3
4
5
6
|
class
SSSprite :
public
CCSprite,
public
CCTargetedTouchDelegate
{
void
setSelectorWithTarget(CCObject *target, SEL_MenuHandler selector);
void
addClickedHandeler(LUA_FUNCTION nHandler);
static
SSSprite* createSprite(
const
char
* pszFileName,
const
char
* pzSlected);
}
|
1
2
|
$#include
"LuaGame.h"
$pfile
"SSSprite.pkg"
|
这两个文件和tolua++.exe在同一个目录。
2 生成LuaGame文件
cmd -> cd 到tolua++.exe目录。输入命令:
tolua++.exe -tCocos2d -o LuaGame.cpp LuaGame.pkg
3、将生成的LuaGame.cpp文件放到工程目录下面,(LuaGame.cpp在案例源码中)
编写LuaGame.h文件
1
2
3
4
|
#pragma once
extern
"C"
{#include
"tolua_fix.h"
} #include
"cocos2d.h"
#include "CCLuaEngine.h"#include "SSSprite.h"/* Exported function */
TOLUA_API
int
tolua_LuaGame_open (lua_State* tolua_S);
|
如果是生成的新接口是在LuaCocos2d.cpp里面就不用注册了,而我们新生成的luaGame需要注册的。
可以查看 CCLuaStack中 bool init(void) 不改动源码,我们直接写个注册接口
1
2
3
4
5
6
7
8
9
10
|
int
initLuaGame(){
CCLuaStack *pStack = CCLuaEngine::defaultEngine()->getLuaStack();
if
(NULL == pStack) {
return
0;
}
lua_State *state = pStack->getLuaState();
if
(NULL == state) {
return
0;
} tolua_LuaGame_open(state);
}
|
5 lua中调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
local function clickedSprite(tag)
-- sssprite clicked
CCLuaLog(
"-----tag-----"
..tag)
end
local layerMenu = CCLayer:create()
-- bg CCSprite
local bg = CCSprite:create(
"farm.jpg"
)
layerMenu:addChild(bg)
bg:setPosition(ccp(origin.width/2,origin.height/2))
-- 按钮精灵 SSSprite
local sprite = SSSprite:createSprite(
"btn_1.png"
,
"btn_2.png"
)
sprite:setPosition(ccp(origin.width/2,origin.height/2))
sprite:setTag(100)
-- 注册点击事件
sprite:addClickedHandeler(clickedSprite)
layerMenu:addChild(sprite)
|