Some of my experiences for cocos2d-x+lua

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:

 Some of my experiences for cocos2d-x+lua_第1张图片

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

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 = 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

 

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

  ……

end

require '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)

end

table.insert(package.loaders, 2, mymoduleLoad)


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

 



你可能感兴趣的:(lua,function,path,menu,button,callback,iphone,lua)