I recently submitted an IOS application(IQ Pyramid), which is based on cocos2d-x(http://www.cocos2d-x.org/ ), most of which code is written in lua.
The itunes link of the app is:
http://itunes.apple.com/us/app/iq-pyramid/id460315207?ls=1&mt=8(US)
http://itunes.apple.com/cn/app/iq-pyramid/id460315207?mt=8(China)
The below is some of my experences for cocos2d-x+lua.
I didn’t recommend using the default HD support, because the resource folder is very ugly.
My folder is:
Lua call function:
sprite = cocos2d.CCSprite:spriteWithFile(QueryImgName(img))
QueryImgName function:
local deviceInfo = {}
--normal screen
deviceInfo[deviceIphone] = {path = 'images/normal/',}
--hd
deviceInfo[deviceIphoneHD] = {path= 'images/hd/'}
--pad
deviceInfo[deviceIpad] = {path = 'images/pad/'}
function QueryImgName(name)
local path = deviceInfo[deviceType].path
if cocos2d.kLanguageChinese== cocos2d.CCApplication:getCurrentLanguage() then
local chres = path..'ch/'..name
if FileExistsResource(chres)then
return chres
end
end
local hires = path..name
if FileExistsResource(hires)then
return hires
end
return name
end
For cocos2d-x, it used the string to call a global lua function, like this:
menuPopupItem:registerScriptHandler("menuCallbackClosePopup")
I extends this function, it needn’t modify the cocos2d-x source codes.
local function CreateGameMenu(blockMenu)
-- flip
local flipb = cocos2d.CCMenuItemImage:itemFromNormalImage(utils.QueryImgName('flip_button.png'), utils.QueryImgName('flip_button_click.png'))
local function OnFlip()
blockMenu:OnFlip(flipb)
end
flipb: registerScriptHandler(RegisterCB(1,OnFlip))
mn:addChild(flipb,10)
end
(obj is a lua class object):
local item = cocos2d.CCMenuItemFont:itemFromString("start")
item:registerScriptHandler(RegisterCB(LayoutTag, obj.OnStart, obj))
local menu = cocos2d.CCMenu:menuWithItem(item)
menuPopupItem:registerScriptHandler("menuCallbackClosePopup")
cbmaps={}
tagmaps={}
idx = 0
function RegisterCB(tag,cb, obj )
idx = idx + 1
local name = 'zzcb'..idx
cbmaps[name] = {obj=obj, cb=cb}
tagmaps[tag] = tagmaps[tag] or {}
table.insert(tagmaps[tag], name)
return name
end
function UnregisterAll(name)
cbmaps = nil
cbmaps = {}
tagmaps={}
end
function UnregisterCB(name)
cbmaps[name] = nil
end
function UnregisterTag(tag)
for _, v in pairs(tagmaps[tag] or {}) do
cbmaps[v] = nil
end
tagmaps[tag] = {}
end
function Call(cbname,...)
local cb = cbmaps[cbname]
if cb then
if cb.obj then
return cb.cb(cb.obj, ...)
else
return cb.cb(...)
end
else
if _G[cbname] then
return _G[cbname](...)
end
end
print('unknown cb:'..cbname)
return -1
end
It need use the myself Luaengine class.
The all interfaces of CCScriptEngineProtocol like the below codes:
bool CMyLuaEngine::executeCallFuncN(const char *pszFuncName, cocos2d::CCNode *pNode )
{
lua_State* L = m_scriptModule->getLuaState();
lua_getglobal(L, "Call");
tolua_pushstring(L,pszFuncName);
tolua_pushusertype(L, (void*)pNode, "cocos2d::CCNode");
int error = lua_pcall(d_state,1,0,0);
……
}
In AppDelegat e.cpp
m_pLuaEngine= new CMyLuaEngine;
For easy debug, I used some tips.
For the top of every lua file, I add the below codes:
if OS_TYPEand OS_TYPE==4 then
package.loaded['pyramid']= nil
……
end
require 'pyramid'
……
If it runed on windows, set OS_TYPE=4
The startup lua file is homepage.lua
if OS_TYPEand OS_TYPE==4then
function OnStartHome()
package.loaded['menu']= nil
require "menu"
cocos2d.CCDirector:sharedDirector():pushScene(CreateSysMenu())
end
local sc = cocos2d.CCScene:node();
local starthome = cocos2d.CCMenuItemFont:itemFromString("start")
starthome:registerScriptHandler("OnStartHome")
local mn = cocos2d.CCMenu:menuWithItem(starthome)
mn:alignItemsVertically();
sc:addChild(mn)
cocos2d.CCDirector:sharedDirector():runWithScene(sc);
else
require "menu"
cocos2d.CCDirector:sharedDirector():runWithScene(CreateSysMenu());
end
In AppDelegate.cpp
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM== CC_PLATFORM_IOS)
string path = CCFileUtils::fullPathFromRelativePath("homepage.lua");
CCScriptEngineManager::sharedScriptEngineManager()->getScriptEngine()->executeScriptFile(path.c_str());
#endif
The mdified lua codes will work after I click the back button and re-enter it.
It will improve the efficiency becauseI needn’t restart the program.
You can make all lua files to a package.The package can be any formats, such as sqlite,zip,etc.
And you need to provide a function to unpack it.
function mymoduleLoad(m)
local buf=getbuffer(m) --unpack the package and get the module buffer
return loadstring(buf)
end
table.insert(package.loaders, 2, mymoduleLoad)
(由于本文要链接到cocos2d-x论坛,故用英文写的,但英文实在不是我强项,所以敬请谅解)