游戏开发的时候用到了sfx作为报警音一直looping, 然后发现了个问题,报警音在响了一段时间后消失了, 其中没有触发任何事件
后来我模拟了这个环境, 在场景初始的位置开始播放报警音
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("sfx_timesup.wav", true);
然后在场景按钮上添加了按钮音:
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("sfx_bt.wav", false);
整个例子就这么简单:
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
USING_NS_CC;
CCScene* HelloWorld::scene(){
CCScene *scene = CCScene::create();
HelloWorld *layer = HelloWorld::create();
scene->addChild(layer);
return scene;
}
bool HelloWorld::init(){
if ( !CCLayer::init() ) {
return false;
}
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("sfx_timesup.wav", true);
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(visibleSize.width/2 ,visibleSize.height/2));
pCloseItem->setScale(10);
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
return true;
}
void HelloWorld::menuCloseCallback(CCObject* pSender){
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("sfx_bt.wav", false);
}
它会完整复现我的bug, 只要你按按钮31次, 就会发现报警音消失了
后来找到cocos2dx引擎代码里面音频部分, 不断调试, 发现每次播放音效都会自加1, 一共分配给sfx 32个通道,而且对于每个通道默认并不检测是否正在播放或者循环
于是发现了个参数 nonInterruptible 不中断, 这个变量如果为true的话, 会进行playing检测, 默认初始化又是false, 我想这点效率没必要节省当成默认值吧, 或者有可能是引擎本身不完善, 而强制覆盖旧音效的吧,不过内部也提供了方法来开启这个参数, 不用去修改初始化,找到CDAudioManager.m这个文件的init初始化代码
然后在:
soundEngine = [[CDSoundEngine alloc] init];
后面加上一句
[soundEngine setSourceGroupNonInterruptible:0 isNonInterruptible:TRUE];
就解决了这个问题, 不论你再点击按钮多少次也不会终止警告音的播放了
这是我的求助帖,当然也是自己解决的,也谢谢cocos2d开发者的协助
https://stackoverflow.com/questions/26945149/there-has-a-bug-with-openal-or-cocos2dx
废话:在这里面找断点很难找,他们的数组,数值,结构都是直接用malloc直接分配的,搞得找断点十分费劲, 唉~~