2010년 6월 24일 목요일

게이머즈 공략 온라인 쇼핑몰 이벤트 ~~

국내 유일의 비디오게임 잡지 Gamer'Z에서 온라인 공략 쇼핑몰을 만들었네요. 비디오 열혈 게이머의 한명으로 정말 잘 운영되서 비디오게임 대중화에 기여를 했으면 합니다. 오픈 행사로 이벤트를 해서 조금이나마 알려보고자 포스팅해봅니다. 게이머즈 화이팅입니다...꾸준히 비디오게임 잡지 만들어 주시길 http://blog.naver.com/gamerzblog/130088611969

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->loadiPhoneGame.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;

}



아래 함수들은 구룹별로 각각 음악을 플레이 해주고 정지 시킬 수 있는 함수들이다...실제 사운드 제어는 이 함수들을 이용해서 하면 되는 것이다. BGM의 경우는 하나의 이벤트만 동작하게 되므로 하나의 이벤트를 정지 해주면 되게끔 되어져 있고 SE의 경우는 여러개의 소리가 동시에 출력되고 있을 수가 있으므로 재생을 정지하려면 모든 SE이벤트에 대해서 정지하도록 만들었다.

- (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);

}


이상으로 허접한 강좌?(강좌라기 보단 개인적인 정리라고 하는게 나을지도...)를 마칠까 한다.
아무튼 이렇게 코드를 구성하면 간단하게 Fmod를 이용해서 아이폰에서 멋진 멀티게임 사운드를 구현해낼 수 있다.
Fmod가 유료라는 점에서 더 자세하게 들어가면 3D사운드의 구현이라던지...실시간으로 패러미터를 조정하여 같은 리소스
의 음원을 다른 느낌으로 플레이 한다던지 하는 것이 가능하다..응용의 범위는 굉장히 넓다고 할 수 있을 것이다.
Fmod사용이 적지 않은 비용이 든다 해도...다운받아서 구현해보는 데는 비용이 들지 않는다..게임을 출시할 경우에 라이센스 비용을 지불하는 식이라 일단은 다운받아서 한번 해보라고 권하고 싶다...

이걸로 마칠까 한다. 모두 즐거운 아이폰 프로그래밍 하시길~~

혹여나 궁금한 사항이 있으신 분은 nakniner@gmail.com이나 nakniner트위터로 연락을 주셔요~

2010년 2월 24일 수요일

아이폰 게임사운드 구현(FMOD 이용) - 2

1.아이폰 Fmod 프로젝트 생성 및 이벤트 구성

자 그럼 실제 아이폰에서 Fmod를 돌리기 위해서 Fmod designer프로젝트를 만들고
Group 및 Event를 만들어보자.

Fmod 상단메뉴에서 File>New project를 선택하여 프로젝트 이름을 뭍는 창이 뜨면 아래와 같이 원하는 이름을 넣어서 Save를 하도록 한다. 여기서는 iPhoneGame으로 하도록 하겠다.

프로젝트를 만든 후 Fmod 라이브러리에서 사용되어지는 Group과 Event를 만들어야 한다. 여기서는 BGM과 SE 두가지 Group을 사용하는 걸로 만들어 보겠다. 통상 게임에서 이렇게 쓰기때문에 적당한 예라고 생각되어진다. 아래그림처럼 생성하면 되겠다.

다음으로는 실제 사운드 리소스 파일을 등록해야만 한다. Sound definitions탭에서 필요한 Sound definition을 만들어서 게임내에서 사용 할 wav파일 리소스들을 등록한다.

이제 Events탭에서 필요한 그룹 BGM과 SE를 만들고 각각의 이벤트를 추가한다. 아래 그림에서는 BGM그룹에 BGM01이벤트를 하나 만들었고 SE그룹에 SE01,SE02 두개이벤트를 만들어서 추가 하였다. 여기까지 되면 아까 생성한 Sound definition을 만든 Event에 넣어 주어야 한다.

