【cocos2d】全てのSEをピタッと止める
ゲームにポーズ機能をしばらく前に付けましたが、ポーズした時に鳴っているSEがすぐに鳴り止まず、弾の発射音や爆発音が後を引くのがずっと気になっていました。
BGMはSimpleAudioEngineのpauseBackgroundMusicで一時停止できますが、エフェクトの方はどのエフェクトを止めるのかsoundIDという物を指定する必要があります。
SimpleAudioEngineを使って普通にSEを鳴らすときにはsoundIDあまり意識しないのですが、以前同時発声数を減らしてSEのキレを良くするクラスを作っていたので、これを拡張して全SEを一瞬で停止するstopAllEffects機能を追加しました。
SEのキレを良くする方法につきましてはこちらをご参照ください。
【cocos2d】あえて同時発声を制限してキレのいいSEを鳴らす - 夏までにiPhone アプリつくってみっか!
改良したソースはこちら。
ヘッダファイル
#import <Foundation/Foundation.h> #import "cocos2d.h" @interface SEManager : NSObject { } + (SEManager *)sharedManager; - (void)playSE:(NSString *)filename keyword:(NSString *)keyword; - (void)playSE:(NSString *)filename keyword:(NSString *)keyword pitch:(Float32)pitch pan:(Float32)pan gain:(Float32)gain; - (void)stopAllEffects; @end
メインファイル
#import "SEManager.h" #import "SimpleAudioEngine.h" @implementation SEManager { NSMutableDictionary* _IDTable; } + (SEManager *)sharedManager { static SEManager* sharedInstance = nil; if (!sharedInstance) { sharedInstance = [[self alloc] init]; } return sharedInstance; } - (id)init { if ((self = [super init])) { _IDTable = [NSMutableDictionary dictionary]; } return self; } - (void)playSE:(NSString *)filename keyword:(NSString *)keyword { id IDObject = _IDTable[keyword]; if (IDObject) { [[SimpleAudioEngine sharedEngine] stopEffect:[IDObject integerValue]]; } ALuint soundID = [[SimpleAudioEngine sharedEngine] playEffect:filename]; _IDTable[keyword] = @(soundID); } - (void)playSE:(NSString *)filename keyword:(NSString *)keyword pitch:(Float32)pitch pan:(Float32)pan gain:(Float32)gain { id IDObject = _IDTable[keyword]; if (IDObject) { [[SimpleAudioEngine sharedEngine] stopEffect:[IDObject integerValue]]; } ALuint soundID = [[SimpleAudioEngine sharedEngine] playEffect:filename pitch:pitch pan:pan gain:gain]; _IDTable[keyword] = @(soundID); } - (void)stopAllEffects { for (id key in _IDTable) { ALuint soundID = [_IDTable[key] integerValue]; [[SimpleAudioEngine sharedEngine] stopEffect:soundID]; } } @end
現在鳴っているsoundIDを記憶しているNSMutableDictionaryから全てのsoundIDを読み出してstopEffectに渡しています。
また、ついでに他のメソッドもモダンな記述方法に直してみました。
Objective-Cっぽさが薄まって読みやすくなったと思います。
https://itunes.apple.com/jp/app/travelshooting-jp-toraberushutingu/id917570972?mt=8&uo=4&at=10laCt