주요 클래스를 훌터보며 cocos2D는 여러 Scene으로 구성되어 연결된다는 사실을 알았다.  
  기존 예제는 HellowWorldScene.h파일에 다음과 같이 정의 되어 있다.
//
//  HelloWorldLayer.h
//   MyGame
//
//  Created by Daniel Lee on 10. 7. 17..
//  Copyright SimVerse 2010. All rights reserved.
//


// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"

// HelloWorld Layer
@interface HelloWorld : CCLayer
{
}

// returns a Scene that contains the HelloWorld as the only child
+(id) scene;

@end

 그럼 추가적인 Scene을 만들어 각 메뉴항목을 클릭하면 전환효과를 적용하는 방식으로 예제를 확장해 보자

1. 새로운 CCLayer를 프로젝트에 추가
  1) File -> New File ...  실행 후 User Template 항목에서 "cocos2d 0.99.4"를 선택 
  2) Subclass of "CCLayer"를 선택하고 Next 버튼 추

    3) File Name "TransitMenu" 입력 후 Finish 클 


2. TransitMenu.m 파일 구현

  1) 우리가 구현하고자 하는 Scene 역시 메뉴로 구현되어 있으므로, 기존 HelloWorld 파일과 크게 다르지 않다. 기존 HelloWorldScene.m의 내용을 새로 구현할 TransitMenu.m에 그대로 복사하여 붙여 놓자. 

  2) Transit효과를 줄 수 있는 메뉴 항목을 만들고 각각의 기능을 연결하자. 
    ㄱ. Transition 효과 구현 클래스  
  • CCFadeTransition
  • CCFlipAngularTransition
  • CCShrinkGrowTransition
  • CCMoveInBTransition
  • CCMoveInTTransition
  • CCMoveInLTransition
  • CCMoveInRTransition
  • CCFadeTRTransition
  • CCFadeUpTransition
  • CCFlipXTransition
  • CCFlipYTransition
  • CCPageTurnTransition
  • CCCrossFadeTransition

       ㄴ. 메뉴 화면 구성시 팁 
// TransitMenu 항목이 모두 13개나 되므로, 한 화면에 보이기 위해서는 메뉴항목 폰트를 조절해야함 
//  1. 메뉴항목 폰트 조절 : static 함수로 다음 함수가 호출될때 까지 적용됨
[CCMenuItemFont setFontSize:18];

//  2. 메뉴 항목을 두 줄로 표현 :
[menu alignItemsInColumns: [NSNumber numberWithUnsignedInt:2], [NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:2], nil];
/*
alignItemsInColumns : 메뉴 행당 표현될 column 갯수를 지정 
alignItemsInRows : 메뉴 열당 표현될 Row 갯수를 지정
*/

//  3. RGB Color값 지정 방법 : 
/*
   3 color  : 구조체/변환함수 = ccColor3B / ccc3(r,g,b)
   4 color  : 구조체/변환함수 = ccColor4B / ccc4(r,g,b,a)
*/

    ㄷ. 화면전환 구현방법
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];   // 새로 적용될 CCLayer 
[[CCDirector sharedDirector] replaceScene:[CCFlipXTransition transitionWithDuration:1 scene:sMain]];

    ㄹ. TransitMenu.m 구현 내용 (TransitMenu.h 은 Template에서 생성한 내용 그대로 사용)
//  TransitMenu.m
//   MyGame
//
//  Created by Daniel Lee on 10. 7. 23..
//  Copyright 2010 SimVerse. All rights reserved.
//

#import "TransitMenu.h"
#import "HelloWorldScene.h"


@implementation TransitMenu