Event에 각 Sound를 매칭 시켜주는 작업은 Sound editor탭에서 해줄 수 있다. 아래 그림에서와 같이 /BGM01부분에 오른쪽 클린한 후 뜨는 팝업메뉴에서 Add sound를 해서 음원을 등록한다. 그리고 Sound instance properties...에서 필요하거나 의도하는 패러미터값을 조정해줄 수 있다. 예를 들면 사운드의 반복재생 여부를 여기서 바꿔 줄 수가 있다..지금의 예제의 경우 BGM01 이벤트에서는 사운드를 반복으로 설정하고 SE01,SE02 이벤트에서는 무반복으로 설정하면 되겠다.

 사운드의 반복여부나 각종 패러미터 값을 Event별로 조정하여 원하는 Evnet를 만든다음 프로젝트를 저장한다. 그런 다음 Fmod designer상단 메뉴 Build에서 Build project를 선택하여  빌드를 한다. 빌드의 결과물로 나오는 파일을 이용해서 게임 어플에서 사용을 하면 되는 것이다.

빌드 결과물 파일 중에 실제 게임에서 사용할 파일은

- 프로젝트명.h
- 프로젝트명.fev
- 프로젝트명.fsb

이다. 이파일들을 XCode 프로젝트에 적당한 부분에 포함시키도록 한다.

여기까지 되었으면 실제 코드를 얘기해보려고 한다.

2. 구현
-------------------------------------FmodIphoneSupport.h-----------------------------------

#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


--------------------------------------------------------------------------------------------
클래스 구성은 위와 같게 하면 기본적인 기능은 구현이 가능하겠다.



아 Fmod 에 대해 간단히 정리 해볼겸 시작했는데 이거 보통 일이 아닌 듯 하다...
실제 구현 부분에 대해서는 3편에서 얘기 하도록 하겠다..


2010년 2월 5일 금요일

아이폰 게임사운드 구현(FMOD 이용) - 1

아이폰게임의 사운드를 구현하는데 있어
무료로서 사용할 만한 Sound구현 모듈이 OpenAL이 있다면 유료지만 더 사용이 편리하고
다양한 것들을 할 수 있는 FMOD란 것이 있다..

실제 콘솔에서도 이 라이브러리를 사용해서 만들어 진 게임이 있고 PC게임에서도 이 FMOD를 사용하고
있다.
흠 최근 나온 게임중에 유명한 것을 들자면 바로 eidos의 Rock Steady Studio의 Batman-Arkam Asylum을 들 수 있다..물론 eidos는 스퀘어에닉스에 흡수되어 사라진 지 꽤 되었지만...

아무튼 이런 게임에서 사용된 것이라면 충분히 아이폰게임에서도 활용도가 높을 것이라고 생각된다.
본격적인 얘기를 해보자.
그럼 이 FMOD를 사용하려면 어떻게 해야하는가..
일단 다운로드를 받아야 한다..관련 소스코드와 라이브러리 및 관련 툴들...

http://www.fmod.org/

머 여기 들어가면 다 있다....잘 찾아보면 FMOD Designer, FMOD Sandbox등 툴이 있고 아이폰 프로젝트에 추가하여 사용할수 있는 라이브러리 파일들이 있다. 내가 작업중인 프로젝트에서는 FMOD Designer를 이용하여 프로젝트를 진행하고 있으니 Designer기준으로 설명을 하겠다.

FMOD홈피에서 Download로 들어가면 아래처럼 각 플랫폼별로 API가 제공되는걸 볼수 있다. 아이폰용을 다운받자.


사운드리소스 파일을 프로젝트로 관리해주며 다양한 패러미터 변경으로 원본사운드에 효과나 연출을 넣을 수 있게 해주는 FMOD Designer 맥버전 윈도우 버전이 있으니 자신이 개발에 쓰고 있는 운영체제용으로 다운 받자...맥용이든 윈도우용이든 뽑아주는 결과파일은 같으니 맥환경에서 패러렐즈나 퓨전등의 VMWare를 이용하는 사람은 윈도우용으로 사용하고 파일은 맥에서 사용하는 것도 가능하다.

받은 파일을 이용하여 FMOD Designer를 설치하고 프로젝트에서 FMOD사용을 위해 header파일과 라이브러리 파일을 링크 해주어야 한다.받은 파일을 작업중인 Xcode 프로젝트의 Frameworks에 아래 그림과 같이 넣어준다.
이렇게 프로젝트에 넣으면 FMOD를 이용해서 사운드출력을 하는 코드를 만들기 위한 준비가
끝난셈이다. 실제 구현 이야기는 2편에서 하도록 하겠다.

이거 데메크 짝퉁 아냐?!@#$ 베요네타!

