Cocos2d-x Lua運(yùn)行流程

Cocos2d-lua 是 Cocos2d-x引擎添加了Lua綁定的版本静尼。使用C++和Cocos2d-x引擎開(kāi)發(fā)時(shí)殿托,編寫(xiě)的代碼是直接調(diào)用Cocos2d-x引擎的API支鸡,因?yàn)镃ocos2d-x引擎也是使用C++編寫(xiě)的暖侨,所以無(wú)需進(jìn)行語(yǔ)言轉(zhuǎn)換椭住。而使用Lua和Cocos2d-x編碼時(shí),編寫(xiě)的代碼必須通過(guò)LuaEngine引擎執(zhí)行字逗,LuaEngine引擎封裝了Cocos2d-x引擎的API京郑,所以相當(dāng)于使用Lua腳本在調(diào)用Cocos2d-x的API。

Cocos2d-lua
Cocos2d-lua

主入口文件 main.lua

main.lua啟動(dòng)文件是Cocos2d-lua項(xiàng)目默認(rèn)主入口葫掉,項(xiàng)目啟動(dòng)時(shí)默認(rèn)首先執(zhí)行main.lua文件些举。

運(yùn)行流程

步驟0:設(shè)置 編譯后的客戶端開(kāi)始執(zhí)行時(shí),使用FileUtils加載Luac文件的提示是否顯示俭厚。

cc.FileUtils:getInstance():setPopupNotify(true)

步驟1:將源代碼src目錄和資源res目錄添加到文件搜索路徑

cc.FileUtils:getInstance():addSearchPath("src/")
cc.FileUtils:getInstance():addSearchPath("res/")
  • 通過(guò)addSearchPath()方法設(shè)置源代碼和資源的搜索路徑

步驟2:加載配置文件讀取配置

require "config"
  • config.lua配置文件用于定義初始化所使用的全局變量
  • require()方法表示引入一個(gè)文件户魏,使用require()方法加載文件的過(guò)程會(huì)檢查文件的lua語(yǔ)法,同時(shí)會(huì)完成被加載文件內(nèi)部變量的初始化。

步驟3:執(zhí)行初始化

加載cocos/init.lua文件叼丑,根據(jù)config.lua配置文件對(duì)cocos2d-lua框架進(jìn)行初始化关翎。

require "cocos.init"

步驟4:加載app目錄下MyApp.lua文件,創(chuàng)建App對(duì)象并調(diào)用run()函數(shù)幢码。

local function main()
  require("app.MyApp"):create():run()
end
  • 調(diào)用對(duì)應(yīng)classCreate()方法創(chuàng)建對(duì)象笤休,并執(zhí)行run()方法。
  • run()函數(shù)用于配置第一個(gè)進(jìn)入的場(chǎng)景症副,默認(rèn)為MainScene店雅。
  • 通過(guò)載入的app.MyApp模塊創(chuàng)建一個(gè)MyApp實(shí)例,并調(diào)用實(shí)例的run()方法贞铣,此時(shí)將啟動(dòng)執(zhí)行MyApp腳本闹啦。

垃圾回收機(jī)制

local function main()
  -- 運(yùn)行一個(gè)完整的垃圾回收周期
  collectgarbage("collect") 
  collectgarbage("setpause", 100) 
  collectgarbage("setstepmul", 5000)
end

collectgarbage("collect")

運(yùn)行一個(gè)完整的垃圾回收周期

collectgarbage("count")

返回當(dāng)前程序使用的內(nèi)存總量,以KB為單位辕坝。

collectgarbage("restart")

若垃圾收集器停止則重新運(yùn)行

collectgarbage("step")

進(jìn)行一次垃圾回收迭代窍奋,第二個(gè)參數(shù)值越大表示一次迭代的時(shí)間越長(zhǎng),如果本次迭代時(shí)垃圾回收的最后一次迭代則函數(shù)返回true酱畅。