+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
TransitMenu *layer = [TransitMenu 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] )) {
CCLabel* label = [CCLabel labelWithString:@"<<< Transit Menu >>>" fontName:@"Marker Felt" fontSize:20];
CGSize size = [[CCDirector sharedDirector] winSize];
label.position =  ccp( size.width / 2 , size.height/10 );
[self addChild: label];
[CCMenuItemFont setFontSize:18];
CCMenuItemFont *item1 = [CCMenuItemFont itemFromString:@"Fade" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item2 = [CCMenuItemFont itemFromString:@"FlipAngular" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item3 = [CCMenuItemFont itemFromString:@"ShrinkGrow" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item4 = [CCMenuItemFont itemFromString:@"MoveInB" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item5 = [CCMenuItemFont itemFromString:@"MoveInT" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item6 = [CCMenuItemFont itemFromString:@"MoveInL" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item7 = [CCMenuItemFont itemFromString:@"MoveInR" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item8 = [CCMenuItemFont itemFromString:@"FadeTR" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item9 = [CCMenuItemFont itemFromString:@"FadeUp" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item10= [CCMenuItemFont itemFromString:@"FlipX" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item11= [CCMenuItemFont itemFromString:@"FlipY" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item12= [CCMenuItemFont itemFromString:@"PageTurn" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item13= [CCMenuItemFont itemFromString:@"CrossFade" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item14= [CCMenuItemFont itemFromString:@" " target:self selector:@selector(displayNext:)];
CCMenuItemFont *item15= [CCMenuItemFont itemFromString:@"return Main Menu" target:self selector:@selector(displayNext:)];

CCMenu *menu = [CCMenu menuWithItems:item1, item2, item3, item4, item5, item6, item7, item8, item9, item10,item11, item12, item13, item14,item15, nil];
[menu setPosition:ccp(size.width/2, size.height/2 + 20)];
[menu alignItemsVertically];
[menu alignItemsInColumns: [NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:2],
[NSNumber numberWithUnsignedInt:1], nil];
 
//[self addChild:menu z:1 tag:0];
[self addChild:menu];
item1.tag = 0;
item2.tag = 1;
item3.tag = 2;
item4.tag = 3;
item5.tag = 4;
item6.tag = 5;
item7.tag = 6;
item8.tag = 7;
item9.tag = 8;
item10.tag = 9;
item11.tag = 10;
item12.tag = 11;
item13.tag = 12; 
item15.tag = 14;
//*/
}
return self;
}


-(void)displayNext:(id)sender {
switch ([(CCMenuItemFont *)sender tag]) {
case 0: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCFadeTransition transitionWithDuration:1 scene:sMain withColor:ccc3(255,0,0)]];
}
break;
case 1: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCFlipAngularTransition transitionWithDuration:1 scene:sMain]];
}
break;
case 2: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCShrinkGrowTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 3: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCMoveInBTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 4: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCMoveInTTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 5: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCMoveInLTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 6: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCMoveInRTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 7: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCFadeTRTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 8: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCFadeUpTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 9: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCFlipXTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 10: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCFlipYTransition transitionWithDuration:1 scene:sMain ]];
}
break;
case 11: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCPageTurnTransition transitionWithDuration:10 scene:sMain ]];
}
break;
case 12: {
CCScene *sMain = [CCScene node];
[sMain addChild:[TransitMenu node]];
[[CCDirector sharedDirector] replaceScene:[CCCrossFadeTransition transitionWithDuration:1 scene:sMain ]];
}
break;
// Main Menu로 돌아가기
case 14: {
CCScene *sMain = [CCScene node];
[sMain addChild:[HelloWorld node]];
[[CCDirector sharedDirector] replaceScene:[CCCrossFadeTransition transitionWithDuration:1 scene:sMain ]];
}
break;
default:
break;
}
}


// 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

## HelloWorldScene.m에서도 "TransitMen"라는 메뉴항목을 추가하고 클릭시 해당 Scene으로 연결되도록 한다.

3. 실행화면
  1) 초기실행화면

  2)TransitMenu 화면  


  3) PageTurn 실행화면

Posted by 꿈을펼쳐라
,
대부분의 게임을 시작하게되면 처음 나오는 초기메뉴를 구현해보자. 