데빌메이크라이1의 프로듀서로 유명한 "카미야 히데끼"가 디렉터를 맡은 베요네타.....

요새 재미있게 플레이 하고 있는 게임이다...
XBOX360/PS3 로 출시가 되었으나 엑박360을 기반으로 개발이 된데다 PS3로 이식이 만족스럽지 못한면이 있어 엑박용으로 구매해서 즐기고 있다.

게임의 장르는 데빌메이크라이,갓오브워,닌자가이덴과 같은 third person action 형태를 취하고 있다..시나리오는 베요네타라는 마녀가 천사들을 때려잡는다는 황당한 이야기~간만에 디카를 꺼내 들고 중간중간 스샷을 찍어봤는데 이건머 건질만한게 몇개 안되는 상황이....정작 게임플레이 장면은 쉴새없이 버튼을 눌러야 하기 때문에 찍지 못했다는..

일단 소감을 말하자면 정말 스피디하다....게임 진행이나 실제 액션이 매우 스피디하게 전개된다....데메크나닌가등은 비교불허. 주먹과 발버튼으로 만들어내는 다양한 연속기와 머리카락으로 이루어진 다양한 소환체의 폭발적인 연출로 시종일관 화면에서 눈을 떼지 못하게 한다. 또한 가장 중요한 시스템이 회피 시스템인데 적의 공격을 가까이서 회피하면 위치타임이라는 무적시간이 발동되어 많은 데미지를 적에게 넣어줄수 있다...가장 핵심적이고 이겜의 재미를 주는 요소라는 생각이 든다.
개인적으로 생각한 단점은 오히려 위치타임이라는 요소때문에 공격을 연속적으로 넣기보단 피하기 바쁘게 된다는 점...머 장점이면서 단점이기도 하단 얘기다. 또하나 너무 비슷한 전투의 반복만 있고 쉬어가기식 퍼즐이나 사고를 요하는 플레이가 없다는 것이 약간은 맘에들지 않는 부분이었다. 이부분은 갓오브워시리즈와 비교해보면서 생각이 든 부분이기도 하다. 머 아뭏튼 약간의 단점을 커버할 정도로 매우 다양한 요소로 재미를 주고 있어 단점은 크게 생각되지 않는 부분이었다.
세가의 퍼블리싱게임이었기에 가능했던 부분도 많았다...스페이스해리어의 오마쥬라고나 할까..그런 슈팅 겜이 들어있기도 하고 마치 소닉을 연상시키는 달리는 부분이라던지...게임내 머니가 소닉의 그것이라던지
그런 소소한부분도 올드 게이머라면 풋 하며 실소를 할만한 요소들이 꽤 있다....

마지막으로 한마디 하자면 정말 강추 액션게임이니 해보라고 말하고 싶다...가능하면 엑박판으로..

베요네타 타이틀 화면

ㅎㅎ 베요네타 누님이다....키 2M의 롱다리 절세 미녀

게임중에서 무기조달을 담당하는 로다인 아찌..

little one이라고 베요네타가 부르는 꼬맹이.....누구인지는 겜을 해보시길

이넘은 나쁜넘이다....

이건 좋은놈.

머리카락으로 이루어진 괴물...일종의 소환체 베요네타가 불러낸다

게임을 플레이하면 많이 보게될 화면 ㅋㅋ

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_Programmers_Guide.pdf

OpenAL개발가이드


이걸 참고로 하고 위 두 소스파일을 분석해보면 iphone에서 사운드를 출력하는데 도움이 될 것이다.

스프라이트 게임 툴 설계..

Use Case Diagram 작성 준비

System 관련 명칭 정의
- 최고 상위 클래스명 - 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파일 추출

뭐 이정도면 유즈케이스 다이어그램을 작성할 준비가 되어 있다고 볼 수 있겠다.

UML툴을 살펴보다 보니 역시나 무료 툴이 있더라~..

이름하야 StarUML 오픈소스 툴이라고 하니 귀가 솔깃 하다....
Rational Rose것을 쓰고 싶지만 비용이 장난 아니었던 걸로 기억하는데
암튼 StarUML에 대해서 공부를 해볼 생각이다...그동안 많이 피부로 접하지 못한
C++도 좀 더 가깝게 두고 느껴야 할 듯...

참고싸이트
http://staruml.sourceforge.net/ko/index.php