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论坛,故用英文写的,但英文实在不是我强项,所以敬请谅解)