'cocos2d'에 해당되는 글 10건

오늘 포스트는, 어제 잠시 보았던 cocos2d소스를 정말 최소한 수정하여, 정말 간단한 시계어플(?)을 만드는 것이다.
사실 말이 시계 어플이지, 아무런 UI도 없다. 사실 시계는 우리에게 시간을 알려주는것이 목적이므로, 그 기본에 정말 충실한 어플이다.

HelloWorld 어플에서 수정해야 하는 부분은 HelloWorldLayer.h와 m 파일이다.

시간을 찍어주고, 저장하고 있을 label을 멤버로 올리고(기존 "HelloWorld"를 저장하던 부분), 스케쥴러를 1초마다 동작하게 하여, 시간을 다시 업데이트 해주는 함수를 추가한다. 이게 끝이다. 이러면 시계가 된다. 앱스토어에 존재하는 수만은 시계 어플들은 여기서 시작한다, 여기다가 배경 사진 그럴사한거 넣어주고, 폰트도 이쁜놈으로 넣어주고, 배치를 그럴사하게 해주면.. 앱스토에 올려놓고 팔거나, 무료로 배포할수 있는 것이다. 이 모든걸 1시간도 안걸려서 만들수 있다. 이후 sprite를 이야기 하고 나서, 이 시계 어플에 배경을 넣고 좀 꾸며 보기로 하자.

바로 소스를 보자.
 

//

//  HelloWorldLayer.h

//  

//



// When you import this file, you import all the cocos2d classes

#import "cocos2d.h"


// HelloWorldLayer

@interface HelloWorldLayer : CCLayer

{

    CCLabelTTF *label; // --> 이걸 추가했다. 아래 프로퍼티 같은건 선언하지 않았다. 기능 구현에만 충실하자.!!!!

}


// returns a CCScene that contains the HelloWorldLayer as the only child

+(CCScene *) scene;


@end


 


 

//

//  HelloWorldLayer.m

//  

 
// 추가된 함수. 매초마다 호출되어 시간을 찍어준다. 아래 코드들은 시간을 찍거나 사용하는 어플에서는 공통으로 사용할수 있는 코드이다. 

- (void) updateTime

{

    NSDate *now = [[NSDate alloc] init];

    NSLocale *locale = [NSLocale currentLocale];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

    [dateFormatter setLocale:locale];


    [label setString:[dateFormatter stringFromDate:now]];

    [dateFormatter release];

    [now release];

}



// on "init" you need to initialize your instance

-(id) init

{

// always call "super" init

// Apple recommends to re-assign "self" with the "super" return value

if( (self=[super init])) {

// create and initialize a Label

                // 멤버 변수를 사용하도록, 이전 소스에서 한부분만 수정. 옆에 폰트도 바꿨음. 

label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"AppleGothic" fontSize:32];


// ask director the the window size

CGSize size = [[CCDirector sharedDirector] winSize];

// position the label on the center of the screen

label.positionccp( size.width /2 , size.height/2 );

// add the label as a child to this Layer

[self addChild: label];

        

        [self schedule:@selector(updateTime) interval:1];// 이것이 바로, 매초마다 호출되게 하는 스케줄러 설정부분.

}

return self;

}

 

끝났다. 여러분은 이제 시계를 만들었다.

소스에 특별한 설명을 할만한 부분이 없으나, update함수를 매초마다 호출하게 하는 방법은 어떻게 하나?? 고민하였을텐데. 바로 위에 나오는 schedule 메소드를 사용하면 된다. 사용하는 문법은 xcode에서 타이핑하면 줄줄줄 바로 나온다. 여기서 등장하는 @selector가 무엇이냐면, 우리가 C/C++을 할때에는 함수 포인터를 사용해서, 타이머 콜백등을 등록해두거나 하는데, objective C 에서는 그렇게 하지 않고, selector라고 하는 것을 사용한다, 함수를 만들고 선언하면, 각 함수는 고유한 SEL값을 가지게 되는데, 그 값을 관리하는 테이블에 실제로 그 함수로 연결해주는 주소를 따로 관리하고 있다. 우리는 콜백을 달거나, 특별히 딜레이를 줘야 할경우가 생긴다면, 앞으로 @selector()를 사용하면 된다.

interval은 1은 1초마다를 뜻한다. 1/60을 하면 60프레임이 되는거고, 아무것도 안넣으면 매프레임마다 호출되게 된다.


또 본인이 개발할때 폰트를 Marker Felt만 써야 되는줄 알고 완전 힘들게 이미로 분리해서 하나씩 썼었는데, 전혀 그럴필요가 없다. 앞으로 cocos2d를 사용해서 글자를 찍고 싶으면 아래 리스트에 나오는 폰트중 아무거나 하나 골르면 된다. 그리고, 최근에 추가된 여러폰트들도 있을것으므로, 인터넷 검색을 통해서 찾아서 사용하면 된다.


CCLabelTTF가 지원하는 폰트들(외부폰트를 사용할수도 있음)

 

Family name: AppleGothic

Font name: AppleGothic

Family name: Hiragino Kaku Gothic ProN

Font name: HiraKakuProN-W6

Font name: HiraKakuProN-W3

Family name: Arial Unicode MS

Font name: ArialUnicodeMS

Family name: Heiti K

Font name: STHeitiK-Medium

Font name: STHeitiK-Light