[HelloWorldScene.m]
...
// 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] )) {
CCLabel* label = [CCLabel labelWithString:@"http://simverse.tistory.com  @simverse" fontName:@"Marker Felt" fontSize:20];
CGSize size = [[CCDirector sharedDirector] winSize];
label.position =  ccp( size.width / 2 , size.height/8 );
[self addChild: label];
CCMenuItemFont *item1 = [CCMenuItemFont itemFromString:@"Tutorials" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item2 = [CCMenuItemFont itemFromString:@"Start Game" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item3 = [CCMenuItemFont itemFromString:@"Option" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item4 = [CCMenuItemFont itemFromString:@"High Score" target:self selector:@selector(displayNext:)];
CCMenuItemFont *item5 = [CCMenuItemFont itemFromString:@"About" target:self selector:@selector(displayNext:)];
CCMenu *menu = [CCMenu menuWithItems:item1, item2, item3, item4, item5, nil];
[menu setPosition:ccp(size.width/2, size.height/2 + 20)];
[menu alignItemsVertically];
//[self addChild:menu z:1 tag:0];
[self addChild:menu];
item1.tag = 0;
item2.tag = 1;
item3.tag = 2;
item4.tag = 3;
item5.tag = 4;
NSLog(@"cx:%f cy:%f", size.width, size.height);
}
return self;
}


시뮬레이터에서 보면 다음과 같은 결과 화면이 나타난다. 

그후에 각 메뉴항목을 클릭했을 때의 구현은 다음 소스에서 확인하자.

-(void)displayNext:(id)sender {
NSLog(@"displayNext [tag:%i]", [(CCMenuItemFont *)sender tag]);
switch ([(CCMenuItemFont *)sender tag]) {
case 0: {
// CCScene *s1 = [CCScene node];
// [s1 addChild:[ShootGame node]];
// [[CCDirector sharedDirector] replaceScene:[CCFlipXTransition transitionWithDuration:1 scene:s1]];
}
break;
case 1: {
// CCScene *s1 = [CCScene node];
// [s1 addChild:[GameScene node]];
// [[CCDirector sharedDirector] replaceScene:[CCFlipXTransition transitionWithDuration:1 scene:s1]];
}
break;
default:
break;
}
}





Posted by 꿈을펼쳐라
,

cocos2D를 구성하고 있는 주요 클래스와 기본 개념을 살펴보면 다음과 같다.
(원문 : http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:basic_concepts#scenes) 
CCScene  
  - app 구현흐름에 비교적 독립적인 장면 구현 : (scene ==  screens == stages )
  - app는 여러개를 갖을 수 있지만, 특정한 순간에는 단 하나의 scene만을 갖음.
  - 하나이상의 CCLayer로 구성됨. ( 형태 및 행위를 구현해줌)
  - Scene사이의 변환은  CCTransitionScene 클래스로 구현가능 ( ex. fade out/in, slide from a side, etc)
  - CCNode의 SubClass이므로 Actions에 의해 변환될 수 있음.
[scene의 구성]
CCDirector  
  - Scene들의 앞뒤 순서를 관리
  - shared Object( singleton)형태로 구현됨.
  - OpenGL ES의 초기화 담당
  - scene calls를 관리  
CLayer 
  - 그릴 수 잇는 영역의 크기를 갖고 있으며, 그리를 구현 방식을 정의함.
  - 타 Layer와 반투명 형태로 겹치게 표현가능
  - Event Handler를 구현하는 클래스 (Event는 특정 Layer가 해당이벤트를 받아 적용할 때까지 전파됨)
  - cocos2D에서는 유용한 CCLayer를 미리 정의해 두었음 ( 메뉴 담당 : CCMenu, 컬러 : CCColorLayer, 멀티픽셀러 : CCMultiplexLayer, ...  물론 사용자정의의 CCLayer를 구현할 수 있음) 
  - CCNode의 SubClass이므로 Actions에 의해 변환될 수 있음.
CCSprite  
  - 2D 이미지를 담당하고 있으며, 이동, 회전, 크기변환, 에니메이션 효과 등을 적용할 수 있음.
  - 다른 CCSprite Object를 하위로 갖을 수 있으며, 부모가 변환시 자식들도 변환됨
  - CCNode의 SubClass이므로 Actions에 의해 변환될 수 있음.
CCNode
  - Object C에서 NSObject와 마찬가지로 cocos2D의 대부분의 클래스는 CCNode에서 상속받음
  - 다른 Node를 추가/삭제하는 컨테이너 포함  
  - 특정 시점을 기준으로 Callback 함수 호출을 통한 스캐줄 관리  
  - Action을 실행할 수 있음.  
  - Rendering 방식을 정의할 수 있음.

클래스 세부정보 :   http://www.cocos2d-iphone.org/api-ref/0.99.4/annotated.html
Posted by 꿈을펼쳐라
,
cocos2D를 설치하고 cocos2D Template만을 적용해서 생성되는 Hello World 구현과정을 살펴보자. 

기본으로 생성되는 프로젝트는 다음과 같이 구성된다.


주요 프로세스 확인하기

1. main 함수(Other Sources/main.m)
#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
        // 사용자정의 Delegate호출
int retVal = UIApplicationMain(argc, argv, nil, @"_MyGameAppDelegate");   
[pool release];
return retVal;
}

 2.  _MyGameAppDelegate::applicationDidFinishLaunching()함수 
- (void) applicationDidFinishLaunching:(UIApplication*)application
{
// CC_DIRECTOR_INIT()
//
// 1. Initializes an EAGLView with 0-bit depth format, and RGB565 render buffer
        // 1. OpenGL ES 화면을 depth buffer를 사용하지 않고, 화면은 16bit color(565) 방식으로 세팅
// 2. EAGLView multiple touches: disabled
        // 2. 멀티터치는 사용하지 않음
// 3. creates a UIWindow, and assign it to the "window" var (it must already be declared)
        // 3. UIWindow를 생성하고 "window"변수에 연결
// 4. Parents EAGLView to the newly created window
        // 4. OpenGL ES구현 뷰인 UIWindow를 새로생성된 window에 연결생
// 5. Creates Display Link Director
        // 5. Display Link Director 생성 ( 이넘은 뭔지 아직 모르겠음)
// 5a. If it fails, it will use an NSTimer director 
        // 5a. 실패시에는 NSTimer director를 사용
// 6. It will try to run at 60 FPS
        // 6. 1초에 60번의 화면을 갱신하도록 기본 셋팅
// 7. Display FPS: NO
        // 7. 화면 갱신 속도(FPS : Frame Per Second)를 표시하지 않음
// 8. Device orientation: Portrait
        // 8. Portrait (세로방향)으로 화면을 표시
// 9. Connects the director to the EAGLView
// 9. 생성된 director를 OpenGL ES View에 연결

CC_DIRECTOR_INIT();
// Obtain the shared director in order to...
CCDirector *director = [CCDirector sharedDirector];
// Sets landscape mode
        // 화면을 Portrait (세로방향)가 아니라  Landscape(가로방향)으로 변경
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
// Turn on display FPS
        // 화면갱신 속도를 표시함으로 변경
[director setDisplayFPS:YES];
// Turn on multiple touches
EAGLView *view = [director openGLView];
        // 멀티터치 구현
[view setMultipleTouchEnabled:YES];
// Default texture format for PNG/BMP/TIFF/JPEG/GIF images
// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565
// You can change anytime.
        // 화면사용해상도는 16bit에서 32Bit로 변경 
[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA8888];
// 사용자 구현 Scen 호출
[[CCDirector sharedDirector] runWithScene: [HelloWorld scene]];
}
  1) applicationDidFinishLaunching() : 어플리케이션이 생성준비가 완료된 후 호출되는 함수  
     ㄱ. 프로그래밍 가능한 최초함수  (?)  : MFC의  CApp:: InitInstance() 와 비슷? 
  2) CC_DIRECTOR_INIT() : cocos2D 화면에 대한 초기화 세팅함수로 주요 기능은 다음과 같다.   
        // 1. OpenGL ES 화면을 depth buffer를 사용하지 않고, 화면은 16bit color(565) 방식으로 세팅
        // 2. 멀티터치는 사용하지 않음
        // 3. UIWindow를 생성하고 "window"변수에 연결
        // 4. OpenGL ES구현 뷰인 UIWindow를 새로생성된 window에 연결생
        // 5. Display Link Director 생성 ( 이넘은 뭔지 아직 모르겠음)
        // 5a. 실패시에는 NSTimer director를 사용
        // 6. 1초에 60번의 화면을 갱신하도록 기본 셋팅
        // 7. 화면 갱신 속도(FPS : Frame Per Second)를 표시하지 않음
        // 8. Portrait (세로방향)으로 화면을 표시
