줄리애비의 소소한 이야기
아이폰,맥,모바일개발,비디오게임하기 개발이나 게임에 관련된 이야기, 소통 장소
2010년 6월 24일 목요일
게이머즈 공략 온라인 쇼핑몰 이벤트 ~~
2010년 3월 4일 목요일
아이폰 게임사운드 구현(FMOD 이용) - 3
실제 구현이 되고 있는 FmodIphoneSupprot.m파일을 살펴보자..
아래 코드들은 설명을 위해 적절히 수정을 하며 적는 코드라 동작을 완전히 보장은 못하다는 것을
명심해주시기 바란다. 구현 형태면에서 봐주셨으면 하는 바램이다..
헤더파일을 임포트하고 게임앱델리게이트 헤더를 임포트하고 있다.
게임앱델리게이트 사용을 위해 gameApp이라는 변수도 extern 선언을 해주고 있다.
#import "FmodIphoneSupport.h"
#import "GameAppDelegate.h"
extern GameAppDelegate *gameApp;
클래스 구현 시작 부분이다. FmodIphoneSupport의 구현임을 알린후
이 클래스 전반에 에러체크를 위해 사용할 ERRCHECK을 만들었다...이것은 Fmod에서 사용되는 API함수가 FMOD_RESULT
타입의 리턴값을 전해주는데 이값을 가지고 에러를 판단한다...이 함수는 Fmod api 다운 받아보면 포함된 예제 코드에 포함된 함수이다. 에러 발생시 에러내용을 디버깅 창에 출력하며 어플을 종료한다. 그 다음은 init함수를 재정의한다. 실제 Fmod초기화 부분은 initializeFMOD에서 해준다.
@implementation FmodIphoneSupport
void ERRCHECK(FMOD_RESULT result)
{
if (result != FMOD_OK)
{
fprintf(stderr, "FMOD error! (%d) %s\n", result, FMOD_ErrorString(result));
exit(-1);
}
}
- (id)init
{
if (self = [super init]) {
[self initializeFMOD];
}
return self;
}
초기화를 담당하는 함수다.. initFMOD 에서 실제 Fmod시스템에 대한 초기화를 해준다.
LoadGroups는 이전에 Fmod Designer에서 설정햇던 Group단위로 로딩을 해준다. 주의하여 보아야 할 부분은 bExternalAudioPlaying변수.. 이변수는 이미 아이팟으로 음악이 플레이중일때 처리를 위한 변수로 자세한 설명은 아래서 다시 하도록 하겠다. LoadGroups다음은 Fmod처리를 위한 update함수를 루프시키기 위해서 타이머 설정이 필요한데 타이머 설정을 해주고 있다. 그 다음은 bExternalAudioPlaying을 이용해서 이미 음악이 플레이중이면 음악을 계속해서 게임사운드와 같이 플레이할지 묻는 팝업창을 뛰우는 부분이다.
- (void)initializeFMOD
{
bool bExternalAudioPlaying = FALSE;
[self initFMOD:FMOD_IPHONE_SESSIONCATEGORY_AMBIENTSOUND externalAudioPlaying:&bExternalAudioPlaying];
[self LoadGroups];
timer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(timerUpdate:) userInfo:nil repeats:YES];
if(bExternalAudioPlaying == TRUE)
{
[gameApp stopTimer];
UIAlertView *resultView = [[[UIAlertView alloc] initWithTitle:@" iPod music Settings" message:@"Your mp3 is playing. Do you want to continue playing your music?"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"cancel", nil] autorelease];
[resultView show];
}
}
Fmod사용을 위한 리소스들을 로딩하고 초기화하는 부분이다. EventSystem_Create로 이벤트시스템을 생성하고
FMOD_IPHONE_EXTRADRIVERDATA 구조체를 초기화하여 eventSystem->init의 인수로 넘기고 초기화를 마친다. 이때 init을 거치면서 bpExternalAudioPlaying의 주소가 가르키는 변수에는 이미 플레이중인 사운드가 있는지를 알수 있는 bool값이 셋팅되게 된다. eventSystem->load로 iPhoneGame.fev에 이벤트관련정보를 로딩한다.
- (void)initFMOD:(FMOD_IPHONE_SESSIONCATEGORY)sessionCategory externalAudioPlaying:(bool *)bpExternalAudioPlaying
{
FMOD_RESULT result = FMOD_OK;
char buffer[200] = {0};
result = FMOD::EventSystem_Create(&eventSystem);
ERRCHECK(result);
FMOD_IPHONE_EXTRADRIVERDATA driverdata;
memset(&driverdata, 0, sizeof(FMOD_IPHONE_EXTRADRIVERDATA));
driverdata.sessionCategory = sessionCategory;
if(bpExternalAudioPlaying)driverdata.otherAudioPlaying = bpExternalAudioPlaying;
result = eventSystem->init(FMOD_SIMULTANEOUS_PLAY_NUM, FMOD_INIT_NORMAL | FMOD_INIT_ENABLE_PROFILE, &driverdata, FMOD_EVENT_INIT_NORMAL);
ERRCHECK(result);
[[NSString stringWithFormat:@"%@/iPhoneGame.fev", [[NSBundle mainBundle] resourcePath]] getCString:buffer maxLength:200 encoding:NSASCIIStringEncoding];
result = eventSystem->load(buffer, NULL, NULL);
ERRCHECK(result);
}
LoadGroups에서 그룹객체를 얻어온다. freeFMOD에서는 eventSystem해제.
timerUpdate는 타이머를 통해서 루프를 돌게 해주는 함수이다. 이안에 eventSystem->update함수를 위치시키면 된다. dealloc은 객체소멸시 처리...
- (void)LoadGroups
{
FMOD_RESULT result = FMOD_OK;
if(eventSystem)
{
result = eventSystem->getGroup("iPhoneGame/BGM", false, &bgmGroup);
ERRCHECK(result);
result = eventSystem->getGroup("iPhoneGame/SE", false, &envGroup);
ERRCHECK(result);
}
}
- (void)freeFMOD
{
[timer invalidate];
if (eventSystem)
{
eventSystem->release();
eventSystem = NULL;
}
}
- (void)timerUpdate:(NSTimer *)timer
{
FMOD_RESULT result = FMOD_OK;
result = eventSystem->update();
ERRCHECK(result);
//메모리 쌓임을 방지하기 위해 일정 메모리 넘어가면 해제
if(memoryCurrent > FMOD_LIMIT_MEM_SIZE)
[self stopAllSE];
}
- (void)dealloc
{
[self freeFMOD];
[super dealloc];
}
- (FMOD::EventSystem *)getSystem
{
return eventSystem;
}
- (FMOD::EventGroup *)getSEGroup
{
return seGroup;
}
- (FMOD::EventGroup *)getBGMGroup
{
return bgmGroup;
}
- (FMOD::Event *)getBGMEvent
{
return bgmEvent;
}
그룹별 사운드볼륨 설정하고 설정값 얻어오는 함수들..
- (float)getBGMVolume
{
return bgmVolume;
}
- (void)setBGMVolume:(float) vol
{
bgmVolume = vol;
if(bgmEvent!=nil)bgmEvent->setVolume(bgmVolume);
}
- (float)getSEVolume
{
return seVolume;
}
- (void)setSEVolume:(float) vol
{
FMOD_RESULT result = FMOD_OK;
seVolume = vol;
}
- (void)playBGM:(int)bgmEventNum
{
if(bgmEventNum<0)
{
return;
}
FMOD_RESULT result = FMOD_OK;
result = bgmGroup->getEventByIndex(bgmEventNum, FMOD_EVENT_DEFAULT, &bgmEvent );
ERRCHECK(result);
if(bgmEvent)
{
result = bgmEvent->setVolume(bgmVolume);
ERRCHECK(result);
result = bgmEvent->start();
ERRCHECK(result);
}
}
- (void)stopBGM
{
FMOD_RESULT result = FMOD_OK;
//이 라인을 넣으면 사운드 데이타 해제
result = bgmGroup->freeEventData();
ERRCHECK(result);
}
- (void)playSE:(int)seEventNum
{
FMOD_RESULT result = FMOD_OK;
FMOD::Event *event;
if(seEventNum<0)
{
return;
}
result = seGroup->getEventByIndex(seEventNum, FMOD_EVENT_DEFAULT, &event );
ERRCHECK(result);
result = FMOD::Memory_GetStats(&memoryCurrent, &memoryMaximum);
ERRCHECK(result);
if(event)
{
result = event->setVolume(seVolume);
ERRCHECK(result);
result = event->start();
ERRCHECK(result);
}
}
- (void)stopAllSE
{
FMOD_RESULT result = FMOD_OK;
result = seGroup->freeEventData();
ERRCHECK(result);
}
2010년 2월 24일 수요일
아이폰 게임사운드 구현(FMOD 이용) - 2
#import "fmod_event.hpp"
#import "fmod_errors.h"
#import "fmodiphone.h"
@interface FmodIphoneSupport : NSObject {
NSTimer *timer;
FMOD::EventSystem *eventSystem;
FMOD::EventGroup *bgmGroup;
FMOD::Event *bgmEvent;
FMOD::EventGroup *seGroup;
FMOD::Event *seEvent;
float bgmVolume;
float seVolume;
}
- (void)initializeFMOD;
- (void)initFMOD:(FMOD_IPHONE_SESSIONCATEGORY)sessionCategory externalAudioPlaying:(bool *)bpExternalAudioPlaying;
- (void)LoadGroups;
- (void)freeFMOD;
- (void)timerUpdate:(NSTimer *)timer;
- (FMOD::EventSystem *)getSystem;
- (FMOD::EventGroup *)getSEGroup;
- (FMOD::EventGroup *)getBGMGroup;
- (FMOD::Event *)getBGMEvent;
- (FMOD::Event *)getSEEvent;
- (float)getBGMVolume;
- (void)setBGMVolume:(float)vol;
- (float)getSEVolume;
- (void)setSEVolume:(float)vol;
- (void)playBGM:(int)bgmEventNum;
- (void)stopBGM;
- (void)playSE:(int)seEventNum;
- (void)stopAllSE;
@end
2010년 2월 5일 금요일
아이폰 게임사운드 구현(FMOD 이용) - 1
이거 데메크 짝퉁 아냐?!@#$ 베요네타!
2010년 2월 4일 목요일
OpenAL로 아이폰 게임사운드 구현에 대해..
아이폰에서 사운드 구현에 대해서 검색을 해보니 openal이라는 프레임웍을
이용해서 개발하는게 좋다고 하더라...
그래서 openal관련해서 뒤져보다가 2개의 예제 소스코드를 발견했다.
1. http://developer.apple.com/iphone/library/navigation/SampleCode.html 에서 찾을 수 있는 oalTouch
2. mac에서 macintoch HD밑의 /Developer/Examples/CoreAudio/Services/OpenALExample 의 소스
이다.
그리고 개발을 위해선 OpenAL에 대한 reference가 필요하다. 아래링크로 다운 받는 파일은 OpenAL API에 대한 설명이 되어 있는 OpenAL개발가이드이다.
OpenAL개발가이드
이걸 참고로 하고 위 두 소스파일을 분석해보면 iphone에서 사운드를 출력하는데 도움이 될 것이다.
스프라이트 게임 툴 설계..
- 최고 상위 클래스명 - JGEObject
- 툴에서 저장 및 열기시 사용할 파일 확장자 - jgf
- 최소 스프라이트단위 - cell
- 정지된 cell들의 셋이 배치된 상태 - frame
- frame 들이 나열되어 재생이 가능한 묶음 - animation
- cell,frame,Animation들이 어떤 명령에 의해 순서나 위치가 나열된 것 - Scene
actor 정의
- 게임 개발자
- 프로그래밍을 통해 데이타를 사용할 프로그래머(programmer)
- 작업한 이미지 파일을 불러들여 애니메이션을 만들거나 프레임을 구성할 디자이너(graphic designer)
- 구성된 그래픽 객체들을 가지고 Scene을 구성할 기획자(game designer)
필요 service 나열-----아래 내용보다 더욱 세분화 되어 질 수 있지만 현재로서는 이정도 단계까지만 use case를 생각해보기로 한다.
- 이미지 파일 불러오기
- 셀(cell) 편집
- 프레임(Frame) 편집
- 애니메이션(Animation) 편집
- 장면(Scene) 편집
- binary파일 추출
- text파일 추출
- header파일 추출
뭐 이정도면 유즈케이스 다이어그램을 작성할 준비가 되어 있다고 볼 수 있겠다.
이름하야 StarUML 오픈소스 툴이라고 하니 귀가 솔깃 하다....
Rational Rose것을 쓰고 싶지만 비용이 장난 아니었던 걸로 기억하는데
암튼 StarUML에 대해서 공부를 해볼 생각이다...그동안 많이 피부로 접하지 못한
C++도 좀 더 가깝게 두고 느껴야 할 듯...
참고싸이트
http://staruml.sourceforge.net/ko/index.php