collectgarbage("stop")

停止運(yùn)行垃圾收集器

collectgarbage("setpause", 100)

設(shè)置垃圾收集暫停時(shí)間變量的值琳袄,值由第二個(gè)參數(shù)指出,該值被用于控制垃圾收集器被Lua自動(dòng)內(nèi)存管理再次運(yùn)行之前需要的等待時(shí)長(zhǎng)纺酸。當(dāng)其小于100時(shí)意味著收集器在新周期開(kāi)始前不再等待窖逗。其值越大垃圾收集器被運(yùn)行的頻率越低,越不主動(dòng)餐蔬。當(dāng)其值200時(shí)碎紊,收集器在總使用內(nèi)存數(shù)量達(dá)到上次垃圾收集時(shí)的2倍再開(kāi)啟新的收集周期。因此樊诺,根據(jù)程序不同的特征仗考,可以通過(guò)修改該值使得程序達(dá)到最佳的性能。

collectgarbage("setstepmul", 5000)

設(shè)置垃圾收集器步長(zhǎng)倍增器的值词爬,步長(zhǎng)倍增器stepmul用于控制垃圾收集器相對(duì)內(nèi)存分配的速度秃嗜。數(shù)值越大收集器工作越主動(dòng),同時(shí)也增加了垃圾收集每次迭代步長(zhǎng)的大小缸夹。值小于100可能會(huì)導(dǎo)致垃圾器1個(gè)周期永遠(yuǎn)不能結(jié)束痪寻,建議不要這樣設(shè)置。默認(rèn)值為200虽惭,表示垃圾收集器運(yùn)行的速率是內(nèi)存分配的2倍橡类。

錯(cuò)誤捕獲

local status, msg = xpcall(main, __G__TRACKBACK__)
if not status then
    print(msg)
end

xpcall(調(diào)用函數(shù), 錯(cuò)誤捕獲函數(shù))

Lua提供xpcall函數(shù)來(lái)捕獲異常,當(dāng)錯(cuò)誤發(fā)生時(shí)芽唇,Lua會(huì)在棧釋放前調(diào)用錯(cuò)誤處理函數(shù)顾画,因此可使用debug庫(kù)收集錯(cuò)誤信息取劫。常用debug處理函數(shù)包括:

  • debug.debug 給出Lua的提示符,可手工查看錯(cuò)誤發(fā)生時(shí)的情況研侣。
  • debug.traceback 控制器解釋器用來(lái)構(gòu)建錯(cuò)誤信息的函數(shù)

程序啟動(dòng)后谱邪,xpcall(表示以“保護(hù)模式”調(diào)用函數(shù))會(huì)被執(zhí)行,它會(huì)調(diào)用main()函數(shù)庶诡。如果發(fā)生錯(cuò)誤惦银,則會(huì)調(diào)用__G__TRACKBACK__()函數(shù)。

配置文件 config.lua

  • DEBUG
    設(shè)置輸出調(diào)試信息選項(xiàng)末誓,即通過(guò)控制不同的print()輸出信息扯俱。
    0 表示關(guān)閉
    1 表示打印少量調(diào)試信息
    2 表示打印標(biāo)準(zhǔn)完整的調(diào)試信息
  • CC_USE_FRAMEWORK
    設(shè)置是否使用quick框架,其中包括MVC框架喇澡。
  • CC_SHOW_FPS
    設(shè)置是否顯示FPS等顯卡信息
  • CC_DISABLE_GLOBAL
    設(shè)置是否允許定義全局字段
  • CC_DESIGN_RESOLUTION
    設(shè)置不同分辨率

默認(rèn)應(yīng)用 MyApp.lua

應(yīng)用文件:app/MyApp.lua

local  MyApp = class("MyApp", cc.load("mvc").AppBase)

function MyApp:onCreate()
  math.randomseed(os.time())
end