// 9. 생성된 director를 OpenGL ES View에 연결
  3) CC_DIRECTOR_INIT() 함수와 다른 특성을 재 설정 
  4) 사용자 구현 Scene 클래스 호출 ( HelloWorld scen)


3. HelloWorld::init() 
-(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 : 
   // CCLabel 생성 : 글자체, 글씨 크기 지정
CCLabel* label = [CCLabel 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.position =  ccp( size.width /2 , size.height/2 );
// add the label as a child to this Layer
[self addChild: label];
}
return self;
}

 4) HelloWorld::scene() 
+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorld *layer = [HelloWorld node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
    ㄱ. applicationDidFinishLaunching() 함수에서 직접호출   
    ㄴ. CCScene클래스에 CCLayer를 추가

Posted by 꿈을펼쳐라
,

아이폰 스터디를 찾아 해매던 차에, 구원의 손길을 주신 곳이 플래시카페(http://flashcafe.org)라는 곳이었는데, 이곳 스터디 명칭이 "아이폰/아이팟 게임제작 스터디"였다. 
사실, 게임에 약간은 과심이 있었지만, 게임제작은 나중에 여유있을 때 한번 해볼까? 하는 생각이었는데, 이곳 스터디에 참여하는 순간 선택의 여지가 없어졌다.  아이폰에서 가장 수익성 있는 분야 중하나이고, 이곳에서 게임 개발의 기초 및 게임 개발 분야에 있는 분들을 알아두면 좋겠다 싶어 열심히 공부하기로 했다.

1.  cocos2d 란 무엇인가? 
게임에서 가장 중요한 기술중 하나는 화면에 무엇을 뿌려주느냐이다.  데스트탑에서는 주로 MS의 Direct3D기술과 OpenGL기술을 사용하였지만, 모바일 단말기로 넘어오면서 OpenGL ES가 업계의 표준이 되었다. (http:/www.khronos.org)

 cocos2D는 이러한 openGL ES를 2D 게임개발에 보다 효율적으로 적용할 수 있도록 만들어 놓은 라이브러리/템플릿의 모임이다. 

2. OpenGL ES를 사용하면 되지 굳이 cocos2D를 사용할 필요가 있는가? 
물론, cocos2D는 OpenGL ES를 모아놓은 것이므로 OpenGL ES로 직접 구현가능하다.  하지만, 2D게임 개발에 필요한 많은 기능들을 쉽고 빠르게 적용할 수 있도록 만든 것이 cocos2D임으로 좀더 편하고, 빠르게 게임 개발이 가능하다.  그래도, 궁극적으로는 OpenGL ES에 대한 이해가 필요하므로 양쪽의 지식을 모두 확보하는 것이 좋으리라 생각된다. 


3. cocos2D 다운받기 
  1) 홈페이지 : http://www.cocos2d-iphone.org ->  download   tab
  2) 최신버전 ( iOS4용) : cocos2d-iphone-0.99.4-rc3.tar.gz

  3) 안정화버전 :   cocos2d-iphone -0.99.3.tar.gz


   (주의) 개발Tool을 최신버전(Xcode 3.2.3 : iOS4)를 사용한다면 2번을 그 이하버전을 사용한다면 3)번을 받으시면 된다. 