Family name: DB LCD Temp

Font name: DBLCDTempBlack

Family name: Helvetica

Font name: Helvetica-Oblique

Font name: Helvetica-BoldOblique

Font name: Helvetica

Font name: Helvetica-Bold

Family name: Marker Felt

Font name: MarkerFelt-Thin

Family name: Times New Roman

Font name: TimesNewRomanPSMT

Font name: TimesNewRomanPS-BoldMT

Font name: TimesNewRomanPS-BoldItalicMT

Font name: TimesNewRomanPS-ItalicMT

Family name: Verdana

Font name: Verdana-Bold

Font name: Verdana-BoldItalic

Font name: Verdana

Font name: Verdana-Italic

Family name: Georgia

Font name: Georgia-Bold

Font name: Georgia

Font name: Georgia-BoldItalic

Font name: Georgia-Italic

Family name: Arial Rounded MT Bold

Font name: ArialRoundedMTBold

Family name: Trebuchet MS

Font name: TrebuchetMS-Italic

Font name: TrebuchetMS

Font name: Trebuchet-BoldItalic

Font name: TrebuchetMS-Bold

Family name: Heiti TC

Font name: STHeitiTC-Light

Font name: STHeitiTC-Medium

Family name: Geeza Pro

Font name: GeezaPro-Bold

Font name: GeezaPro

Family name: Courier

Font name: Courier

Font name: Courier-BoldOblique

Font name: Courier-Oblique

Font name: Courier-Bold

Family name: Arial

Font name: ArialMT

Font name: Arial-BoldMT

Font name: Arial-BoldItalicMT

Font name: Arial-ItalicMT

Family name: Heiti J

Font name: STHeitiJ-Medium

Font name: STHeitiJ-Light

Family name: Arial Hebrew

Font name: ArialHebrew

Font name: ArialHebrew-Bold

Family name: Courier New

Font name: CourierNewPS-BoldMT

Font name: CourierNewPS-ItalicMT

Font name: CourierNewPS-BoldItalicMT

Font name: CourierNewPSMT

Family name: Zapfino

Font name: Zapfino

Family name: American Typewriter

Font name: AmericanTypewriter

Font name: AmericanTypewriter-Bold

Family name: Heiti SC

Font name: STHeitiSC-Medium

Font name: STHeitiSC-Light

Family name: Helvetica Neue

Font name: HelveticaNeue

Font name: HelveticaNeue-Bold

Family name: Thonburi

Font name: Thonburi-Bold

Font name: Thonburi

 
 

위의 시계어플을 실행시킨 동영상을 마지막으로 첨부한다.

 

다음포스트에서 sprite에 대해서 이야기 해보자.
 

'코딩하고 > iOS' 카테고리의 다른 글

VoodooHDA 64비트 빌드 그리고, nVidia HDMI 제거.  (2) 2011.08.15
iOS용 게임 개발기 -5-  (0) 2011.08.10
iOS용 게임 개발기 -4-  (0) 2011.08.01
iOS용 게임 개발기 -3.1-  (0) 2011.07.11
iOS용 게임 개발기 -3-  (0) 2011.07.11
블로그 이미지

커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

,
지난 포스트에서 약속했던바와 같이 이번 포스트에서는 정말 cocos2d의 기초 부분을 살짝 확인해보는 데 의미를 두는 글을 쓰도록 하겠다.  앞으로 게임을 개발 하든, 어플을 개발하든 기본, 기초만 알고 있으면, 나머지 필요한 부분은 각종 인터넷 매뉴얼을 본다거나, 샘플 코드를 보면서 따라 해도 아무런 무리가 될것이 없다.

본인 역시도, cocos2d를 사용하면서, "내가 하고 싶은것이 이런건데, 이건 대체 어떻게 해야 하나???" 고민하는 것보다, 인터넷 검색을 해서 바로 필요한 부분을 찾고, 기초적인 내용을 조합해서 해당 기능이 동작하도록 한 것이 대부분이다.

게임 개발하면서 가장 중요했던 부분이 자료구조인데, 이부분은 C/C++의 것을 그대로 사용할까 하다가, 이왕이면 Objective C의 것을 사용하고자 마음먹고, 이부분도 cocos2d를 보면서 같이 공부했는데 아무런 어려움이 없었다. 여러분들도 그러할것이다.!!

그러면, 아래 소스를 한번 보자.

// main.m file.
#import
<UIKit/UIKit.h>


int main(int argc, char *argv[]) {

    

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");

    [pool release];

    return retVal;

}


위 파일은 프로젝트를 만들면 자동으로 생성되는 main.m파일인다, 우리가 이전에 C언어를 사용하면, 하나의 프로그램에 엔트리를 만드는데 보통 main함수를 만들어 썼다. objective c 도 마찬가지이다. 위에서 처럼, 자동해제해주는 메모리 풀을 만들어주고,  AppDelegate를 찾아서 실제 제어를 넘겨준다.

우리는 앞으로 main.m을 건드릴은 거의 없다. 본인은 전혀 없었다.

// AppDelegate.h file
#import
<UIKit/UIKit.h>


@class RootViewController;


@interface AppDelegate : NSObject <UIApplicationDelegate> {

UIWindow *window;

RootViewController *viewController;

}


@property (nonatomic, retain) UIWindow *window;


