1、在Cocos2d-x遊戲中使用SimpleAudioEngine支援音效,發現從系統訊息處(即視窗關閉按鈕)退出經常會引發異常;
2、在遊戲內通過某個功能表按鈕退出時,按鈕回呼函數中加入如下代碼後則退出時不會異常:
void GameMenu::menuExitCallback(CCObject* pSender)
{
SimpleAudioEngine::sharedEngine()->end();//這句話起了作用。
CCDirector::sharedDirector()->end();
}
3、經分析在AppDelegate裡加入如下代碼就好了
AppDelegate::~AppDelegate()
{
SimpleAudioEngine::sharedEngine()->end();
}
4、分析過程:
從系統訊息處(即視窗關閉按鈕)退出時,CCEGLView類的訊息處理函數WindowProc會收到WM_CLOSE訊息然後還會收到WM_DESTORY訊息;
從遊戲內某個功能表按鈕退出時,CCEGLView類的訊息處理函數WindowProc會收到WM_DESTROY訊息。
CCEGLView::WindowProc()
{
case WM_CLOSE:
CCDirector::sharedDirector()->end();
break;
case WM_DESTROY:
destroyGL();
PostQuitMessage(0);
break;
}
因為這兩個訊息的處理都在引發異常的時序之前,這樣第一想法就是在此處加上SimpleAudioEngine::sharedEngine()->end()。
編譯後你會發現碰上了麻煩,CCEGLView類屬於libcocos2d庫,libCocosDenshion反而要依賴它,如果在CCEGLView類中調用SimpleAudioEngine類方法,實際上就是libcocos2d庫要反過來使用依賴於它自己的庫,這個不合理。
再分析發現:退出引發異常之前,還有兩個地方可以調用SimpleAudioEngine::sharedEngine()->end()。
一個是主情境主布景層的onExit方法,即根節點的CCNode::OnExit方法;
一個則是應用程式的解構函式AppDelegate::~AppDelegate()。
相比之下AppDelegate::~AppDelegate()裡加入SimpleAudioEngine::sharedEngine()->end()調用比較具有通用性。
因為情境OnEixt可能還會發生在情境切換的時候,除非切換情境的時候需要把音效庫中已載入的所有音效和背景樂全部清掉,不然這麼做是沒有必要的。