4. 설치하기 
  1) 다운받은 파일을 특정위치로 옯긴 후 압축을 풀어 놓음
  2) 터미널(응용프로그램->유틸리티->터미널)을 실생하고, 압축을 푼 위치로 이동 : Finder 에서 경로를 copy하여 사용  (cd, pwd, ls -l  명령어 이용) 
  3) ./install-templates.sh -u 을 이용하여 설치

Daniel-Leeui-MacBook-Pro:cocos2d-iphone-0.99.4-rc3 simverse$ ./install-templates.sh -u
cocos2d-iphone template installer
...creating cocos2d template directory




Installing cocos2d template
----------------------------------------------------

...creating destination directory: /Users/simverse/Library/Application Support/Developer/Shared/Xcode/Project Templates/cocos2d 0.99.4/cocos2d Application/
...copying template files
...copying cocos2d files
...copying cocos2d dependency files
...copying CocosDenshion files
...copying cocoslive files
...copying cocoslive dependency files
done!



Installing cocos2d + box2d template
----------------------------------------------------

...creating destination directory: /Users/simverse/Library/Application Support/Developer/Shared/Xcode/Project Templates/cocos2d 0.99.4/cocos2d Box2d Application/
...copying template files
...copying cocos2d files
...copying cocos2d dependency files
...copying CocosDenshion files
...copying cocoslive files
...copying cocoslive dependency files
...copying Box2D files
done!



Installing cocos2d + chipmunk template
----------------------------------------------------

...creating destination directory: /Users/simverse/Library/Application Support/Developer/Shared/Xcode/Project Templates/cocos2d 0.99.4/cocos2d Chipmunk Application/
...copying template files
...copying cocos2d files
...copying cocos2d dependency files
...copying CocosDenshion files
...copying cocoslive files
...copying cocoslive dependency files
...copying Chipmunk files
done!
...creating destination directory: /Users/simverse/Library/Application Support/Developer/Shared/Xcode/File Templates/cocos2d 0.99.4/



Installing CCNode file templates...
----------------------------------------------------

done!
Daniel-Leeui-MacBook-Pro:cocos2d-iphone-0.99.4-rc3 simverse$ 
[설치화면]


  4) 제대로 설치가 되었다면 Xcode -> create new Xcode Project 에서 다음과 같이  cocos2D template이 보일 것이다.

  ( 나의 경우, cocos2d 0.99.3과 cocos2d 0.99.4를 모두 설치하여 두개가 보인다.)

   4) 여기까지 온 김에 실제화면을 한번 확인해보자. 위의 화면에서 "cocos2d Application"을 선택하고 "Choose.." 버튼을 누르고, 프로그램을 실행시켜보자. 

   모든 프로그래밍의 시작 "Hello World"가 아래와 같이 나타난다. 



시작이 반이라고 하니, 이미 우리는 cocos2d 반은 배운 것이다. ^^  정말!!!
Posted by 꿈을펼쳐라
,


1. Project 생성
  1) Create a new Xcode Project -> View based Application -> "WebCtrl" 

2. Ctrl 추가 및 구현
  1) Text Field 추가 -> UITextField  연결
  2) Web View 추가 -> UIWebView 연결 
    ㄱ. delegate를 File's Owner에 연결해야함
    ㄴ. 부모 클래스 추가 : <UIWebViewDelegate>
  3) Round button 추가 - > (IBAction) goURL 연결

3. 헤더파일 및 소스파일

@interface WebCtrlViewController : UIViewController <UIWebViewDelegate> {
IBOutlet UITextField *urlText;
IBOutlet UIWebView *webDtl;

}
- (IBAction) goURL;
...
-(IBAction) goURL
{
NSString *urlAddr = urlText.text;
 
[webDtl loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlAddr]]]; 
}