return MyApp
  • MyApp類繼承自mvc中的cc.mvc.AppBase類迅栅,系統(tǒng)自動(dòng)查找packages/mvc/AppBase.lua文件,AppBaseQuick框架自帶的一個(gè)MVC的應(yīng)用程序基礎(chǔ)類晴玖,此類為應(yīng)用程序提供一些邏輯控制上的功能读存,如進(jìn)入場(chǎng)景、切換場(chǎng)景等呕屎。
  • class()方法本身是Quick框架定義的用于創(chuàng)建自定義lua類的函數(shù)让簿,function class(classname, super)函數(shù)參數(shù)classname表示類名,super表示父類或創(chuàng)建對(duì)象實(shí)例的函數(shù)秀睛。

MVC

MVC是一種組合設(shè)計(jì)模式拜英,被廣泛應(yīng)用在帶有圖形交互的用戶界面程序(GUI)開(kāi)發(fā)中。MVC的宗旨在于分離關(guān)注點(diǎn)(SoC)琅催,將界面表現(xiàn)和業(yè)務(wù)邏輯分離。SoC原則在現(xiàn)代軟件工程中是一個(gè)非常重要的設(shè)計(jì)理念虫给。對(duì)于實(shí)際問(wèn)題藤抡,要?jiǎng)澐植煌年P(guān)注點(diǎn),且關(guān)注點(diǎn)之間必須隔離開(kāi)來(lái)抹估,這樣才能達(dá)到 更好的代碼重用缠黍,以獲得魯棒性、可適配性药蜻、可維護(hù)性瓷式。

MVC

Cocos2d本身并不是基于MVC的理念設(shè)計(jì)的,在Cocos2d中CCScene语泽、CCLayer贸典、CCSprite等類都是CCNode的子類,開(kāi)發(fā)流程基本是這樣的:

  1. 通過(guò)應(yīng)用程序代理類來(lái)初始化第一個(gè)即主場(chǎng)景
  2. 場(chǎng)景中實(shí)例化一個(gè)或多個(gè)布景圖層踱卵,并將其添加進(jìn)去廊驼。
  3. 布景圖層中實(shí)例化一個(gè)或多個(gè)精靈据过,并將其添加進(jìn)去。
  4. 場(chǎng)景處理用戶輸入妒挎,例如Touch事件和加速計(jì)的改變绳锅。同時(shí)更新布景圖層和精靈,讓精靈運(yùn)行一個(gè)或多個(gè)動(dòng)作等酝掩。
  5. 場(chǎng)景中運(yùn)行一個(gè)游戲循環(huán)(一般是1/60更新一次)鳞芙,然后布景圖層和精靈在游戲循環(huán)中做更新和游戲邏輯。

對(duì)于手游而言期虾,界面UI的布局與顯示都是由View負(fù)責(zé)的原朝,點(diǎn)擊事件手勢(shì)滑動(dòng)等操作是由Controller來(lái)處理的,游戲中需要的數(shù)據(jù)是由Model負(fù)責(zé)的彻消。

local MyApp = class("MyApp", cc.load("mvc").AppBase)

/src/packages/mvc/AppBase.lua 中定義了一個(gè)AppBase基類竿拆,作為所有Quick游戲的Lua入口,由player新建的工程宾尚,有個(gè)app/MyApp.lua文件就是繼承自AppBase類丙笋。

AppBase功能類似于iOS工程中的 AppDelegate.m 實(shí)現(xiàn)的功能:

  • 程序前后臺(tái)切換事件的接收和分發(fā)
  • framework 提供程序退出接口
  • 提供創(chuàng)建 sceneview 的接口,并約定其存放路徑煌贴。

垃圾收集

local function main()
  collectgarbage("collect")
  collectgarbage("setpause", 100)
  collectgarbage("setstepmul", 5000)
end

本地存儲(chǔ)

