From: Cocosbuilder + cocos2d-x-luaproxy Resolve multiple-language text substitution in the CCB editor
We use Cocos2d-x + LUA to develop the game while using Cocosbuilder as the UI editor. You need to place a label in the UI, such as Cclabelttf, but we can't give him text in a different language in the editor. Because we are using LUA, use the Cocos2d-x-luaproxy library to load the CCBI scene in Lua. Therefore, based on the previous "Lua multi-language solution" and some extensions for Luaproxy, a multi-language text replacement scheme for label in the CCB editor is implemented.
Basic principle: In the CCB editor for a label-bound variable name that you want to replace text with, this variable name directly uses the name of the text index (see Lua Multi-Language text solution, such as String_hello). After using Ccbproxy to load the CCBI file in the Lua script, all members of the scenario (member in Ccbproxy, which is actually the object that binds the variable name), are traversed if a variable name such as "String_xxx" is found to be bound. Find the object, transform it into Cclablettf and use the LUA Multi-language text solution to set the text for the current language.
Here's a method I've implemented to replace the label text in the CCB:
function Replaceccbtext (CCBP)
Local members = Ccbp:getmembers ()--CCBP is a Ccbproxy object, note that the GetMembers interface Ccbproxy is not provided, is my own binding, the following will say
Local count = Members:count ()
If Count==0 then return end
Local text = require (' text ').
Local keys = Members:allkeys ()--Gets all key, that is, the variable name of the binding
For i=0,count-1 do-note that the LUA array index 1 begins, but Cocos2d-x's LUA bindings still need to use an array index starting with 0, possibly because the binding code is tolua++ automatically generated so it can't be converted.
Local key = Tolua.cast (Keys:objectatindex (i), "ccstring"): Getcstring ()
--log (' key is '. Key)
Local start = String.find (key, ' string_ ')--is the special variable name we marked.
If Start==1 Then
Local obj = Members:objectforkey (key)
obj = Tolua.cast (obj, "Cclabelttf")--Gets the object and transitions to Cclabelttf
If Obj~=nil Then
Local Strid = _g[key]--to get the value of this variable, for example, the value of String_hello is 1, notice that I'm using a lua5.1,lua5.2 I've been told that the environment has changed, I haven't studied it.
If Strid==nil Then
--log (' warning! text index not found for%s ', key)
Obj:setstring (key)--If the text index does not exist, set the label directly to the value of the key, causing attention
Else
--log (' Replace string for key:%s,id:%d ', Key,strid)
Obj:setstring (Text (Strid))--Replaces the text of the current language corresponding to the index
End
End
End
End
End
Working with stories:
--Load the main menu CCBI
Local CCBP = Ccbproxy:create ()
Local n = ccbp:readccbfromfile ("MAINMENU.CCBI")
Local scene = Ccscene:create ()
Scene:addchild (Tolua.cast (N, "Ccnode"))
--Replace text
Replaceccbtext (CCBP)
A few questions:
1 gets all the objects that are bound to the variable from the ccbproxy using Ccbproxy::getmembervariables, but Ccbproxy does not bind the method, so I've tied it myself
Add in Tolua_ccbproxy.h
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;
}
Luaopen_luaproxy.cpp in Tolua_beginmodule (L, "Ccbproxy"), add the following:
Tolua_function (L, "GetMembers", tolua_ccbproxy_getmembers);
2 I only use the Cclabelttf this one control, and did not use Cclabelbmfont, in fact, I wrote before:
obj = Tolua.cast (obj, "Cclabelttf") or Tolua.cast (obj, "Cclabelbmfont")
If Obj~=nil Then
If I bind a cclabelbmfont to a variable name, I hope this place is properly cast as a Cclabelbmfont object, but the fact is that he cast it as Cclabelttf. Why, then? Because the object is not Cclabelttf, tolua.cast (obj, "Cclabelttf") does not return to nil. Look at Tolua's code to find that he is just a pointer to a strong turn, even if you write a non-existent "cclablexxx", will not return to nil. The reason this place does not have an error (but does not work) is that both Cclabelbmfont and Cclabelttf have setstring methods. If you change to "cclabelxxx" will be an error setstring for nil.
For the moment, I use a control because there are still problems (3) to solve.
3 Sometimes we should not only exchange this content according to the language, you may need to change the font, or even change the control. For example, we may use Cclabelbmfont for English, but it may only be cclabelttf for Chinese. This problem can be replaced by the original control after the acquisition of the solution, on the basis of replaceccbtext to modify. Of course, if each control is set to a different font is more cumbersome, you can only manually get the individual special control and replace the font (using Getnodewithtype)