- (void)webViewDidStartLoad:(UIWebView *)webView
{
NSLog(@"Start Load"); 
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(@"Finish Load"); 
}
 
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
NSLog(@"Fail Load");
}
...






무작정 따라하기를 시작한지 2주 남짓하여 12강의 AppsNext 무료 동영상 강의를 마무리 했다.

"시작하세요 아이폰3 프로그래밍"책으로 혹자 공부를 했었으나, 한달 남짓 나간 진도는 7장... 
하지만, 뒤 돌아보면 기억되는 것이 없는 상태에서, 주위의 소개를 공부를 시작했다.

한 강의당 20분 내외이므로 그냥 듣고 지나가면 2-3일 만에 마무리 할 수 있는 내용이었지만, 책으로 공부했을 때의 경험이 있는지라 이왕 할 것 정리를 해야겠다는 생각으로 블로그에 하나하나 자세히, 맥북에서 따라해보고 그 결과를
다시 데트크탑 PC에서 블로그에 정리했다.

이렇게 하다보니 20분 정도 하나의 강의를 공부하는데 2시간 정도 걸린 듯하다.  
하지만, 그만큼 효과와 보람이 있는 듯하다.

분명히 공부한 내용은 조금 지나면 잊혀지겠지만, 기억이 나지 않을 때 이곳에 와서 확인하면 보다 쉽게 기억해내고, 나에게는 좋은 레퍼런스가 될 것이며, 혹 누군가에도 좋은 자료나 자극이 된다면 더 좋겠다. 

아이폰 개발의 역사적인 첫 발을 찍으며...

Dream Big, Start Small
Posted by 꿈을펼쳐라
,




1. Project 생성
  1) Create a new Xcode Project -> View based Application -> "EtcCtrl"

2. Control 생성 및 연결
  1) Library 창에서 원하는 Control을 View에 올려 놓음
  2) header 파일에 해당하는 함수 혹은, 변수를 추가함
  3) Source 파일에서 해당하는 함수, 혹은 변수 구현 ( 변수일 경우, release 확인)
  3) IB에서 컨트롤과 해당하는 함수, 혹은 변수와 연결 ( 함수는 컨크롤에서 File's Owner로, 변수는 File's Owenr에서 해당 컨크롤로 연결)

3. Header / Source 파일
@interface EtcCtrlViewController : UIViewController {
IBOutlet UIProgressView *neoProgress;
}

- (IBAction) segmentChange:(id)sender;
- (IBAction) switchChange:(id)sender;
- (IBAction) sliderChange:(id)sender;
- (IBAction) click1;
- (IBAction) click2;
- (IBAction) click3;


@end

...

- (IBAction) segmentChange:(id)sender
{
 NSLog(@"click index %i", [sender selectedSegmentIndex] );
}

- (IBAction) switchChange:(id)sender
{
UISwitch* tmpSwitch = (UISwitch* ) sender;
 
if(tmpSwitch.isOn){
NSLog(@"현재 켜짐");
}
else {
NSLog(@"현재 꺼짐");
}
}
 
- (IBAction) sliderChange:(id)sender
{
UISlider *slider = (UISlider *) sender; 
NSLog(@"value : %f", slider.value); //0~1 소수형
}

-(IBAction) click1
{
neoProgress.progress =0.3; 
}

-(IBAction) click2
{
 neoProgress.progress =0.6; 
}

-(IBAction) click3
{
neoProgress.progress =1.0;
}

...



[기타사항]

1. 자료형변환 :  UISlider *slider = (UISlider *) sender;  에서와 같이 "( * )"를 사용. : []를 사용해놓고 에러 때문에 30분 해멤.  헥~헥~

2. 변수 neoProgress 도 relase 해워야 할 듯. (이제 신경도 안쓰시네..)
Posted by 꿈을펼쳐라
,



1. Project 생성
  1) Create a new Xcode Project -> View based Application -> "AlertManager"

2. Action Button 연결하기
  1) Round Button 추가 -> 버튼명 설정
  2) header 파일에 함수 선언  : - (IBAction) clickButton;
  3) source 파일(*.m) 파일에 정의  : - (IBAction) clickButton;
  4) IB에서 Round Button 클릭 후 File's Owner로 오른쪽 마우스 클릭 후, Drag & Drop -> 함수연결

3.UIAlertView / UIActionSheet 사용하기
    -> 프로그램 코드 참고

4. UIAlertView / UIActionSheet 의 버튼 클릭 이벤트 사용하기
  1) Header 파일에 이벤트를 컨트롤 할 수 있는 Delegate Class를 상속받을 수 있도록 함 :
     ㄱ. UIAlertViewDelegate, UIActionSheetDelegate ; 
  2)  버튼 클릭시 호출되는 함수를 구현
     ㄱ. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
     ㄴ. - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

   
