一、 閉包
閉包:使得內部函數能夠呼叫外部函數的區域性變數
local newrequire = function(folder)
return function(file)
Return require(folder…src…file)
end
End
Game.require = newrequire(「gameSk」)
Import(「.fish」) 替換爲 game.require(「fish」)
2.通過閉包也可以實現
二、 .和:的區別
__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佔用
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).原生相關
第三方庫 公司的庫檔案去掉沒用的模組,避免重複匯入
刪除dex中的垃圾指令、通過混淆來減少dex的大小
語言優化 .android {
defaultConfig {
resConfigs 「zh」, 「zh-rCN」
}
}
(二) 遊戲記憶體(絕大部分記憶體被紋理佔用)
cocos2d裏面紋理載入分爲兩個階段:1.從圖片檔案中建立一個UIImage物件;2.以這個建立好的UIImage物件來建立CCTexture2D物件。這意味着,當一個紋理被載入的時候,在短時候內,它會消耗兩倍於它本身記憶體佔用的記憶體大小.
.畫素格式
A. rgba8888
B. rgba4444
C. rgb565 (沒有透明度)適合背景圖及規則圖片)
D. rgb5a1 不支援半透明
Cocos2dx 對非壓縮紋理預設採取rgba8888 ,可以通過
cc.Texture2D:setDefaultAlphaPixelFormat設定
圖片聲音的釋放
ccexp.autoEngine.uncache
cc.animationcache:destoryInstance
cc.spriteframe:getInstance():removeUnusedSpriteFrames
cc.director:getInstance():gettexturecache():removeUnusedTextures()
目前產品遊戲模式比較單一,每個場次資源和聲音沒有區別,基本上沒有在紋理和聲音釋
放上有操作
(三) 效能
(1) 卡頓
.聲音檔案和資原始檔預載入
cc.driector:getInstance():getTextureCache():addImageAsync()
ccs.armaturedatamanger:getInstance():addArmatureFileinfoasync()
ccexp.autoEngine.preload
.頻繁播放的音效檔案時間要短
(2) 發熱
A. 降低遊戲回圈複雜度
B. 降低drawcall數量(合圖、動態調整影格率)
C. 粒子使用不合理
D. 頻繁的io操作
下圖爲渲染流程
繼承於Layout控制元件,支援裁剪的話會有單獨的渲染佇列
Z_order 分爲3種 <0 =0 >0