@end

 위 파일은 바로전에 실제 제어를 넘겨받는 AppDelegate의 헤더 파일이다. 어떤 내용이 있다 궁금하니까 한번 열어보는 정도의 의미를 두면 되는데, AppDelegate 는 NSObject를 상속받고, 그 멤버로는 window와 viewController가 있다. 아래는 @property는 나중에 쓰다보면, 알게 되지만, 간단하게 말해서 우리가 프로그래밍을 할때, 어떠한 클래스의 멤버 변수를 셋팅하거나 가져오거나 할수 있도록 만드는데, 그것을 objective C에서는 위와 같은 방법으로 선언하고, 실제 구현파일 즉 *.m 에서 @synthesize 를 이용해서 그 바디를 자동으로 구현하도록 한다. 나중에 외부 클래스에서 window라는 변수를 접근할수 있게 해주는 것이다.  이걸 setter와 getter라고 한다.

여기서 retain이라고 하는것도 굉장히 중요한데, 이부분은 나중에 따로 메모리 관리를 이야기 하면서 하나의 주제로 포스팅하겠다. 메모리 릭 나오고, 죽고 하는 문제 때문에 정말 피똥싼적있는데,. 다 저런것들 때문이었다..

그러면 이제는 실제 구현되는 부분으로 가보자.

//

//  AppDelegate.m

//  


//

//  AppDelegate.m

//  cocos2dTest

//

//  Created by Yongsu Kim on 11. 7. 11..

//  Copyright iinov.com 2011. All rights reserved.

//


#import "cocos2d.h"


#import "AppDelegate.h"

#import "GameConfig.h"

#import "HelloWorldLayer.h"

#import "RootViewController.h"


@implementation AppDelegate


@synthesize window;


- (void) removeStartupFlicker

{

//

// THIS CODE REMOVES THE STARTUP FLICKER

//

// Uncomment the following code if you Application only supports landscape mode

//

#if GAME_AUTOROTATION == kGameAutorotationUIViewController


// CC_ENABLE_DEFAULT_GL_STATES();

// CCDirector *director = [CCDirector sharedDirector];

// CGSize size = [director winSize];

// CCSprite *sprite = [CCSprite spriteWithFile:@"Default.png"];

// sprite.position = ccp(size.width/2, size.height/2);

// sprite.rotation = -90;

// [sprite visit];

// [[director openGLView] swapBuffers];

// CC_ENABLE_DEFAULT_GL_STATES();

#endif // GAME_AUTOROTATION == kGameAutorotationUIViewController

}

- (void) applicationDidFinishLaunching:(UIApplication*)application

{

// Init the window

window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

// Try to use CADisplayLink director

// if it fails (SDK < 3.1) use the default director

if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )

[CCDirector setDirectorType:kCCDirectorTypeDefault];

CCDirector *director = [CCDirector sharedDirector];

// Init the View Controller

viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];

viewController.wantsFullScreenLayout = YES;

//

// Create the EAGLView manually

//  1. Create a RGB565 format. Alternative: RGBA8

// 2. depth format of 0 bit. Use 16 or 24 bit for 3d effects, like CCPageTurnTransition

//

//

EAGLView *glView = [EAGLView viewWithFrame:[window bounds]

  pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8

  depthFormat:0 // GL_DEPTH_COMPONENT16_OES

];

// attach the openglView to the director

[director setOpenGLView:glView];

// // Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices

// if( ! [director enableRetinaDisplay:YES] )

// CCLOG(@"Retina Display Not supported");

//

// VERY IMPORTANT:

// If the rotation is going to be controlled by a UIViewController

// then the device orientation should be "Portrait".

//

// IMPORTANT:

// By default, this template only supports Landscape orientations.

// Edit the RootViewController.m file to edit the supported orientations.

//

#if GAME_AUTOROTATION == kGameAutorotationUIViewController

[director setDeviceOrientation:kCCDeviceOrientationPortrait];

#else

[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];

#endif

[director setAnimationInterval:1.0/60];

[director setDisplayFPS:YES];

// make the OpenGLView a child of the view controller

[viewController setView:glView];

// make the View Controller a child of the main window

[window addSubview: viewController.view];

[window makeKeyAndVisible];

// Default texture format for PNG/BMP/TIFF/JPEG/GIF images

// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565

// You can change anytime.

[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];


// Removes the startup flicker

[self removeStartupFlicker];

// Run the intro Scene

[[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];

}



- (void)applicationWillResignActive:(UIApplication *)application {

[[CCDirector sharedDirector] pause];

}


- (void)applicationDidBecomeActive:(UIApplication *)application {

[[CCDirector sharedDirector] resume];

}


- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {

[[CCDirector sharedDirector] purgeCachedData];

}


-(void) applicationDidEnterBackground:(UIApplication*)application {

[[CCDirector sharedDirector] stopAnimation];

}


-(void) applicationWillEnterForeground:(UIApplication*)application {

[[CCDirector sharedDirector] startAnimation];

}


- (void)applicationWillTerminate:(UIApplication *)application {

CCDirector *director = [CCDirector sharedDirector];

[[director openGLView] removeFromSuperview];

[viewController release];

[window release];

[director end];

}


- (void)applicationSignificantTimeChange:(UIApplication *)application {

[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];

}


- (void)dealloc {

[[CCDirector sharedDirector] end];

[window release];

[super dealloc];

}


