Lomohome.com :: 괴발자 모근원


COCOSDenshion (of cocos2d 0.99.5) 의 SimpleAudioEngine 믿고 배경음을 출력했었다.
시뮬레이터에서 잘 되고~ 아이팟 터치 2세대에서 잘 되고~

그런데!! iPhone 4에서만 배경음악이 출력이 안되는것~! (효과음 effect 출력은 잘 되고있는데?!)
로그를 찍어보니 파일의 위치를 읽어오지 못하고 있었다.
참고로 한 Sample 의 TomTheTurret 도 마찬가지의 버그를 내고있었고..
버그인지.. cocos2d 라이브러리를 직접 수정하다가. 곧 업데이트가 될것 같아서 원복하고..
그냥 임시로 업데이트될때까지 SimpleAudioEngine 에서 배경음 재생 실패할 경우 AVAudioPlayer 를 이용해서 재생하도록 했다.
그리고 Fadein/out 시켜주는 메소드 하나 추가하고..
결과는 기종에 관계없이 배경음이 자~알 출력된다.
사운드 엔진은 싱글턴으로 프로그램내에서 어디서든지 불러다 쓸수있게 했다.

SimpleAudioEngine *soundEngine_;



//-- 이 아래에는 AVAudioPlayer를 위한 멤바들.

BOOL isAVAudioPlayer; //한번이라도 AVAudioPlayer 이용하여 배경음을 재생하면 셋팅된다.

//차선책으로 쓰는 AVAudioPlayer

AVAudioPlayer *bgmPlayer;

CGFloat fadeAmt; //Fadeout 감소값.

CGFloat fadeDesc; //Fadein 목표값.

요러한 멤버객체가 인터페이스에 선언이 되어있다 치고..

-(SimpleAudioEngine *) soundEngine

요런식으로 심플 오디오 엔진을 리턴하는 메소드가 있다 하자..

객체 init 해줄때 초기화 꼼꼼히 해주고..

isAVAudioPlayer = NO;

fadeAmt = 0;


dealloc  해줄땐 AVAudioPlayer 로 배경음 재생중이면 꺼주고 죽여주자.

if (self.bgmPlayer != nil) {

[self stopBGMwithAudioPlayer];

}




발로짠 오디오 플레이어 부분.

//배경음 재생을 시작한다.

-(void)playBGMwithAudioPlayer:(NSString*)filename ext:(NSString*)ext volume:(CGFloat)vol{

if (self.isSoundOn) {

[self stopBGMwithAudioPlayer];

if(self.bgmPlayer == nil){

self.bgmPlayer = [self createAudioPlayer:filename ext:ext volume:vol];

//-1 무한반복

self.bgmPlayer.numberOfLoops = -1;

}

[self.bgmPlayer play];

}

}


-(void)stopBGMwithAudioPlayer{

if (self.isSoundOn && self.bgmPlayer != nil) {

NSLog(@"AVAudioPlayer 스탑!");

[self.bgmPlayer stop];

// self.bgmPlayer.currentTime = 0; //rewind

self.bgmPlayer = nil;

}

}



//오디오 플레이어를 만든다.

-(AVAudioPlayer*)createAudioPlayer:(NSString*)filename ext:(NSString*)ext volume:(CGFloat)vol{

NSString *audioPath = [[NSBundle mainBundle]pathForResource:filename ofType:ext];

NSLog(@"새로운 AVAudioPlayer 생성 %@.%@ (%f%%)",filename,ext,vol);

AVAudioPlayer *tmpAudioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:audioPath] error:nil];

tmpAudioPlayer.numberOfLoops = 0;

tmpAudioPlayer.volume = vol;

//소리를 위해 버퍼에 로딩

[tmpAudioPlayer prepareToPlay];

isAVAudioPlayer = YES;

[tmpAudioPlayer autorelease];

return tmpAudioPlayer;

}



//음악을 서서히 죽여준다.

-(void)fadeoutBGMwithAudioPlayer{

    if (self.bgmPlayer!=nil && self.bgmPlayer.volume > 0.01f) {

//2초정도 소리를 줄여주기 위하여

if (fadeAmt == 0) fadeAmt = self.bgmPlayer.volume/20;

        self.bgmPlayer.volume = self.bgmPlayer.volume - fadeAmt;

        [self performSelector:@selector(fadeoutBGMwithAudioPlayer) withObject:nil afterDelay:0.1f];

} else {

NSLog(@"fadeOut finish");

fadeAmt = 0;


[self stopBGMwithAudioPlayer];

}

}



//음악을 서서히 살려준다.

-(void)fadeinBGMwithAudioPlayer{

//NSLog(@"fadeIn %f amount %f desc %f",self.bgmPlayer.volume,fadeAmt,fadeDesc);

    if (self.bgmPlayer!=nil && self.bgmPlayer.volume <= fadeDesc) {

//2초정도 소리를 줄여주기 위하여

if (fadeAmt == 0) fadeAmt = fadeDesc/20;

        self.bgmPlayer.volume = self.bgmPlayer.volume + fadeAmt;

        [self performSelector:@selector(fadeinBGMwithAudioPlayer) withObject:nil afterDelay:0.1f];

} else {

NSLog(@"fadeIn finish");

fadeAmt = 0;

}

}


