Cocos2dx + lua分享

2020-08-12 16:49:50

一、 閉包
閉包:使得內部函數能夠呼叫外部函數的區域性變數
local newrequire = function(folder)
return function(file)
Return require(folder…src…file)
end
End
Game.require = newrequire(「gameSk」)
Import(「.fish」) 替換爲 game.require(「fish」)

2.通過閉包也可以實現
二、 .和:的區別

  1. 變數存取用 .
  2. 函數存取
    Function Fish.create(_type)
    Function Fish:create(_type)
    用冒號(:)呼叫函數時,會預設傳一個值(呼叫者自身self)作爲第一個參數; 用點(.)呼叫函數時,則沒有
    用冒號(:)建立函數時,會預設新增一個參數self,作爲第一個參數;
    用點(.)呼叫函數時,則沒有
    . 和 :函數可以相互呼叫,但需要正確的傳遞self值。
    三、 Table
    元表的元方法
    __add 運算子 +
    __sub 運算子 -
    __mul 運算子 *
    __ div 運算子 /
    __mod 運算子 %
    __unm 運算子 -(取反)
    __concat 運算子 …
    __eq 運算子 ==
    __lt 運算子 <
    __le 運算子 <=
    __call 當函數呼叫
    __tostring 轉化爲字串
    __index 呼叫一個索引
    __newindex 給一個索引賦值
    (1) lua通過元表來實現面相物件
    __index
    呼叫table的一個不存在的索引時,會使用到元表的__index元方法
    查詢__index元方法表,若有該索引,則返回該索引對應的值,否則返回nil

__index 作爲函數則是呼叫,作爲table則是查詢

Local _mt = {}
_mt.__index = function(_tb,key)
Print(「this is」 … key)
End

t = {1,2,3}
Print(t.key)
Setmetatable(t,_mt)
Print(t.key)

Local _mt = {}
_mt.__index = {key = 「this is test」}

t = {1,2,3}
Print(t.key)
Setmetatable(t,_mt)
Print(t.key)

__nexindex
當爲table中一個不存在的索引賦值時,會去呼叫元表中的__newindex元方法
作爲函數則是呼叫,作爲table則是新增k/v,但是不改變table
rawget 和 rawset
有時候我們希望直接改動或獲取表中的值時,就需要rawget和rawset方法了。
rawget可以讓你直接獲取到表中索引的實際值,而不通過元表的__index元方法。
Local _mt = {}
_mt.__newindex = function(_tb,key,value)
rawset(_tb,key,value)
end

實現只讀table
local mt = {
__newindex =
function (t,k,v)
error(「attempt to update a read-only table」,2)
end
}
Local tb = {}

setmetatable(tb,mt) – 設定代理table的元表
目前程式碼採用cocos2dx封裝的class方法
Local classA = class(「classA」) ==>>
寫法1
classA.__index = classA
Function classA.create()
Local obj = {}
setmetatable(obj,classA)
Return obj
End

Function classA:create()
Local obj = {}
self.__index = self
setmetatable(obj,classA)
Return obj
End