@end

 
본인은 보면서 "이게 뭐지???" 라는 생각부터 들었다. 대체 어디로 제어권이 넘어가는거야!! 하고 버럭 버럭 하고 앉았었으나, 그건  iOS 어플이 어떻게 돌아가는지 몰라서 그런거였고.. 지금 보면 굉장히 심플한 것이었다, applicationDidFinishLaunching 이것이 바로, "론치가 끝나면 여기로 오세요"를 의미하는 함수이다.

사실 여기 부분도, 기존의 부분은 거의 수정할것이 없다. 본인은 추가는 생각보다 많이 했다. 나중에 소스를 하나씩 하나씩 보면서 설명하겠지만, 다른 메뉴의 전환, 레벨 조절, 점수 저장 등등등 설계자체가 너무 좀 크게 해서 그런지, 그들을 서로 연결해주는 게이트웨이가 필요했는데, 본인은 그 게이트웨이를 여기 이 delegate로 정했다. 다른 게임을 설계할때에도 하나의 파일에 전부다 구현할수가 없고, 하나의 클래스에 전부다 넣을수 없으며, cocos2d의  scene이나 layer하나에 전부 넣을수 없다. 그때 서로 다른 클래스, scene, layer간의 필요한 정보의 교환을 할수 있는 곳이 필요한데, 바로 이런곳에서 하면 된다. 


물론 그 계층 구조를 어떻게 만드냐에 따라서, layer들은 상위  scene을 통해서 하면되고, scene들만 delete를 통해서 의사소통하면 된다. 본인의 경우에는 이러한 구조로 작업을 하였으며, 만들고 나서보니 하나의 게임 프레임웍이 되어, 다른 게임을 또 하나 만들고 있다. 

위 소스에서 가장 중요한 부분은 바로 다음 부분이다.

// Run the intro Scene