5. 구현소스
...
@interface AlertManagerViewController : UIViewController <UIAlertViewDelegate, UIActionSheetDelegate> {
}

- (IBAction) clickSimple;
- (IBAction) clickMulti;
- (IBAction) clickActionSheet;

...

..
- (IBAction) clickSimple
{
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:@"질문에 답해주세요."  
message:@"아이폰 프로그래밍 너무 재미있죠?"  delegate:self 
cancelButtonTitle:@"뭐,그런걸 다" otherButtonTitles:@"당근이죠",nil];
 
[alert show];
[alert release]; 
}

- (IBAction) clickMulti
{
 UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"솔직하게 답해주세요"
message:@"계속 아이폰 프로그래밍 공부 하실 건가요?" delegate:self
cancelButtonTitle:@"말할수 없음" otherButtonTitles:@"당근빳따",
@"기회가된다면!",@"싫어욧!",nil];
 
[alert show];
[alert release];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(alertView.title);
NSLog(@"Pressed button index : %ith", buttonIndex);
 
if(buttonIndex ==2 || buttonIndex ==3)
{
[self clickMulti];
}
}

- (IBAction) clickActionSheet
{
 UIActionSheet *actionSheet = [[UIActionSheet alloc]initWithTitle:@"당신의 열정을 보여주세요" delegate:self cancelButtonTitle:@"뭐 이런걸 다 ..." destructiveButtonTitle:@"나의 열정은 마르지 않는 샘물" otherButtonTitles:@"안개속에서 나는 울었어~",@"외로워서 한참을 울었어~", nil];
 
[actionSheet showInView:[self view]];
[actionSheet release];
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(actionSheet.title);
NSLog(@"Pressed button index : %ith", buttonIndex);
 
if(buttonIndex ==2 || buttonIndex ==3)
{
[self clickActionSheet];
}
}
..

6. 실행화면  
  1) clickSimple 실행화면

  2) clickMulti 실행화면

  3) clickActionSheet 실행화면


[특이사항]
1. UIAlertView의 버튼이 2개까지는 옆으로 정렬되어 나오고, 3개 이상부터는 수직으로 펼쳐진다.
2. 버튼 클릭시 발생하는 clickedButtonAtIndex 함수에서 인자로 넘어오는 buttonIndex 값이 UIAlertView와 UIActionSheet의 기준이 틀림
   1) UIAlertView : Canel 버튼이 항상 0이고, 나머지 버튼들이 순차적인 index를 지님
   2) UIActionSheet : Canel 버튼을 포함하여, 위에서부터 순차적인 index를 지님
3. 여러개의 Alert이나 ActionSheet가 있을 경우, title값을 확인하여 어쩐 질문인지를 파악할 수 있음.
   ( 스트링 비교가 부담될 것 같은데, 더좋은 방법이 있을까? : 물론 생성하는 alertView의 포인터를 관리하는 방법이 있겠으나 일반적으로 사용하는 방법은? )
 

Posted by 꿈을펼쳐라
,


1. Project 생성
  1) Create a new Xcode Project -> View based Application -> "PickerTest"

2. Picker View 추가/연결하기
  1) PickerTestViewController.xib 실행
  2) Library 창에서 "Picker View"와 "Label"을 윈도우로 Drag & Drop 
  3) IBOutlet 변수 추가
@interface PickerTestViewController: UIViewController {
IBOutlet UIPickerView *dataPicker;
IBOutlet UILabel *selectedText;

}
@end

  4) File's Owner 선택해 "Picker View"와 "Label"에 각각 변수연결
  5) UIPickerViewDataSource 클래스의 " required" 메소스 추가
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView 
      Picker Control의 Picker 갯수 (선택 항목 갯수)
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component 
      Picker Control의 항목갯수 (행 갯수)
  6) UIPickerViewDelegate 클래스의 " required" 메소스 추가
   - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)
component 
      Picker Control의 각 항목의 내용 입력     
  7) 헤더 파일에, <UIPickerViewDataSource,UIPickerViewDelegate> 에서 상속됨을 표시
  8) View 화면에서 "Picker View"를 File's Owner로 Drag & Drop하여, dataSource와 delegate를 연결

3. 출력 데이터를 적용
 1) 헤더파일 멤버변수 추가
    - NSMutableArray *pickData; 추가
 2) 배열 초기값 입력 
   - (void)viewDidLoad 함수에서 pickData 
   - NSMutableArray 초기화 방법 적용
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
  pickData = [[NSMutableArray alloc]init];
 [pickData addObject:@"1등입니다."];
 [pickData addObject:@"2등입니다."];
 [pickData addObject:@"3등입니다."];
 [pickData addObject:@"4등입니다."];
 [pickData addObject:@"5등입니다."];
 [pickData addObject:@"6등입니다."];
 [pickData addObject:@"7등입니다."];
 3) 선택된 항목을 Label에 출력하기 
  - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
  //NSLog(@"value : %i", row);
 selectedText.text = [pickData objectAtIndex:row];
}