--[[
客戶端本地存儲(chǔ)
場(chǎng)景:游戲中需在本地存儲(chǔ)數(shù)據(jù)御板,根據(jù)存儲(chǔ)的數(shù)據(jù)類型調(diào)用接口
設(shè)置客戶端本地?cái)?shù)據(jù)庫(kù),本地的UserDefault.xml會(huì)存在相應(yīng)數(shù)據(jù)牛郑。
--]]
-- 獲取客戶端本地存儲(chǔ)數(shù)據(jù)
function GetClientUserData(key, dataType)
    local type = string.lower(dataType)
    if type == "bool" then
        return cc.UserDefault:getInstance():getBoolForKey(key)
    elseif type == "int" then
        return cc.UserDefault:getInstance():getIntegerForKey(key)
    elseif type == "float" then
        return cc.UserDefault:getInstance():getFloatForKey(key)
    elseif type=="double" then
        return cc.UserDefault:getInstance():getDoubleForKey(key)
    elseif type == "string" then
        return cc.UserDefault:getInstance():getStringForKey(key)
    end
end
-- 設(shè)置客戶端本地存儲(chǔ)數(shù)據(jù)
function SetClientUserData(key, value, dataType)
    local type = string.lower(dataType)
    if type == "bool" then
        return cc.UserDefault:getInstance():setBoolForKey(key, value)
    elseif type=="int" then
        return cc.UserDefault:getInstance():setIntegerForKey(key, value)
    elseif type=="float" then
        return cc.UserDefault:getInstance():setFloatForKey(key, value)
    elseif type=="double" then
        return cc.UserDefault:getInstance():setDoubleForKey(key, value)
end

聲音系統(tǒng)

聲音引擎:SimpleAudioEngine

音樂(lè)格式 iOS和Android均可采用MP3格式
AudioEngine.preload("bg.mp3") 預(yù)加載背景音樂(lè)
AudioEngine.playMusic("bg.mp3", true) 播放背景音樂(lè)怠肋,true為循環(huán)。
AudioEngine.stopMusic() 停止播放音樂(lè)
AudioEngine.pauseMusic() 暫停播放音樂(lè)
AudioEngine.resumeMusic() 恢復(fù)播放音樂(lè)
AudioEngine.isMusicPlaying() 判斷音樂(lè)是否播放
AudioEngine.setMusicVolumn(0.5) 設(shè)置音樂(lè)音量
AudioEngine.getMusicVolumn() 獲取音樂(lè)音量

音效格式 iOS可采用MP3或WAV,Android可采用OGG格式淹朋。
AudioEngine.preloadEffect("effect.mp3") 預(yù)加載音效
AudioEngine.playEffect("effect.mp3") 播放音效
AudioEngine.pauseAllEffect() 暫停所有音效的播放
AudioEngine.resumeAllEffect() 繼續(xù)播放所有音效
AudioEngine.resumeEffect(id) 繼續(xù)播放指定ID的音效
AudioEngine.stopEffect(id) 停止播放指定ID的音效
AudioEngine.stopAllEffect() 停止播放所有音效
AudioEngine.setEffectsMusicVolumn(0.5) 設(shè)置音效音量
AudioEngine.getEffectsVolumn() 獲取音效音量

-- LUA使用方式
cc.SimpleAudioEngine:getInstance():playMusic("bg.mp3")

-- 重新設(shè)置為上次聲音
local musicVolumn = cc.UserDefault:getInstance():getFloatForKey("MusicVolumn", 1)
cc.SimpleAudioEngine:getInstance():setMusicVolumn(musicVolumn)
cc.SimpleAudioEngine:getInstance():setEffectsMusicVolumn(musicVolumn)

殺蟲(chóng)游戲

玩法:初始化5個(gè)血量笙各,隨機(jī)生成爬向洞的昆蟲(chóng),累積進(jìn)入5個(gè)即結(jié)束游戲础芍。

殺蟲(chóng)游戲
組織結(jié)構(gòu)

