cocos2dx清除緩存
1. cocos2d texturecache 怎麼管理內存
1. 介紹
紋理緩存是將紋理緩存起來,之後的繪制工作就能減少內存。每一個緩存圖像的大小,顏色和區域范圍都是可以被修改的。這些信息都是存儲在內存中,不用在每一次繪制的時候都發送給GPU。
2. CCTextureCache
Cocos2d通過調用CCTextureCache或者CCSpriteFrameCache來緩存精靈的紋理。
當這個精靈調用CCTextureCache 或 CCSpriteFrameCache的方法的時候,cocos2dx將使用紋理緩存來創建一個CCSprite。所以你可以預先將紋理載入到緩存中,這樣你在場景中使用的時候就非常方便了。怎麼樣載入這些紋理就看你自己的想法。例如,你可以選擇非同步載入方式,這樣你就可以為loading場景增加一個進度條。
當你創建一個精靈,你一般會使用CCSprite::create(pszFileName)。假如你去看CCSprite::create(pszFileName)的實現方式,你將看到它將這個圖片增加到紋理緩存中去了:
bool CCSprite::initWithFile(const char *pszFilename)
{
CCAssert(pszFilename != NULL, "Invalid filename for sprite");
CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(pszFilename);
if (pTexture)
{
CCRect rect = CCRectZero;
rect.size = pTexture->getContentSize();
return initWithTexture(pTexture, rect);
}
// don't release here.
// when load texture failed, it's better to get a "transparent" sprite then a crashed program
// this->release();
returnfalse;
}
上面代碼顯示一個單例在控制載入紋理。一旦這個紋理被載入了,在下一時刻就會返回之前載入的紋理引用,並且減少載入的時候瞬間增加的內存。(詳細API請看CCTextureCache API)
3. CCSpriteFrameCache
CCSpriteFrameCache單例是所有精靈幀的緩存。使用spritesheet和與之相關的xml文件,我們可以載入很多的精靈幀到緩存中,那麼之後我們就可以從這個緩存中創建精靈對象了。
和這個xml相關的紋理集一般是一個很大的圖片,裡麵包含了很多小的紋理。下面就是一個紋理集的例子:
有三種方式來載入紋理集到CCSpriteFrameCache中:
(1)載入一個xml(plist)文件
(2)載入一個xml(plist)文件和一個紋理集
(3)通過CCSpriteFrame和一個精靈幀的名字
具體完整API請看CCSpriteFrameCache API。
樣例:
CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile(「hello.plist」, 「hello.png」);
使用緩存的原因就是減少內存,因為當你使用一個圖片創建一個精靈的時候,如果這個圖片不在緩存中,那麼就會將他載入到緩存中,當你需要用相同的圖片來新建精靈的時候,就可以直接從緩存中取得,而不用再去新分配一份內存空間。
4. CCSpriteFrameCache 對比 CCSpriteBachNode
(1) 最好是盡可能的使用spritesheets (CCSpriteBatchNodes)。這樣的方式是減少draw的調用次數。Draw的調用是非常耗時的。每一個batchnode調用一次draw就可以繪制上面所有的節點,而不是每一個節點的draw都單獨調用一次,
(2) CCSpriteBatchNode渲染所有的子節點只需要一次,只需要調用一次draw。那就是為什麼你需要把精靈載入batch node的原因,因為可以統一一起渲染。但是只有這個精靈使用的紋理包含在batch node中的才可以添加到batch node上,因為batch node一次只渲染這相同的紋理集。
(3) 假如你把精靈添加到其他的節點上。那麼每一個精靈就會調用自己的draw函數,batch node就沒起作用了。
(4) CCSpriteBatchNode也是一個常用節點。你可以從場景中像其他節點一樣移除掉。紋理集和精靈幀都被緩存在CCTextureCache 和 CCSpriteFrameCache單例中。假如你想要從內存中移除紋理集和精靈幀,那麼你不得不通過緩存類來完成這個工作。
轉載
2. cocos 性能優化方案求助
一.內存優化
1.內存泄漏
在最近的項目中使用了C11的智能指針,經過一年的使用證明這是不是一個成功的選擇。雖然已經沒了自己管理的煩躁,但是增加了內存泄漏的幾率。畢竟不是所有人都能完全理解和掌握shared_ptr的使用。 建議使用cocos2dx自帶的輕量級智能指針,採用了引用計數,並且沒有了C11智能指針循環引用及其他使用容易導致引用計數異常的問題。
2.緩存(材質緩存,精靈幀緩存)管理
這里必須要引入過渡場景,用於removeunused的緩存,然後預載入下一個場景需要使用的資源。 並且cocos2dx提供了api可以查看內存中所有的緩存,做為開發必須能完全熟知內存中的這些緩存,能及時判斷哪些材質是多餘的。
這里要多提的一點是,不使用jpg,android使用pkm,ios使用pvr是非常有必要的。特別對於8000*8000超大地圖。
3.高性能對象池
傳統對象池只有一個list保存所有對象,每次使用循環遍歷查找未使用的對象。
這里的優化是新增一個隊列保存所有可使用的對象。每次對象使用完進行push_front的操作,每次使用通過pop_front獲取。
二.CPU優化
1.近似數學函數
開方、三角函數近似替換演算法,計算兩點間的距離(曼哈頓距離、牛頓迭代或者使用平方數值做比較),位移運算(針對頻繁的乘除2的n次冪)等。
2.演算法
在演算法的選擇上其實滲透在我們的每一個即使非常小的功能模塊,對於不是專門研究演算法的我們,演算法更多是一種意識。拒絕所有的時間復雜度O(n*n)的操作,永不高估CPU的計算性能,在現有的操作上力求更低的計算量。 然後有的放矢的去選擇適合自己項目的演算法。
3.分幀
分幀是比較壞的情況,因為這時候優化可能到了末尾。確實有一些cpu密集型的計算需要分幀甚至開線程來解決了。
PS:空間換時間。其實上面三條包括我的高性能的高斯模糊演算法那篇文章,基本上對於cpu的優化核心都是空間換時間。
三.GPU優化(Drawcall優化)
1.超大圖的切片
切片太小對於drawcall是非常有影響的,目前使用最大化切片2048*2048,並且圖片使用壓縮格式使用存在於緩存中。
2.合圖(多攝像機場景)
對於攝像機比較多的場景,由於底層是遍歷攝像機,每個攝像機執行一次場景的全部繪制。
所以在合圖的時候需要按照攝像機來分層合圖,不要把不同攝像機的圖片合到一起。
做為開發要能夠根據看到的場景預估drawcall數量,在判斷出異常的時候分步優化層級drawcall數量。
3. cocos2dx的3d 怎麼獲取cc對象
cocos2dx的3d獲取cc對象:通過對導演、場景、層和節點的剖析,現在我們已經可以寫出一個完整的游戲體系了。
獲取精靈的方法可以考慮將你的所有精靈加入到一個單例層里作為精靈管理層,加進去的時候定義好TAG值,方便隨時隨地可根據TAG值取到想要的精靈。
觸摸坐標否在精靈上第一個思路是先獲取你的sprite的boundingBox,和你觸摸點坐標,判斷觸摸點坐標是否包含於sprite的區域內。
主要功能:
圖形渲染:包括2D圖片、文字、序列幀動畫、骨骼動畫、粒子、特效等渲染,在v3.3版本開始加入簡單的3D模型渲染和3D動畫。
音頻功能:支持游戲內的音效和背景音樂播放控制。
資源管理:圖片、音頻和腳本資源的載入、緩存及釋放。
物理模塊:通過集成 2D 物理引擎 Box2D 和 Chipmunk、3D物理引擎 Bullet 以支持游戲的物理特性。
場景管理:通過場景、層、精靈三層主要結構,對游戲的場景樹進行創建和銷毀管理。