cocos2dx場景切換記憶體問題

2021-06-23 04:18:30 字數 3936 閱讀 5733

最近在做乙個cocos2d-x的專案時,遇到乙個問題,就是在pc上執行都是ok的,可是在ipad和andriod上面,在場景切換時時常會掛掉,用蘋果自帶的instruments工具檢測時,發現在場景正常執行時,記憶體大概保持在三四十兆,但是在場景切換時,一瞬間會達到七八十兆,遇到一些素材比較多或者層比較多的場景,則會達到一百多兆。大家知道在ipad1上面,記憶體最大是128m,那麼這個程式如果在ipad1上面執行,肯定會經常掛掉。遇到問題,只能一步步分析,一步步找。

(1)先把所有場景的retain的東西檢查一遍,看看在onexit的時候有沒有release掉,這個檢查完以後,還是會crash,所以這種情況不是根源。

(2)對於有好幾個層的場景,在init的時候,先載入第乙個層的,而不是把所有層的東西全部載入完,在切換層的時候再載入相對應的層,這種方法果然有效,當切換到這個場景的時候,記憶體果然減少了一半左右。但是對於只有乙個層的場景來說,在切換時也是會掛,所以問題還沒有找完全。

(3)我們知道,在每個場景裡面會有乙個init函式,乙個onentertransitiondidfinish函式,乙個onexit函式,init實現一些初始化工作,onentertransitiondidfinish在init之後執行,onexit在場景退出時**init時分配的資源。在除錯時發現乙個很有趣的現象,那就是從場景切換場景二時,在切換的一瞬間會記憶體會非常高,但是過了一段時間後,記憶體會回到乙個平穩的狀態,譬如切換記憶體會達到80m,切換過後記憶體會降到50m。分析原因,懷疑是上乙個場景記憶體還沒有釋放,然後這乙個場景記憶體已經分配,所以兩個疊加在一起,就比較高了。所以我便在第乙個場景的onexit函式中加乙個斷點,在第二個場景的init和onentertransitiondidfinish函式中各加乙個斷點,然後執行程式,發現程式先到第二個場景的init中,然後再回到第乙個場景的onexit中,最後才到第二個場景的onentertransitiondidfinish中。我才恍然大悟,原來在場景切換時,不是馬上會執行第乙個場景的onexit函式,而是先到第二個場景的init中載入資源,然後回到第乙個場景中釋放資源,最後才是到onentertransitiondidfinish中。

最終解決方法:

把一些資源的初始化放到onentertransitiondidfinish中進行,那麼究竟應該把那些資源放到onentertransitiondidfinish中初始化,而那些資源又只能放到init中呢?

(1)像背景圖這種只能放到init中,像場景切換時要看到的一些精靈,必須放到init中,不然場景切換時會看不到背景或者一些精靈。

(2)象精靈的一些動畫,動作,可以放到onentertransitiondidfinish中來初始化。

舉個例子:

譬如乙隻船在划動,那麼船這只精靈在場景切換時要展示,所以必須放在init中

//小船精靈的載入

[cpp]view plaincopy

m_boataction = ccsprite::spritewithfile(s1_little_boat1);  

addchild(m_boataction);  

m_boataction->setposition( ccpointmake(s.width/2, s.height/2+130));  

m_boataction->setscale(0.3);  

m_boataction->retain();  

而船划動的動作,就可以放到onentertransitiondidfinish來初始化和執行

[html]view plaincopy

ccsize s= 

ccdirector

::shareddirector()-

>

getwinsize();  

ccanimation* animation

= ccanimation

::animation();  

char framename[100] = ;  

for( int i=1

;i<

=5;i++)  

ccactioninterval*  action

= ccanimate

::actionwithduration(2, animation, false);  

repeataction

= ccrepeatforever

::actionwithaction(action);  

repeataction->

retain();  

通過這三步,基本上就可以避免在場景切換記憶體過而導致crash的情況
快取釋放  

如果遊戲有很多場景,在切換場景的時候可以把前乙個場景記憶體全部釋放,防止總記憶體過高.  

cctexturecache::sharedtexturecache()->removealltextures(); 釋放到目前為止所有載入的  

cctexturecache::sharedtexturecache()->removeunusedtextures(); 將引用計數為1的釋放掉cctexturecache::sharedtexturecache()->removetexture(); 單獨釋放某個  

ccspriteframecache 與 cctexturecache 釋放的方法差不多。  

場景切換:  

值得注意的是釋放的時機,一般在切換場景的時候釋放資源,如果從a場景切換到b場景,呼叫的函式順序為  

1、如果沒有切換效果,則為b的init(),a的onexit(),b的onenter()  

2、如果有切換效果,則為b的init(),b的onenter(),a的onexit()  

有時強制釋放全部資源時,會使某個正在執行的動畫失去引用而彈出異常,可以呼叫ccactionmanager::sharedmanager()->removeallactions();來解決。  

Cocos2d x之場景切換

在很多rpg遊戲中大部分存在多個場景,如開始的歡迎介面 選單介面 戰鬥介面 場景切換只需要呼叫ccdirector shareddirector replacescene s s為新的場景,這句 的是含意,是用新的場景s去替換掉舊的場景,但是這樣的場景替換,來得太突然,給使用者的感覺不太好,我們需要...

cocos2dx切換場景

分享一下cocos2dx切換場景函式 場景a切換到場景b,有切換特效 呼叫順序如下 aaabababa a 建構函式 a onenter a onentertransitiondidfinish b 建構函式 a onexittransitiondidstart b onenter a onexit...

Cocos2d x中場景切換

ccscene場景切換 場景的切換效果 1 執行場景 1 ccscene pscene helloworld scene 2 pdirector runwithscene pscene 2 替換場景 1 ccscene pscene scenetestscene scene 2 ccdirector...