[[CCDirector sharedDirectorrunWithScene: [HelloWorldLayer scene]];


이곳이 이제 실제로 cocos2d의 개념 이해가 필요한 부분인데.

위의 코드가 뜻하는 바는, "HelloWorldLayer의 Scene으로 넘어가라."이다.


이제 scene이 의미하는 것은 대체 뭔가 궁금해질것이다. 궁금해야 올바른 개발자이다. 처음에 scene의 개념을 모호하게 이해 못해서, 좀 어리 버리한짓을 많이 했는데, 나름 그 개념을 이해하고나, 현실에서 우리가 흔히 말하는 영화의 씬~, 애니메이션의 씬~, 드라마의 씬~ 바로 그것과 똑같은 것이다. 영화를 예를 들면, 촬영을 할때, 무슨씬 무슨 컷 이렇게 촬열이 들어간다면, 그 씬은 하나의 큰 주제를 의미할수 있다. 가령, 철수와 영희의 격투씬 을찍으면 그 씬은 정해져있고, 그씬안에 들어갈 내용들을 촬영하고 스토리로 나누게 되는데, 그 씬안에 들어가는 것들이 layer다.


여러분은 이제 cocos2d를 구성하는 scene과 layer의 의미를 이해했다. 물론 이론적으로정확히 설명을 하면 아래와 같이 설명할수 있다. 

Scenes

A “scene” in Cocos2d is just a special sort of node that acts as the ultimate parent for all other nodes that are visible. --> 이것이 핵심!! 

You can use this however you like, but typical usage is probably to make one scene for the “real” playable part of your game, and then use other scenes for the title page, high scores list, options, and so on. A scene is represented by the CCScene class.

A scene is “running” if it is the scene that is visible, has actions that are progressing, and so on. Only one scene can be running at a time. However, it's possible to push another scene on top of the current one, pausing the current one and running the new one; then later pop that new one and resume running the first. Or, you can have one scene entirely replace another (which is usually preferable, since it uses less memory).

This pushing/popping or replacing of scenes is done by the director (CCDirector). You've already seen this if you've poked around much in the project template. Look in the application delegate (e.g., in Lesson1AppDelegate.m or whatever it's called in your project). At the bottom of the applicationDidFinishLaunching method, you'll find a line like this:

	[[CCDirector sharedDirector] runWithScene: [HelloWorld scene]];

This tells the director to start running the given scene (HelloWorld).

To replace the running scene with another – for example, when the user taps the “Play” button on the menu screen, or when the game is over and you want to go back to the main menu – simply call replaceScene on the director:

	[[CCDirector sharedDirector] replaceScene: [SomeOtherScene scene]];

This terminates the current scenes, and starts the next one. You could later restart the first (or any other) by calling replaceScene again.

If you wanted to just pause the current scene instead, use pushScene instead of replaceScene; then you would call popScene later to terminate the new one, and resume the old. But use this sparingly, since memory on the iPhone is limited, and all scenes on the stack stay in memory.


이제는 helloWorldLayer로 가보자.

// HelloWorldLayer.h

#import
"cocos2d.h"


// HelloWorldLayer

@interface HelloWorldLayer : CCLayer

{

}


// returns a CCScene that contains the HelloWorldLayer as the only child

+(CCScene *) scene;


@end


뭐 큰내용이 없다. Layer이기 때문에, CCLayer를 상속받았고, 클래스 메소드로 scene이라는 메소드를 가지고 있다. + 표시가 바로 이 함수는 클래스 메소드 이다. 즉, "해당 클래스가 생성될때 새로 생성되는 것이 아닌(Instance가 아닌), static 메소드입니다." 라는 것이다. 해당 클래스를 생성하지 않아도 호출할수 있는 함수 정도로 이해해두자.

scene함수는 아래소스를 보면 그 body가 구현되어 있다. Scene을 하나 만들어서, 거기 밑에다가 HelloWorldLayer를 하나 만들어서 자식으로 달고, scene을 반환하도록 되어 있다. 좀 더 복잡한 소스를 나중에 보면서 좀더 자세히 설명하겠지만, 지금은 그냥 저렇게 하위에 레이어를 하나 달아주는것이구나정도로 이해하면 된다. 위에서 말했던 것처럼 Scene아래에 layer가 있으므로, 우리는 아래 코드로 Scene을 만들고,Layer도 하나 만들어서 사용할수 있게 한것이다.

//

//  HelloWorldLayer.m

//  



// Import the interfaces

#import "HelloWorldLayer.h"


// HelloWorldLayer implementation

@implementation HelloWorldLayer


+(CCScene *) scene

{

// 'scene' is an autorelease object.

CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.

HelloWorldLayer *layer = [HelloWorldLayer node];

// add layer as a child to scene

[scene addChild: layer];

// return the scene

return scene;

}


// on "init" you need to initialize your instance

-(id) init

{

// always call "super" init

// Apple recommends to re-assign "self" with the "super" return value

if( (self=[super init])) {

// create and initialize a Label

CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];


// ask director the the window size

CGSize size = [[CCDirector sharedDirector] winSize];

// position the label on the center of the screen

label.positionccp( size.width /2 , size.height/2 );

// add the label as a child to this Layer

[self addChild: label];

}

return self;

}


// on "dealloc" you need to release all your retained objects

- (void) dealloc

{

// in case you have something to dealloc, do it in this method

// in this particular example nothing needs to be released.

// cocos2d will automatically release all the children (Label)

// don't forget to call "super dealloc"

[super dealloc];

}

@end


scene함수에서 [HelloWorldLayer node];이 부분이 의미하는 바는 " HelloWorldLayer의 node 메소드를 호출하라." 그러면 cocos2d의 node 함수는 아래와 같이 되어 있다.

+(id) node

{

return [[[self alloc] init] autorelease];

}

여기도 클래스 메소드인데, 바로 자기 자신을 하나 생성하고(HelloWolrdLayer클래스를 위한 공간을 만들고) init 메소드르 호출하라.(autorelease도 다음에 다루겠다.)

init 은 바로 위 소스에 나오는 것처럼, 아래와 같다.

// on "init" you need to initialize your instance

-(id) init

{

// always call "super" init

// Apple recommends to re-assign "self" with the "super" return value

if( (self=[super init])) {

// create and initialize a Label

CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];


// ask director the the window size

CGSize size = [[CCDirector sharedDirectorwinSize];

// position the label on the center of the screen

label.position =  ccp( size.width /2 , size.height/2 );

// add the label as a child to this Layer

[self addChild: label];

}

return self;

}

여기서 -는 이제 일반 함수이다. instance함수.(꼭 생성후 alloc후 사용가능한 함수)

여기가 바로.. 우리가 화면에서 보던 "Hello World"를 찍어주는 부분이다. 코드의 내용의 자세한 부분은 다음에 해당 주제가 나올때 다시 이야기 하기로 하고, 여기까지 왔으면 이제 cocos2d를 이용해서, 문자열을 찍어주는 간단한 어플은 이제 만들수 있게 된다. 전광판과 같은 효과라던가, 그런 화려한 효과는 아니더라도, 내가 찍고자하는 내용을 원하는 규칙에 맞게 이제 콘트롤 가능한 것이다. 

다음 포스트는 sprite에 대해서 이야기 하도록 하겠다. cocos2d의 존재 목적이 바로 sprite이다. 우리가 게임을 만들때, 수많은 이미지들을 사용하고, 각종이펙트나, 애니매이션 효과를 구현할때에도 역시 이미지들 즉, sprite를 이용한다. 그것을 우리가 정말 빡세게 하나 하나, 장인정신으로 한땀 한땀 손수 만들수 있지만, 이미 정말 잘만들어진 솔루션이 있고, 공짜다. 그게 바로  여러분이 보고 있는 cocos2d라는것이다.

다음 주제를 최대한 빨리 준비해서 다시 포스트 하도록 하겠다. 


추신)
본 포스트들은 완전히 개인적인 목적으로 글을 쓰는 것이고, 개발기는 본인이 iOS용 게임 개발을 공부하면서 처음 개발한 BlueOcean을 개발하면서 경험한 것들을 정리하는 내용들이다. BlueOcean은 실제로 아래 링크에서 아직도 살아있다.
http://itunes.apple.com/us/app/blue-ocean/id430842838?l=ko&ls=1&mt=8







 

'코딩하고 > iOS' 카테고리의 다른 글

iOS용 게임 개발기 -5-  (0) 2011.08.10
iOS용 게임 개발기 -4.1-  (0) 2011.08.02
iOS용 게임 개발기 -3.1-  (0) 2011.07.11
iOS용 게임 개발기 -3-  (0) 2011.07.11
iOS용 게임 개발기 -2-  (0) 2011.07.09
블로그 이미지

커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

