cocosBuilder + cocos2d-x-LuaProxy 解决在CCB编辑器中的label的多国语言文本替换
我们使用cocos2d-x + lua来开发游戏,同时使用cocosBuilder作为UI编辑器。在UI中需要放置label,例如CCLabelTTF,但是在编辑器中我们无法给他设定不同语言的文本。由于我们使用的是Lua,使用cocos2d-x-LuaProxy这个库来在lua中载入ccbi场景。因此基于之前的 "lua多国语言解决方案",并针对luaProxy做一些扩展,实现了一个CCB编辑器中label的多国语言文本替换方案。
基本的原理:在CCB编辑中对于想替换文本的label绑定变量名,这个变量名直接使用文本索引的名字(见lua多国语言文本解决方案,如string_hello)。在lua脚本中使用CCBProxy载入ccbi文件之后,对该场景中所有的member (CCBProxy中的member,其实就是绑定了变量名的对象)进行遍历,如果发现绑定了像"string_xxx"这样的变量名,就把这个对象找出来,转型为CCLableTTF并使用"lua多国语言文本解决方案"的方法设置当前语言的文本。
下面是我实现的一个方法,用来替换CCB中的label文本:
function replaceCCBText(ccbp)
local members = ccbp:getMembers() --ccbp是一个CCBProxy对象,注意getMembers接口CCBProxy并没有提供,是我自己绑定的,下面会说
local count = members:count()
if count==0 then return end
local text = require('text').get
local keys = members:allKeys() --获取所有key,也就是绑定的变量名
for i=0,count-1 do --注意lua数组索引1开始,但cocos2d-x的lua绑定中依然需要使用从0开始的数组索引,可能由于绑定代码是tolua++自动生成的因此没法转换吧
local key = tolua.cast(keys:objectAtIndex(i),"CCString"):getCString()
--log('key is ' .. key)
local start = string.find(key,'string_') --是我们标记的特殊的变量名吗?
if start==1 then
local obj = members:objectForKey(key)
obj = tolua.cast(obj,"CCLabelTTF") --取得对象并转型为CCLabelTTF
if obj~=nil then
local strId = _G[key] --取得这个变量对应的值,例如string_hello的值是1,注意我使用的是lua5.1,lua5.2据说环境有所改变,我还没研究过
if strId==nil then
--log('warning! text index not found for %s',key)
obj:setString(key) --如果文本索引不存在,则直接将label设置为key的值,引起注意
else
--log('replace string for key:%s,id:%d',key,strId)
obj:setString(text(strId)) --替换为该索引对应的当前语言的文本
end
end
end
end
local ccbp = CCBProxy:create()
local n = ccbp:readCCBFromFile("mainmenu.ccbi")
local scene = CCScene:create()
//CCBProxy::getMemberVariables
static int tolua_CCBProxy_getMembers(lua_State *l){
#ifndef TOLUA_RELEASE
tolua_Error err;
if(!tolua_isusertype(l, 1, "CCBProxy", 0, &err)){
tolua_error(l,"#ferror in function 'CCBProxy.getMembers'.",&err);
return 0;
}
#endif
CCBProxy *p = (CCBProxy *)tolua_tousertype(l, 1, NULL);
CCDictionary* tolua_ret = (CCDictionary*)p->getMemberVariables();
int nID = (tolua_ret) ? (int)tolua_ret->m_uID : -1;
int* pLuaID = (tolua_ret) ? &tolua_ret->m_nLuaID : NULL;
toluafix_pushusertype_ccobject(l, nID, pLuaID, (void*)tolua_ret,"CCDictionary");
return 1;