Cocos2d x 快取機制 預載入與重複使用

2022-04-10 05:56:49 字數 2749 閱讀 4673

快取在軟硬體設計中是乙個十分常見的優化方法,多用於高效能軟硬體的設計。簡單地說,快取就是利用儲存器的速度等級差異,將低速儲存中使用頻率高的內容載入到高速儲存中,這樣可以有效提高訪問速度。比如將常用的資源從磁碟讀到記憶體,將常用的程式段從記憶體搬到cpu的快取記憶體中。

移動裝置比較常用的是外存到記憶體的快取。儘管大部分手機使用快閃儲存器作為外部儲存已經比pc上磁碟的速度快得多,但相比記憶體而言還是差了兩到三個數量級。從快閃儲存器內讀取一張平均會耗費接近0.1秒的時間,這樣反覆載入將占用非常多的系統資源。而快取機制可以預先載入我們需要的內容到記憶體,並且在之後的操作中重複使用。

快取空間畢竟有限,每乙個快取都應該實現合理的換入換出機制來保證快取中的內容確實是最需要被反覆利用的。同時,快取應該盡量透明化,也就是說,在不主動呼叫的情況下快取就應該生效。幸運的是,我們不需要自己實現快取,因為cocos2d-x已經為我們提供了足夠強大的實現。引擎中存在3個快取類,都是全域性單例模式。

1 cctexturecache

首先是最底層也最有效的紋理快取cctexturecache,這裡快取的是載入到記憶體中的紋理資源,也就是資源。其原理是對加入快取的紋理資源進行一次引用,使其引用計數加一,保持不被清除,而cocos2d-x的渲染機制是可以重複使用同乙份紋理在不同的場合進行繪製,從而達到重複使用,降低記憶體和gpu運算資源的開銷的目的。常用的是如下所示的3個

1

static cctexturecache* sharedtexturecache(); //

返回紋理快取的全域性單例

2 cctexture2d* addimage(const

char* fileimage); //

新增一張紋理到快取中

3void removeunusedtextures(); //

清除不使用的紋理

在這3個介面中,cctexturecache遮蔽了載入紋理的許多細節;addimage函式會返回乙個紋理cctexture2d的引用,可能是新載入到記憶體的,也可能是之前已經存在的;而removeunusedtextures則會釋放當前所有引用計數為1的紋理,即目前沒有被使用的紋理。後面會看到,引用計數的記憶體管理方式為快取的設計帶來了很大的便利。

在這3個介面中,cctexturecache遮蔽了載入紋理的許多細節;addimage函式會返回乙個紋理cctexture2d的引用,可能是新載入到記憶體的,也可能是之前已經存在的;而removeunusedtextures則會釋放當前所有引用計數為1的紋理,即目前沒有被使用的紋理。後面會看到,引用計數的記憶體管理方式為快取的設計帶來了很大的便利。

2 ccspriteframecache

第二個則是精靈框幀快取。顧名思義,這裡快取的是精靈框幀ccspriteframe,它主要服務於多張碎圖合併出來的紋理。這種紋理在一張大圖中包含了多張小圖,直接通過cctexturecache引用會有諸多不便,因而衍生出來精靈框幀的處理方式,即把擷取好的紋理資訊儲存在乙個精靈框幀內,精靈通過切換不同的框幀來顯示出不同的圖案。

ccspriteframecache的常用介面和cctexturecache類似,不再贅述了,唯一需要注意的是新增精靈幀的配套檔案-- 乙個plist檔案和一張大的紋理圖。下面列舉了ccspriteframe cache常用的方法:

1

static ccspriteframecache* sharedspriteframecache(void); //

全域性共享的快取單例

2void addspriteframeswithfile(const

char *pszplist); //

通過plist配置檔案新增一組精靈幀

3void removeunusedspriteframes(void); //

清理無用快取

3 ccanimationcache

最後乙個是ccanimationcache動畫的快取。通常情況下,對於乙個精靈動畫,每次建立時都需要載入精靈幀,按順序新增到陣列,再建立對應動作類,這是乙個非常煩瑣的計算過程。對於使用頻率高的動畫,比如魚的游動,將其加入快取可以有效降低每次建立的巨大消耗。由於這個類的目的和快取內容都非常簡單直接,所以其介面也是最簡單明瞭的,如下所示:

1

static ccanimationcache* sharedanimationcache(void);//

全域性共享的快取單例

2void addanimation(ccanimation *animation, const

char * name);//

新增乙個動畫到快取

3void removeanimationbyname(const

char* name);//

移除乙個指定的動畫

4 ccanimation* animationbyname(const

char* name);//

獲得事先存入的動畫

唯一不一樣的是,這次動畫快取需要我們手動維護全部動畫資訊。也因為載入幀動畫完全是**操作的,目前還沒有配置檔案指導,所以不能像另外兩個快取那樣透明化。實際上,如果考慮到兩個場景間使用的動畫基本不會重複,可以直接清理整個動畫快取。

所以,在場景切換時我們應該加入如下的清理快取操作:

1

void

releasecaches()

2

值得注意的是清理的順序,應該先清理動畫快取,然後清理精靈幀,最後是紋理。按照引用層級由高到低,以保證釋放引用有效。

cocos2dx 紋理快取

快取 cache 機制的原理是什麼?把新加進記憶體的資源做乙個hashmap儲存,每乙個資源加乙個key。每次載入資源,先從快取中尋找,如果找到就直接返回,否則載入到記憶體後再返回。一 自動快取紋理 直接使用display.newsprite filename 建立精靈,引擎內部會自動把紋理載入到快...

cocos2dx 紋理快取

在遊戲中需要載入大量的紋理,這些操作都是很耗記憶體和資源的。當遊戲中有個介面用到的非常多,第一次點進這介面時速度非常慢 因為要載入繪製很多 出現卡頓,我們可以使用texturecache提前非同步載入紋理,等載入結束,進入到這個介面再使用這些速度就會非常快。texture2d 紋理,即加載入記憶體後...

cocos2dx事件分發機制

事件型別 enum class type 事件 型別 enum class type 關於事件 的優先權通過 addeventlistenerwithscenegraphpriority 新增的 優先權為0。通過 addeventlistenerwithfixedpriority 新增的 可以自定義...