4. Source 및 해더 파일

@interface PickerTestViewController: UIViewController {
IBOutlet UIPickerView *dataPicker;
IBOutlet UILabel *selectedText;

NSMutableArray *pickData;

}
@end


...
 
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
pickData = [[NSMutableArray alloc]init];
[pickData addObject:@"1등입니다."];
[pickData addObject:@"2등입니다."];
[pickData addObject:@"3등입니다."];
[pickData addObject:@"4등입니다."];
[pickData addObject:@"5등입니다."];
[pickData addObject:@"6등입니다."];
[pickData addObject:@"7등입니다."];

 
[super viewDidLoad];
}

...

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [pickData count];
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [pickData objectAtIndex:row];
// return @"피커뷰 입니다.";
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(@"value:%i",row);
selectedText.text = [pickData objectAtIndex:row];
}


- (void)dealloc {
[pickData release]; 
[dataPickerrelease]; 
[selectedText release]; 


[super dealloc];
}

...

 

TRACE 적용하기

Source 중에 NSLog(@"value:%i",row); 와 같이 출력하고자 하는 Text를 문법에 맞춰 코딩하고, 실행시 Xcode의 gdb버튼을 클릭하면, 해당 소스가 실행될때, gdb 실행윈도우에 문법에 해당하는 Text가 출력됨.


[Question]
pickData 이넘을 release 해주는 것인 맞는 것인가요?
Posted by 꿈을펼쳐라
,


1. Project 생성
  1) Create a new Xcode Project -> Window based Application -> "SendData"

2. Navigation Controller 추가/구현
  1) Navigation Controller 추가 (Drag & Drop)
  2) Header /Source 파일에 변수 및 addSubView 함수 추가
  3) 변수 연결

3. 클래수 추가 
  1) 세개의 뷰를 추가 
     a. Class 폴더 마우스 우측 클릭, Add -> New File -> "UIView Controller subClass" with Xib for user interface
         "FirstView", "SecondView" 추가
     b. "Text Field" "Round Button"을 first view에 Drag & Drop 추가 
     c. header 관련 변수 및 함수 추가
@interface FirstView : UIViewController {
IBOutlet UITextField *textData;
}
-(IBAction) sendSecondView;
@end

    d. 변수와 함수를 연결 (FirstView.Xib )
      - 변수 연결 : File's Owner는 먼저 선택하고 마우스 오른쪽 클릭 후 Text Field에 Drag & Drop 후 "textField" 선택
      - 함수 연결 : Round Button을 먼저 선택하고 File's Owner에 Drag & Drop 후 "sendSecondView" 선택
    e. Navigation Cotroller에 FirstView 적용 
      - MianWindow.Xib에서 Navigation Controller를 펼쳐, View Controller를 선택
      - View Controller의 Attributes창(Cmmnd+1)에서 NIB NAME에서 FirstView를 선택, Identity에서도 Class 항목을 FirstView Class를 선택하여 실행  
     f. 함수 연결 및 추가
#import "FirstView.h"
#import "SecondView.h"

@implementation FirstView

...

-(IBAction) sendSecondView
{
UINavigationController *sNav = self.navigationController;
 
SecondView *sView = [[SecondView alloc] initWithNibName:@"SecondView"     bundle:nil];
 
[sNav pushViewController:sView animated:YES];
[sView release]; 
}

...

- (void)dealloc {
[textField release];    
[super dealloc];
}

4. XIB 연동 및 값전달
  1) SecondView 구현 
     a. NSString *recevieData 변수 추가 및 @property 및 @synthesize 구현
     b. View에 Label Drag & Drop하고 변수추가(IBOutlet UILabel *lblText) 및 연결
@interface SecondView : UIViewController {
NSString *receiveData;
IBOutlet UILabel *lblText;

}
@property (readwrite, assign) NSString *receiveData;
@end
@implementation SecondView
@synthesize receiveData;

...
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
lblText.text = receiveData;
[super viewDidLoad];
}

...

- (void)dealloc {
[lblText release];
[super dealloc];
}

  2) FirstView의 sendSecondView에 값전달 기능 구현
-(IBAction) sendSecondView
{
UINavigationController *sNav = self.navigationController;
 
SecondView *sView = [[SecondView alloc] initWithNibName:@"SecondView"     bundle:nil];
sView.receiveData = textData.text; 
 
[sNav pushViewController:sView animated:YES];
[sView release];

 }
Posted by 꿈을펼쳐라
,