,
말나온김에, 내가 만든 게임 플레이 동영상을 첨부해본다.

동영상 시뮬레이터.



위 플레이 영상은 정말 가장 쉬운 레벨들인데도 불구하고, 개발자 본인은.. 단박에 클리어 하지 못하고 있다. 

물론 디바이스에 넣어서 플레이했을때는 저 영상보다 훨씬 더 나은 실력을 발휘 할수 있다.!!!

45레벨 모두를 클리어하는데, 대략 1주일이 걸렸다. 보기에는 쉬우나, 뒤로 갈수록 정말 뒷목 잡고 쓰러질뻔한 게 한두번이 아니다. 내가 만들었는데, 왜 내가 클리어를 이렇게 힘들게 해야 하는지.. 정말 출제자의 의도를 알아도 풀수가 없다니....

다음포스트에서, 다시 보기로 하자. 

 

'코딩하고 > iOS' 카테고리의 다른 글

iOS용 게임 개발기 -4.1-  (0) 2011.08.02
iOS용 게임 개발기 -4-  (0) 2011.08.01
iOS용 게임 개발기 -3-  (0) 2011.07.11
iOS용 게임 개발기 -2-  (0) 2011.07.09
iOS용 게임 개발기 -1-  (0) 2011.07.08
블로그 이미지

커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

,
이번 포스트는, 지난 2편에서 이야기 했던 cocos2d를 처음 접하는 당혹감에 대한 내용이다.
내가 당혹감이라고 표현하는 이유는, 이전에 까지 접해왔던 여러 언어들 C/C++, Java, PHP, ....여러 언어들에 너무 익숙해져있었던 나머지,
Objective C 언어를 너무 쉽게 생각했다.

"어차피 C언어니까, 별다를게 있겠어?" 하고 쉽게 생각했는데, 정말 별다른게 많았다.  

생전 처음 보는 생소한 문법, 물론 자바와 유사한 점이 있긴하지만, 확연히 다르다.
물론 C언어의 문법을 약간 따르고 있을뿐, 확연히 다르다.

거기에다가, 나는 전혀Objective C 언어를 할줄 몰랐다. 엎친데 덮친격으로 cocos2d라는 것도 생전 처음 써봤다.

소프트웨어 개발자로 월급 받으며 먹고 살고 있는것이 벌써 7년이고, 전공도 컴퓨터 공학이었던 나에게는 이런 생소하고 당혹스러운 경험은 무서웠다.

대략 1주일 가량 이리 저리 앉아서, 이것 해보고, 저것 해보고 나니, Objective C언어는 별무리 없이 쓸수 있었다. 물로 내가 꼭 필요한 부분에 한해서이다. cocos2d는 매뉴얼 보면서 하나씩 구현해봤다.

그리하여 나온게임이 아래 게임이다.

http://itunes.apple.com/us/app/blue-ocean/id430842838?l=ko&ls=1&mt=8


게임이름도 거창하게 "Blue Ocean" 푸른 바다, 사실 이때 내 마음이 저 맑디 맑은 망망대해에 점하나를 똑 찍어놓은듯한 그런 느낌이었고, 이를 시작으로 많은 게임을 만들어보자는 생각에 작명하게 된것이다.

나중에 차근 차근 그 과정을 써나가면서, 주요 소스 코드들과, 이미지들을 사용한 방법, 레벨을 구성할때 했던 고민들, 맵을 만들때 데이터와 코드를 분리하기 위해 했던 많은 고민들, 로딩을 자연스럽게 하기 위해서 했던 고민들, 여러 고민들... 정말 고민들이 많았다.

그 고민들의 출처는 아마, 무지로부터 왔을것이다. 해본적이 없으니까.!!!!

여러분중에 누구라도, 처음에 뭔가를 만들려고 한다면, 익숙하지 않은 이런것들에 대해서 당혹감을 당연히 가질수 있다. 그런데 아무런 걱정할 필요 없다. 필자처럼, 생전 처음 보는 도구들을 이용해서 하루 2~3시간의 작업으로 6개월만에 이런 게임도 하나 만들어낼수 있었으니 말이다. 여러분은 나보다 훨씬 더 재밌고 좋은 게임을 만들 가능성이 높다. 

자, 지금부터 1주일간이 시간이 주어진다면, 당장 지나주에 설치해둔 xcode를 열고 아래와 같이 한번 따라 해보자. 다음주가 되면, 그냥 클릭 몇번하는게 아주 자연스럽게 될것이다.(물론 나는 중간에 수도없이 프로젝트를 만들었다, 없애고, 만들었다 없애고 하는 과정이 있었다. 왜냐면, 프로젝트를 수작업으로 라이브러리 추가하고 따로 빌드하는 법을 그 당시에는 몰랐기 때문이다. 지금도 사실 그렇게 할필요는 없다.)


cocos2d용 프로젝트 만들기.(동영상으로 모든 설명을 요약)


사실, 프로젝트 만들고 하는 과정을 하나씩 캡쳐하고 설명하고 하는것이 더 좋을수 있으나, 개인적으로 동영상 하나 보면서 따라하는 것 만큼 쉬운게 없었다. 그래서, 동영상 수정이나 그런걸 전혀 할줄 모르기때문에, 퀵타임의 화면기록을 떠서 위와 같이 올린다.

실행해보면, 정말 "세상아 안녕!!!" 하는 것이 끝이다. 너무 허탈하지만, 그게 시작이다.

