#ゲームにBGMは欠かせない。
ゲームBGMで「懐かしの名曲集」がYoutubeで人気なのもうなずける。
しかしせっかくの名曲もボタンをタップした瞬間に「ぶっ」と切れてしまっては情緒もへちまもない。
偉大な音楽に敬意を払い、FadeOutでかっこよく曲を停止させる方法をシェアする。
まず曲を鳴らす際にはAVAudioPlayerを使うが、viewDidLoad内でPathを取得したり
ごちゃごちゃするのは美しくない。
[SEEventhandler sharedManaber] bgmSoundPlay: @"opening.mp3"];
って感じで1行でばちっと呼び出したいので、
ゲーム内で使うイベント(音を鳴らしたり、他にもゲーム内でのイベントを発生させる)を
まとめて扱うシングルトンを作成する。
※AVAudioPlayerの使用方法は「yuky_az」さんの下記のストックを参考にさせて頂きました。
この場を借りて、お礼を申し上げます。
http://qiita.com/yuky_az/items/085e30c159cafa8dac1c
#ソースコード実例
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface SEEventHandlerManager : NSObject
//***** Class Method *****
+(SEEventHandlerManager *)sharedManager;
//***** Instance Method *****
-(void)bgmSoundPlay: (NSString *)fileName;
-(void)bgmStopWithFadeOut;
@end
#import "SEEventHandlerManager.h"
@interface SEEventHandlerManager ()
@property(nonatomic) NSMutableArray* soundArray;
@property(nonatomic) float soundVolume;
@end
@implementation SEEventHandlerManager
//--------------------------------------------------------------//
#pragma mark -- Initialize --
//--------------------------------------------------------------//
static SEEventHandlerManager *sharedInstance = nil;
+(SEEventHandlerManager *)sharedManager
{
if (!sharedInstance) {
sharedInstance = [[SEEventHandlerManager alloc] init];
}
return sharedInstance;
}
- (id) init
{
self = [super init];
if (self) {
_soundArray = [[NSMutableArray alloc] init];
_soundVolume = 1.0;
}
return self;
}
-(void)bgmSoundPlay: (NSString *)fileName
{
NSString *soundPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:fileName];
NSURL* soundUrl = [NSURL fileURLWithPath:soundPath];
AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
audioPlayer.numberOfLoops = -1;
audioPlayer.volume = _soundVolume;
audioPlayer.delegate = (id)self;
[_soundArray insertObject:audioPlayer atIndex:0];
[audioPlayer prepareToPlay];
[audioPlayer play];
}
-(void)bgmStopWithFadeOut
{
AVAudioPlayer* currentPlayer = [_soundArray objectAtIndex:0];
if (currentPlayer.volume > 0.1) {
currentPlayer.volume = currentPlayer.volume - 0.1;
[self performSelector:@selector(bgmStopWithFadeOut) withObject:nil afterDelay:0.1];
}else{
[currentPlayer stop];
[_soundArray removeAllObjects];
}
}
@end
bgmStopWithFadeOutがFadeOut処理になっている。
別に難しいことはなく、メソッドをVolumeが0になるまで呼び出しつづけ、0になったらオブジェクトを破棄する。
配列に格納したのは後に音を複数鳴らす際に、必要になるかもしれないと考えてのこと。
#シングルトンのおかげでこれがうれしい
また、シングルトンによって下記の利点を得る。
■利点:画面遷移に関係なく、好きなタイミングで音を再生(停止)できる。
#シミュレータでは動かないよ・・・
また、上記のソースコードは下記のシミュレータ上では動作しなかった。
OS X 10.9.2
XCode 5.1.1
iOSシミュレータ 7.1(iPhone Retina 4-inch 64bit)
「Cannot find executable for CFBundle CertUIFramework.axbundle」なる
エラーが発生していた。
参考URL:http://stackoverflow.com/questions/18888059/cannot-find-executable-for-cfbundle-certuiframework-axbundle
これはXCodeのバグのようで、実機でシミュレータを動作させた場合には正常に音楽が再生されたので、テストする際にはご注意を。
では!HappyBoyがお送りしました!