Some of my experiences for cocos2d-x+lua

来源:互联网 发布:linux命令和shell关系 编辑:程序博客网 时间:2024/05/31 13:16

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.

1      Resource folder structure

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 screendeviceInfo[deviceIphone]  = {path = 'images/normal/',}--hddeviceInfo[deviceIphoneHD] = {path= 'images/hd/'}--paddeviceInfo[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 nameend

2      Lua callback

For cocos2d-x, it used the string to call a global lua function, like this:

menuPopupItem:registerScriptHandler("menuCallbackClosePopup")

It can’t use the upvalue and it will confusedif I used many callback functions.

I extends this function, it needn’t modify the cocos2d-x source codes.

2.1    Call format

2.1.1  Example 1

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


2.1.2  Example 2

(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)

2.1.3  Example 3(support call a global function)

menuPopupItem:registerScriptHandler("menuCallbackClosePopup")

2.2    Callbackmng.lua file

cbmaps={}tagmaps={}idx = 0function 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 nameendfunction UnregisterAll(name)  cbmaps = nil  cbmaps = {}  tagmaps={}endfunction UnregisterCB(name)  cbmaps[name] = nilendfunction UnregisterTag(tag)  for _, v in pairs(tagmaps[tag] or {}) do     cbmaps[v] = nil  end  tagmaps[tag] = {}endfunction 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 -1end 

2.3    My LuaEngine class

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);  ……}
 

2.4   Init

In AppDelegat e.cpp

    m_pLuaEngine= new CMyLuaEngine;

3      Debug

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  ……endrequire 'pyramid'  ……


If it runed on windows, set OS_TYPE=4

 

3.1    The startup lua file

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 


3.2    call the startup lua file

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
 

3.3    Running

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.

 

4      Make the lua package

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)endtable.insert(package.loaders, 2, mymoduleLoad)

 (由于本文要链接到cocos2d-x论坛,故用英文写的,但英文实在不是我强项,所以敬请谅解)

 



原创粉丝点击