—寫法2 cocos2dx節點
Local classA= require(「classA」)
Local classB= require(「classB」)
Function appendtable(src,dst)
For k,v in pairs(dst)
Src[k] = v
End
end
Function classC.create()
Local obj = cc.Node:create()
Appendtable(obj,classA)
Appendtable(obj,classB)
Return obj
End
Function classC:init()
End
四、 … 可變參數
Local functiona = function(…)
Local param = {…}
Print(param[1],param[2])
End
–如果變長參數中故意傳入nil
–那麼就要使用select函數來存取變長參數列表了.
–select得以參數如果傳入的是整數n, 返回的是第i個元素開始到最 後一個元素結束的列表
–如果傳入的是"#",則返回參數列表的總長度
select(n, …) --數位n表示起點,select(n, …)返回從起點n到結束的可變參數
Local _idx = 3
… 是 0,1,2,3,4,5
Print(select(_idx,…)) 2,3,4,5
Print(select(「#」…)) 5

五、 多返回值
(1) Local function ()
Local a,b = 1,1
Return a,b
End
(2) Lua 呼叫 c++ 返回值
Static int Lua_call_c(L)
{
Lua_pushnum(L,1)
Lua_pushnum(L,2)
Return 2
}
Local par1,par2 = lua_call_c()
六、 安全判斷
local function getData(_key)
If data == nil then return nil end
return data[_key]
end
Local _value = getData(_key)
Print(「_value =」,_value)
七、 常見執行錯誤
attempt to index upvalue (類沒有返回)
attempt to index local ‘self’ (a nil value) (.和:弄混了)
attempt to call method ‘Func’ (a nil value) (寫錯了–大小寫或者筆誤)
attempt to call global ‘getScheduler’ (寫錯了–大小寫或者筆誤)
syntax error during pre-compilation (語法錯誤 常見在 end對不上)
Invalid cobj’ in function ‘lua_cocos2dx_Node_setVisible’(cobj爲空了或者已經被銷燬了,debug會報錯,release會崩潰)
attempt to perform arithmetic on local ‘x’ (a nil value) (與nil的x進行了運算操作)
八、 Apk 大小及優化

Lib 包含各平臺需要的so檔案
Assets 應用所需要的資源(lua程式碼+資源)
Res 未編譯到的資源
Resources.arsc 已編譯到的資源
Meta_inf 簽名檔案
Classs.dex 程式碼二進制檔案
(一) 包體大小
(1) .so 保證apk中只有一套架構 對浮點運算有高需求的採用 armable-v7a否則採
用armeable
libcocos2dx角度縮減包體是剔除掉不用的模組
ccConfig.h 中
#define CC_USE_WEBP 0 不需要的
#define CC_USE_WEBP 1 需要的
或者 jni/Application.mk中
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=0 -DCC_ENABLE_BOX2D_INTEGRATION=0 -DCC_USE_3D_PHYSICS=0 -DCC_USE_WEBP=0 -DCC_USE_TIFF=0 -DCC_USE_NAVMESH=0 -std=c++11 -fsigned-char -Wno-extern-c-compat
(2) .遊戲內資源(聲音+圖片)
你需要很清楚當前自己專案什麼地方佔的體積最多,例如動畫序列多少MB,聲音佔用,普通UI佔用

  1. .聲音(.mp3)
    .音訊有三個因素影響檔案大小,分別是音訊檔格式,位元率,和樣本率
    .採樣率 96-128kbps ,位元率44kHz
  2. .圖片(coco2dx支援的格式)
    A. png
    B. jpg
    C. pvr/etc壓縮紋理
    D. webp
    E. s3tc atitc tga s3tc用於pc
    壓縮紋理不需要cpu解碼,能直接被gpu接收
    解析速度 webp<jpg<png< etc/pvr
    體積 webp < jpg < png/ etc/pvr
    採用壓縮紋理需根據平臺準備對應的2份紋理
    Webp沒使用

png24/32是無壓縮格式的RGBA通道,品質是最好的,真彩色儲存
JPG是有失真壓縮的格式,不支援ALPHA通道,但是是安裝包最小的。

但JPG會進行記憶體解壓,也就是說,一個JPG讀入到記憶體後,與png24/32讀入記憶體是一樣的。

目前採用方式png+jpg
A. 採用工具對資源進行
B. 採用png壓縮工具等
C. 降低圖片品質,png32->png8
D. 使用特定的壓縮格式的圖片
E. 如果專案中幀序列動畫佔的比較多,那麼可以採取減幀
F. 縮放圖片,九宮格,圖片對稱翻轉
G. 採用骨骼動畫
H. 分包 (公用 – 大廳 – 遊戲)
I. 隔幾個版本清理資源
Tiny androidstudio外掛
https://github.com/meili/TinyPIC_Gradle_Plugin
(3).原生相關

  1. 第三方庫 公司的庫檔案去掉沒用的模組,避免重複匯入

  2. 刪除dex中的垃圾指令、通過混淆來減少dex的大小

  3. 語言優化 .android {
    defaultConfig {
    resConfigs 「zh」, 「zh-rCN」
    }
    }
    (二) 遊戲記憶體(絕大部分記憶體被紋理佔用)
    cocos2d裏面紋理載入分爲兩個階段:1.從圖片檔案中建立一個UIImage物件;2.以這個建立好的UIImage物件來建立CCTexture2D物件。這意味着,當一個紋理被載入的時候,在短時候內,它會消耗兩倍於它本身記憶體佔用的記憶體大小.

  4. .畫素格式
    A. rgba8888
    B. rgba4444
    C. rgb565 (沒有透明度)適合背景圖及規則圖片)
    D. rgb5a1 不支援半透明
    Cocos2dx 對非壓縮紋理預設採取rgba8888 ,可以通過
    cc.Texture2D:setDefaultAlphaPixelFormat設定

  5. 圖片聲音的釋放
    ccexp.autoEngine.uncache
    cc.animationcache:destoryInstance
    cc.spriteframe:getInstance():removeUnusedSpriteFrames
    cc.director:getInstance():gettexturecache():removeUnusedTextures()
    目前產品遊戲模式比較單一,每個場次資源和聲音沒有區別,基本上沒有在紋理和聲音釋
    放上有操作
    (三) 效能
    (1) 卡頓

  6. .聲音檔案和資原始檔預載入
    cc.driector:getInstance():getTextureCache():addImageAsync()
    ccs.armaturedatamanger:getInstance():addArmatureFileinfoasync()
    ccexp.autoEngine.preload

  7. .頻繁播放的音效檔案時間要短
    (2) 發熱
    A. 降低遊戲回圈複雜度
    B. 降低drawcall數量(合圖、動態調整影格率)
    C. 粒子使用不合理
    D. 頻繁的io操作
    下圖爲渲染流程
    繼承於Layout控制元件,支援裁剪的話會有單獨的渲染佇列
    Z_order 分爲3種 <0 =0 >0