다음 포스트에서는 Hello World의 소스를 약간 분석해보면서, 정말 핵심적으로 우리가 나중에 손대야 할만한곳들에 대해서면 이야기 해보도록 하자.
사실 나도 아직 cocos2d템플릿으로 만들어놓고, 내가 추가한 부분은 많아도, 원래걸 수정한 부분은 몇군데 안된다. 그만큼 사용하기 좋게 만들어둔것이라고 생각한다.


이 포스트들은 순전히 개인적인 기록을 목적으로, 정리하는데 의의를 두고 글을 쓰고 있습니다.
질문하실 부분이 있거나, 지적하실 부분이 있다면 댓글로 남겨주세요.
 

'코딩하고 > iOS' 카테고리의 다른 글

iOS용 게임 개발기 -4.1-  (0) 2011.08.02
iOS용 게임 개발기 -4-  (0) 2011.08.01
iOS용 게임 개발기 -3.1-  (0) 2011.07.11
iOS용 게임 개발기 -2-  (0) 2011.07.09
iOS용 게임 개발기 -1-  (0) 2011.07.08
블로그 이미지

커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

,
2편에서는 지난 1편에서 약속한대로, 개발환경의 설치와 게임 엔진중에 하나인 cocos2d가 무엇인지, 물리엔진중에 하나인 box2d가 무엇인지 알아보고 그 설치방법에 대해서 이야기 하겠다.

일단 iOS용 프로그램을 개발하려면,iOS SDK를 설치해야 하고, Xcode라고 하는 개발툴을 설치해야 한다.
Xcode는 얼마전까지는 무료였으나. 4로 업데이트 되면서 부터 유료 개발자 프로그램에 등록한 사람에 한하여 무료 다운로드 가능하도록 되어 있다.
무료로 구할수 있는 방법이 있을것 같으나, 이 부분은 구글이라던지 다른 경로를 통해서 알아보는 것이 더 빠를것이다.

xcode가 우선 무엇인가?
지금 이글을  읽고 있는 분이 이전에 개발을 한번도 하지 않으신 분이였다면, 다르게 설명을 해야 하나, 개발을 한번이라도 해보고 윈도우즈또는도스에서 c언어를 통해서 무엇인가 프로그래밍이라는 것을 해본적이 있는 분께는 아주 쉽게 설명할수 있다.
윈도우즈 개발하시던 분이라면,Visual Studio 와 같은 개발툴을 한번 정도는 접해보셨을것 이고, 자바 개발자라면 eclipse와 같은 개발환경을 한번은 접해보셨을 것이다.

그렇다,!!! xcode는 Mac용 프로그램을 쉽게 개발할수 있게 도와주는 IDE중에 하나이다. 굉장히 강력하고 여러 편리한 기능이 많이 제공되고 있으며, 이전까지 무료였다는게 믿어 지지 않을 정도로 그 완성도가 높은 개발 툴이다.


 
위 캡쳐 화면은 나의 개발환경을 참고용으로 올려둔 것이다. 개발하시던 분들은 아!! 뭐 이거구나. 하고 바로 사용가능하다.

만약 개발자가 아니신분들은 아이폰용 프로그래밍을 쉽게 해줄수 있도록 도와주는 프로그램 정도로 이해하고 넘어가도 무방하다. 나는 비록 개발자이지만 리눅스 또는 도스에 익숙한 커맨드 라인(메모장 같은 걸로 편집해서 컴파일명령을 내리는 )에 익숙한 개발자여서 통합 개발환경에 익숙하지 않았다. 그런데 한번 두번 쓰면 자연스럽게 손에 익는 그런 도구라서 따로 공부할 필요도 없었다, 사용하다 모르는 부분이 있으면 여기에 댓글을 남겨주면, 내가 직접 찾아서라도 답변을 남기도록 하겠다.

그러면, 이 xcode를 어디서 다운받는가?
바로 애플 개발자 센터이다. http://developer.apple.com/xcode/index.php 여기로 가보면, 친절한 설명과 다운 받으려면 유료회원으로 가입해야 된다는 설명이 나온다. 좌절하지 말고 구글등을 통해서 여러 경로를 알아보도록 하자. 물로 나는 유료회원으로 가입했기 때문에, 여기서 다운로드 받았다.

여기서 유료회원과 무료회원의 차이는 궁극적으로, 무료회원은 시뮬레이터등을 이용해서 프로그램을 돌려볼수는 있지만, 앱스토어에 등록하거나, 실제 디바이스에 올려보지 못한다. 유료회원은 그게 다 가능하다, 앱스토어에 무료 앱을 올리고자 해도, 유료 개발자 프로그램에 가입해야 한다. 1년에 104,000원 정도 밖에 안하므로, 한달에 9000원 정도 취미로 쓴다 생각하고 결재하는것이 좋은것 같다.