그리고 SimpleAudioPlayer 를 같이 쓰면서 배경음 재생 실패하면 바로 AVAudioPlayer 를 이용.

//BGM재생.

-(void) playBGM:(NSString*)filename ext:(NSString*)ext volume:(CGFloat)vol{

if (self.isSoundOn){

//soundEngine

if (!isAVAudioPlayer && [self soundEngine] != nil) {

NSLog(@"soundEngine 으로 배경음 재생 시도.");

[self soundEngine].backgroundMusicVolume = vol;

[[self soundEngine] playBackgroundMusic:[[NSBundle mainBundle] pathForResource:filename ofType:ext] loop:YES];

}

NSLog(@"soundEngine : isBackgroundMusicPlaying (%d), isAVAudioPlayer(%d)",[[self soundEngine] isBackgroundMusicPlaying],isAVAudioPlayer);

if (isAVAudioPlayer || [self soundEngine] == nil || ([self soundEngine] != nil && ![[self soundEngine] isBackgroundMusicPlaying])) {

//AudioPlayer

NSLog(@"soundEngine 으로 배경음 재생 실패하여 AVAudioPlayer 시도.");

[self playBGMwithAudioPlayer:filename ext:ext volume:vol];

}

}

}


-(void) fadeinBGM:(NSString*)filename ext:(NSString*)ext volume:(CGFloat)vol{

if (self.isSoundOn){

//soundEngine

if (!isAVAudioPlayer && [self soundEngine] != nil) {

NSLog(@"soundEngine 으로 배경음 페이드 재생 시도.");

[self soundEngine].backgroundMusicVolume = 0;

[[self soundEngine] playBackgroundMusic:[[NSBundle mainBundle] pathForResource:filename ofType:ext] loop:YES];

[CDXPropertyModifierAction fadeBackgroundMusic:2.0f finalVolume:vol curveType:kIT_SCurve shouldStop:NO];

}

if (isAVAudioPlayer || [self soundEngine] == nil || ([self soundEngine] != nil && ![[self soundEngine] isBackgroundMusicPlaying])) {

//AudioPlayer

NSLog(@"soundEngine 으로 배경음 재생 실패하여 AVAudioPlayer 페이드 재생 시도.");

fadeDesc = vol;

[self playBGMwithAudioPlayer:filename ext:ext volume:0];

[self fadeinBGMwithAudioPlayer];

}

}

}


-(void) stopBGM{

if (self.isSoundOn){

if (isAVAudioPlayer) {

[self stopBGMwithAudioPlayer];

} else {

if ([self soundEngine] != nil){

[[self soundEngine] stopBackgroundMusic];

}

}

}

}


-(void) fadeoutBGM {

if (self.isSoundOn) {

if (isAVAudioPlayer) {

[self fadeoutBGMwithAudioPlayer];

} else {

if ([self soundEngine] != nil){

//2 페이드 아웃.

[CDXPropertyModifierAction fadeBackgroundMusic:2.0f finalVolume:0.0f curveType:kIT_SCurve shouldStop:YES];

}

}

}

}


끗. (이랬는데 뭔가 잘못써서 SimpleAudioEngine 에서 출력이 안된거라면 대략 난감.. 삽질의 향기가..)


- (덧) COCOS 2D 1.0rc 버전에서는 수정되었음 -_-......... 
Posted by 모근원
2011년 새해도 밝았고 앱을 만들어 앱스토어에 올리자! 라는 명목으로 맥을 구입한지도 3년째..
그간 맥북 기변에 업그레이드만 줄창 하다가 올해 목표는 진심으로 앱스토어에 앱을 올리는것으로 정했다.

처음엔 유용한 어플을 만들어 올릴까 했는데 눈이 점점 높아져서 어릴적부터 만들어보고 싶었던 게임을 만들기로 했다.
생각해보면 프로그래밍을 처음 배우기 시작했던것도 게임을 만들어보고 싶어서였었는데.. 
그냥 그렇게 10년도 넘게 훌쩍 지나가버렸다.

게임 그래픽은 죽마고우인 민태와 같이 작업하기로 하고 기획하고 기본 메소드들 만들기 시작하는데 하...
이거 cocos2d 라는 게임엔진이 상당히 잘 되어있다.
어플제작만 하고 게임제작은 난생 처음해보는 나도 공부한지 3일만에 쉬운 게임정도는 간단히(실은 그렇게 간단하지 않고 노가다가 필요하지만..) 만들수 있겠더라.

하여간 블로그에 공부하면서 개발하면서 얻은 노하우와 게임제작 기법등을 정리해 올려보기로 했다.
반년이내에 완성해서 앱스토어에 진출하리라~

*사진은 전투씬에서 충돌검사를 테스트하면서 찍은 스크린샷.
Posted by 모근원