布景層生命周期

生命周期順序流程

  1. init() 初始化布景層調(diào)用杈抢,在類初始化時(shí),僅會(huì)調(diào)用一次仑性。
  2. onEnter() 進(jìn)入布景層時(shí)調(diào)用惶楼,可能會(huì)發(fā)生多次。

Cocos2dx類似于ObjectC一樣诊杆,有兩種方式來(lái)申請(qǐng)內(nèi)存創(chuàng)建對(duì)象歼捐,一種是靜態(tài)函數(shù)create(),一種是在自身的init()中晨汹,在這兩種函數(shù)中申請(qǐng)內(nèi)存創(chuàng)建對(duì)象能讓程序正常運(yùn)行豹储,但是當(dāng)對(duì)象將要去展現(xiàn)或被添加到另一個(gè)容器時(shí),它會(huì)調(diào)用onEnter()函數(shù)宰缤,所以最好不要在onEnter()中做內(nèi)存方面的操作颂翼。

  1. onEnterTransitionDidFinish() 進(jìn)入布景層且過(guò)渡動(dòng)畫(huà)結(jié)束時(shí)調(diào)用
  2. onExit() 退出布景層時(shí)調(diào)用
  3. onExitTransitionDidStart() 退出布景層且開(kāi)始過(guò)渡動(dòng)畫(huà)時(shí)調(diào)用
  4. clearup() 布景層對(duì)象被清除時(shí)調(diào)用晃洒,整個(gè)布景層銷毀時(shí)調(diào)用。

簡(jiǎn)單來(lái)說(shuō)

  • 進(jìn)入布景層時(shí):init()->onEnter()->onEnterTransitionDidFinish()
  • 退出布景層時(shí):onExit()->onExitTransitionDidStart()->init()

onEnteronExit在Lua中不會(huì)因?yàn)楣?jié)點(diǎn)的addremove而直接被調(diào)用朦乏, 當(dāng)子節(jié)點(diǎn)被父節(jié)點(diǎn)的addremove時(shí)球及,會(huì)發(fā)送enterexit的消息,所以需要初始化節(jié)點(diǎn)的時(shí)候呻疹,監(jiān)聽(tīng)消息并在收到消息后調(diào)用onEnteronExit吃引。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市刽锤,隨后出現(xiàn)的幾起案子镊尺,更是在濱河造成了極大的恐慌,老刑警劉巖并思,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庐氮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡宋彼,警方通過(guò)查閱死者的電腦和手機(jī)弄砍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)输涕,“玉大人音婶,你說(shuō)我怎么就攤上這事±晨玻” “怎么了衣式?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)檐什。 經(jīng)常有香客問(wèn)我碴卧,道長(zhǎng),這世上最難降的妖魔是什么乃正? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任螟深,我火速辦了婚禮,結(jié)果婚禮上烫葬,老公的妹妹穿的比我還像新娘。我一直安慰自己凡蜻,他們只是感情好搭综,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著划栓,像睡著了一般兑巾。 火紅的嫁衣襯著肌膚如雪沧侥。 梳的紋絲不亂的頭發(fā)上坠宴,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音汰蓉,去河邊找鬼。 笑死堂油,一個(gè)胖子當(dāng)著我的面吹牛修档,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播府框,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吱窝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了迫靖?” 一聲冷哼從身側(cè)響起院峡,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎系宜,沒(méi)想到半個(gè)月后照激,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盹牧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年俩垃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欢策。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吆寨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出踩寇,到底是詐尸還是另有隱情啄清,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布俺孙,位于F島的核電站辣卒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏睛榄。R本人自食惡果不足惜荣茫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望场靴。 院中可真熱鬧啡莉,春花似錦、人聲如沸旨剥。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)轨帜。三九已至魄咕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蚌父,已是汗流浹背哮兰。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工毛萌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人喝滞。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓阁将,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親囤躁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子冀痕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容