요약하면, 당신이 프로그램을 개발하고자 한다면, 제일 처음 기본적으로 Mac OS 가 설치된 PC는 기본적으로 있어야 한다.
맥북 저렴한걸 사는것도 좋고(http://store.apple.com/kr) 최저가 1,290,000원 이다. 해킨토시라고 있는데, 일반 PC 에 OSX를 설치하는 것을 말한다. 이걸 할수 있다면, 이런 방법도 추천한다. 그러나, 정신이 피폐해지기 쉽고, OSX 에 관한 지식이 없다면, 해킨으로는 도저히 개발을 할수 없을것이다.  그리고 개발툴인 xcode를 설치해야 한다. 위에서 말한 사이트에서 유료개발자로 가입한후 다운로드 받아도 되고, 일단 다운받은 다음에 클릭만 하면 설치가되므로 아무런 걱정할필요 없다. iOS용 프로그램을 개발하기로 했으므로, iOS용 SDK를 설치해야 하는데 xcode설치할때 같이 설치할수 있다. 

여기 까지하면 기본적인 앱은 클릭 몇번으로 만들수 있다. 

나는 게임 개발하는 과정을 정리하기로 했으므로, 게임개발에 반드시 필요한 두가지 엔진추가로 설치하였다.
그중 한가지는 이미지들을 처리해주고, 각종 애니메이션들을 처리해주는 스프라이트 엔진인 cocos2d이고, 그리고 이것을 설치할때 같이 설치하는 물리엔진인  box2d이다. 이름에서 부터 알수 있듯이, 2d 환경에서 물리를 시뮬레이트해주고(그 유명한 앵그리버드도 box2d를 사용한것으로 알고 있다.) 이미지를 처리해주는 굉장히 훌륭한 엔진이다. cocos2d는 많은 게임들에 사용되고 있을만큼 그 사용성도 광범위 하므로, 게임을 개발하고자 마음먹었다면, 이참에 같이 설치해서 공부해두는것이 좋다. 물론 다음에 내가 만든 게임 코드들 하나 하나를 보면서 cocos2d를 사용중 봉착한 문제점, box2d엔진을 사용하다 만나게 된 여러 문제점들을 하나씩 짚고 정리할 예정이다.

먼저 coco2d를 설치해보자.
http://www.cocos2d-iphone.org/
여기로가서 stable버전을 다운로드 하고(현재 0.99.5 xcode4 지원안함.) 수작업으로 프로젝트에 맞춰서 사용하여도 되고, 최신 버전으로 다운받아서(1.0이상버전은xcode4지원) 프로젝트 생성할때 클릭 두번으로 쉽게 작업하여도 된다.

나는 0.99.3시절에 시작하여, 중간에 iOS버전을 두번 올리면서 개발환경도 두번업데이트 했다. 사실 아무것도 모르고 무턱대고 클릭하다 보니, 일이 커지게 되었으나, 막상 하고 나서 보니, 역시 최신 버전을 쓰기 잘했구나 싶을 정도로 많은 발전을 한것이 느껴졌다.

cocos2d를 다운받고 설치하면, 자동으로 xcode 템플릿이 설치된다.(xcode4의 경우는 반드시 1.0 이상 버전을 사용해야 설치됨)


설치하고나서, xcode를 실행시키고 새로운 프로젝트를 생성해보면 위와 같이 나온다. 제일 처음 나오는게 물리엔진을 사용하지 않는 cocos2d템플릿, 두번째 것은 cocos2d 와 물리엔진 box2d를 사용하는 템플릿, 마지막것은 다른 물리엔진인 chipmunk를 사용하는 템플릿이다.

그 용도에 맞게, 선택해서 프로젝트를 생성하면 기본적인 앱이 이미 만들어져서 나온다.
게임 성격이 물리엔진이 필요치 않다면, 당연히 cocos2d만 사용해서 만들도록 하는것이 좋다.

물리엔진이 무엇인지 잠깐 설명하면, 쉽게 말해서, 우리가 앵그리버드에 새들을 쏴 올리면, 그 새들이 곡선을 그리고 날아가고(중력과 힘의 영향을 받음) 그리고 다른 장애물이나 돼지에 부딪치거나 하면 튕기거나 하는데 이런 것들이 다 현실에서는 물리현상들이다. 이런것들을 일일이 개발자가 하나씩 계산해서 좌표를 직접 찍어줄수 있는데, 이런걸 미리 다 하나로 모아서 라이브러리화 해놓고, 그것들을 자연스럽고 쉽게 사용할수 있는 api들을 제공하는데 바로 이것을 물리엔진이라고 한다.



이글은 전혀 퇴고의 과정을 거치지 않는 정말 라이브한 글이다. 단순히 내가 겪은 과정을 무에서 시작해서 유를 만들어내는 과정을 정리하고, 그 과정중에 만난 시행착오들을 정리하는데 더 큰 의미를 두는 글이다.

다음 포스트는 cocos2d를 처음 사용할때 느끼는 당혹감에 대해서 이야기 하도록 하겠다.
나는 당혹감을 느끼고 나서, 비로소 편안해졌다.  오브젝티브 C  에 대해서는 꼭 필요한 경우가 아니면, 여러 설명을 하지 않을 예정이다.

-2편 끝-

 

'코딩하고 > iOS' 카테고리의 다른 글

iOS용 게임 개발기 -4.1-  (0) 2011.08.02
iOS용 게임 개발기 -4-  (0) 2011.08.01
iOS용 게임 개발기 -3.1-  (0) 2011.07.11
iOS용 게임 개발기 -3-  (0) 2011.07.11
iOS용 게임 개발기 -1-  (0) 2011.07.08
블로그 이미지

커뉴

이 세상에서 꿈 이상으로 확실한 것을, 인간은 가지고 있는 것일까?

,