'Xcode'에 해당되는 글 9건

이번에는 cocos2d Touch Event  처리 방법이다.

터치 이벤트는 두가지 방법이 있는데, 하나는 싱글 터치 처리 방식이고, 나머지 하나는 멀티 터치 처리 방식이다.

게임을 할때, 좌우 방향 버튼도 있고, 발사 버튼, 점프 버튼 등이들어가는 아케이드 같은 게임들은 멀티 터치 처리를 해줘야 한다.
즉, 터치 이벤트들을 모두 받아서 차례로 다 처리 해줘야 하는 것이다.

하지만, 앵그리버드 같은 게임은 그냥 손가락 하나만 슥슥 움직이고, 눌러주고 하는 컨트롤이 대부분이기 때문에, 굳이 멀티 터치를 사용할 필요가 없다.
오직 한번에 터치 이벤트 하나만 처리하도록 만들면 되는 것이다.

그러면 다음 소스를 보면서, 첫번째는, 싱글터치 처리 방법에 대해서 알아보고, 두번째는 멀티 터치 처리 방법에 대해서 알아보자.
구현할 예제는 지난 예제에서 사용한 우리 거북군을 아무런 효과도 없이 그냥 터치가 들어오는 이벤트에 맞게 이리 저리 움직여 보는것으로 하자.

멀티 터치는 예제로 표현하기 좀 애매해서, 예제 동영상은 싱글 터치에 대해서만 촬영해서 올리도록 하겠다.

1. 싱글 터치만 사용할 경우.(지난 예제들과 똑같다,)

 

//

//  HelloWorldLayer.m

// 



// Import the interfaces

#import "HelloWorldLayer.h"



//static int transitionIndex=0;

static int effectIndex=0;


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

}


-(id) init

{

// always call "super" init

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

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

        self.isTouchEnabled = YES;     // Layer를 초기화 할때, 나는 터치를 받겠습니다. 라고 해줘야 한다.     


}

return self;

}

 

- (void) registerWithTouchDispatcher {

    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

}


- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {// 터치 시작했다.

    CGPoint location = [touch locationInView: [touch view]];

    

CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

NSLog(@"ccTouchBegan : %f , %f",convertedLocation.x ,convertedLocation.y);

    

    return YES;

   

}


- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event { // 엇? 움직이네?

    CGPoint location = [touch locationInView: [touch view]];

    

CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

NSLog(@"ccTouchMoved  %f , %f",convertedLocation.x ,convertedLocation.y);

    

    


}


- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event { // 손뗐어.

    CGPoint location = [touch locationInView: [touch view]];

    

CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

NSLog(@"ccTouchEnded : %f , y : %f",convertedLocation.x ,convertedLocation.y);


    

}


- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event { // 터치한거 취소야.

    

} 
그런데 레이어마다 각가가 터치 이벤트를 처리할수 있게 되면 어떻게 되는거지? 하고 잠시 고민하고 생각했다면.!!! 굉장히 바람직하다.
처음에 나는매번 레이어가 바뀔때마다, "이 놈들은 터치를 받지 말아야 해" 하며 NO로 설정하는 작업을 넣어줬으나, cocos2d는 그렇게 호락 호락한 프레임워크가 아니었다. 

여러개의 레이어들이 중첩되어 있는 상태라면, 터치 이벤트를 처리할수 있돌고 한 레이어중 TOP에 올라오는 레이어가 해당 터치 이벤트를 받아먹게 된다. 위에서 언급한 각 레이어들을 직접 터치 enable/disable 해주는 작업이 필요한 경우도 있으나, 그렇게 많이 고민 할필요는 없다.
 
그리고 어떤 터치 방법을 사용할것이냐에 대해서 설정하는 것이, registerWithTouchDispatcher 메소드 인데, CCTouchDispatcher를 들여다보면 아래와 같이 되어 있습니다.

즉, 이 레이어에서 터치를 전달 받겠다고 하는 것이고, 그 이벤트들을 처리해주는 메소드들이 바로 위에 나오는 메소드들이다.
 

-(void) addStandardDelegate:(id<CCStandardTouchDelegate>) delegate priority:(int)priority

{

CCTouchHandler *handler = [CCStandardTouchHandler handlerWithDelegate:delegate priority:priority];

if( ! locked ) {

[self forceAddHandler:handler array:standardHandlers];

} else {

[handlersToAdd addObject:handler];

toAdd = YES;

}

}


각 터치 이벤트를 처리하는 메소드 아래 아래와 같은 내용이 있는데, 이건 좌표계를 변환해주는것이다. 우리가 사용하는 코코스2d좌표계와 openGL의 좌쵸가 다르기 때문에(y좌표) 아래 처럼 사용하는 것이다.

CGPoint location = [touch locationInView: [touch view]];  // 싱글 터치라서 touch를 바로 가져다가 쓴다.

    

GPoint convertedLocation = [[CCDirector sharedDirectorconvertToGL:location];



2. 멀티 터치를 사용할 경우.  (메소드의 인자가 다르다)

 

- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

NSSet *allTouches = [event allTouches];

int count = [allTouches count];

if(count > 1){


NSArray *current_touches = [allTouches allObjects];

for(int i=0; i<count;i++){

UITouch *touch = [current_touches objectAtIndex:i];

CGPoint location = [touch locationInView:[touch view]];

location = [[CCDirector sharedDirector] convertToGL:location];


}

}else {

UITouch *touch = [touches anyObject];

CGPoint location = [touch locationInView:[touch view]];

location = [[CCDirector sharedDirector] convertToGL:location];


}

}


-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

UITouch *touch = [touches anyObject];

CGPoint location = [touch locationInView:[touch view]];

location = [[CCDirector sharedDirector] convertToGL:location];


}


- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

UITouch *touch = [touches anyObject];

CGPoint location = [touch locationInView:[touch view]];

location = [[CCDirector sharedDirector] convertToGL:location];


}


 
 
멀티 터치는 싱글 터치보다 역시 복잡하다. register하는 메소드는 사용하면 안되고, 위에서 보는 것처럼 함수를 구현해주면, 멀티 터치를 처리 해줄수 있다. 눈여겨 봐야 할부분은 began시에 터치 이벤트의 수를 세이라는 부분이다. 이놈이 지금 멀티 터치일경우,아닐경우를 잘 구분해서처리해줘야 한다.


오늘도 어김 없이. 예제를 하나 만들어보자.

거북군을 움직여 보자. 움직이는 방법은 손가락으로 화면의 임의의 곳을 터치 하면 거북군이 스멀 스멀 그쪽으로 이동하게 한다.

 

- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint location = [touch locationInView: [touch view]];

    

CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

NSLog(@"ccTouchEnded : %f , y : %f",convertedLocation.x ,convertedLocation.y);


    [turtleSprite stopAllActions];

    [turtleSprite runAction: [CCMoveTo actionWithDuration:MOVE_DURATION position:convertedLocation]];

    

}

 

 이전까지 했던 소스에서, 터치가 업되는 순간에 위와 같이 해주면 터치된 좌표로 움직이게 된다. 너무 쉽다. 맞다!! 이렇게 시작하는거다 원래.

위 코드에서 CMoveTo 효과가 나오는데, 지난번에 이야기 한 것들과 마찬가지로 이것도 하나의 action이다, 이전것들은 effect 를 위한 action 들이고, 이넘은 아주 기초적인 action이다. 이 내용도 굉장히 많은데, 다음 포스트에서 basic action들을 비롯해서, 한번 또 다 확인해보도록 하자.

그리고 MOVE_DURATION 값을 3.0으로 줬는데, 의미하는 바는, 정해진 좌표까지 moveto하는데 걸리는 시간은 항상 일정하게 3초가 걸리도록 하라 이다.
즉, 멀리 찍으면 빨리 움직이고, 가까이 찍으면 천천히 움직이게 하는 것이다.


마지막으로 동영상 올라간다.
 

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

iOS용 게임 개발기 -8-  (0) 2011.08.20
iOS용 게임 개발기 -7-  (0) 2011.08.19
iOS용 게임 개발기 -6-  (0) 2011.08.17
VoodooHDA 64비트 빌드 그리고, nVidia HDMI 제거.  (2) 2011.08.15
iOS용 게임 개발기 -5-  (0) 2011.08.10
iOS용 게임 개발기 -4.1-  (0) 2011.08.02
블로그 이미지

rekun,ekun 커뉴

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

어제에 이어 오늘 포스트는 sprite에 대한 Effect Action에 대한 주제이다. 
즉, 우리가 게임중이든 어떠한 목적을 가지는 어플에서 이미지를 사용할때, 그 이미지에 특별한 효과를 주고 싶을때 cocos2d를 사용하지 않는 다면, 직접 openGL을 사용하여 모핑 효과라던지, 여러가지 효과를 줘야 하는데, 그걸 개발자가 사용하기 쉽게 cocos2d에서는 API로 제공하고 있다.

어제 만든 예제를 중, HelloWorldLayer에다른 이미지를 넣어서 cocos2d에서 제공하는 모든 Effect Action을 한번 사용해 보자.

이번에는 BlueOcean의 메인 캐릭터인 거북군이 등장한다.

21가지의 effect들을 모두 테스트 해본결과, cocos2d에서는 3d effect들은 정상적으로 나오지 않는것 같다. 이부분은 depth버퍼등을 조절하여 확인하였으나, 이쁘게 나오지 않는다, 대신 2D전용 effect들은 확실히 쓰임새가 많을것같다.

바로 소스 첨부한다.

수정이 필요한 부분은 appdelegate에서 EAGL설정해주는 부분이 있는데, 1.0 부터는 depth버퍼와 pixel color타입을 이때 바로 생성해주어여 한다.아래와 같이 코드를 수정하자,

아래 굵은 부분을 잘 확인하고 수정해야, effect를 줄때 해당 sprite만 컨트롤이 가능하다.
 

//

//  AppDelegate.m

// 


#import "cocos2d.h"



@implementation AppDelegate


@synthesize window;



- (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:kEAGLColorFormatRGBA8

   depthFormat: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:NO];

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

}

 
 

이렇게 하면, 일단 openGL설정은 다 끝났다. 이제 helloWorldLayer로 가서, 이펙트들을 하나씩 다 사용해보자.
구글을 뒤져보거나 하면 각 effect들을 사용하는 샘플 코드가 몇개 나오지 않는다. 본 포스트에서는 cocos2d 1.0이 제공하는 모든 effect들 21가지의 샘플 코드를 모두 작성하여 아래와 같이 만들어보았다.


일단 sprite 의 effect들은 action을 정의 한후, sprite의 runAction메소드를 사용하여 효과를 줄수 있다. 
 

//

//  HelloWorldLayer.h

//  

//



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

#import "cocos2d.h"


// HelloWorldLayer

@interface HelloWorldLayer : CCLayer

{

    CCSprite *turtleSprite;  // 거북군을 위한 sprite, 모든 효과를 여기에 준다.

    CCLabelTTF* effectlabel;

    CGSize size;

    id effectAction; // --> effect들을 정의하는 action을 저장함.


}


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

+(CCScene *) scene;


@end

 
 

지난 예제에서는 매번 label을 생성하고 계속 child로 추가하였는데, 이렇게 하면 나중에 메모리 부족 문제가생길수 있다. 
그래서 이번예제에서는 하나만 생성하고, 해당 문자열을 업데이트 하는 구조로 변경하였다. 

배경이미지를 하나 정해서 뿌려주고, 거북군을 올려준다.
 

//

//  HelloWorldLayer.m

//  cocos2dTest

//

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

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

//



// Import the interfaces

#import "HelloWorldLayer.h"


#define EFFECT_MAX          21


//static int transitionIndex=0;

static int effectIndex=0;


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

}


-(id) init

{

// always call "super" init

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

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

        self.isTouchEnabled = YES;  

        effectAction = nil;

        

        // ask director the the window size

        size = [[CCDirector sharedDirector] winSize];

        

        //bg sprite

        

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

        

        sprite.anchorPoint = CGPointZero;                        

        

        [sprite setPosition: ccp(0, 0)];

        [self addChild:sprite z:1 tag:1];

        

        //turtleSprite = sprite;

        

        turtleSprite = [CCSprite spriteWithFile:@"turtle1.png"];

        

                              

        

        [turtleSprite setPosition: ccp( size.width /2 , size.height/2 )];

        [self addChild:turtleSprite z:1 tag:1];

                

        CCLabelTTF* label= [CCLabelTTF labelWithString:@"coolkim.tistory.com" fontName:@"AppleGothic" fontSize:24];

        

        

        // position the label on the center of the screen

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

        //[label setVisible:NO];

        // add the label as a child to this Layer

        [self addChild: label z:16 tag:2];    

        

        

        effectlabel= [CCLabelTTF labelWithString:@"Touch to play" fontName:@"AppleGothic" fontSize:24];

        effectlabel.positionccp( size.width /2 , size.height/4 );

        //[effectlabel setVisible:NO];

        // add the label as a child to this Layer

        [self addChild: effectlabel z:2 tag:2];


}

return self;

}

 


터치 입력이 완료될때, 즉, touch up일경우에 효과를 무한 반복으로보여주고, 다음 효과로 넘어간다. 
아래의 샘플 코드를 응용하여, 여러가지 효과를 조합해서 사용할수도 있다. 이부분은 action  부분만 따로 주제를 다룰때 다시 이야기 하도록 하자.
 

- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint location = [touch locationInView: [touch view]];

    

CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

NSLog(@"ccTouchEnded : %f , y : %f",convertedLocation.x ,convertedLocation.y);


    effectAction=nil;

    switch (effectIndex)

    {

        case 0:

            [effectlabel setString:@"CCFlipX3D"];

            effectAction = [CCFlipX3D actionWithDuration:1.0f];

            break;

            

        case 1:

            [effectlabel setString:@"CCFlipY3D"]; 

            effectAction = [CCFlipY3D actionWithDuration:1.0f];

            break;

            

        case 2:

            [effectlabel setString:@"CCLens3D"];

            effectAction = [CCLens3D actionWithPosition:ccp(size.width/2,size.height/2) radius:240 grid:ccg(15,10) duration:1.0f];

            break;

            

        case 3:

            [effectlabel setString:@"CCLiquid"];   

            effectAction = [CCLiquid actionWithWaves:40 amplitude:37 grid:ccg(6, 33) duration:200];

            break;

            

        case 4:

            [effectlabel setString:@"CCRipple3D"]; 

            effectAction = [CCRipple3D actionWithPosition:turtleSprite.position radius: size.width/2 waves:2 amplitude:10 grid:ccg(50,50) duration:5];

            break;

            

        case 5:

            [effectlabel setString:@"CCShaky3D"];

            effectAction = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];

            break;

            

        case 6:

            [effectlabel setString:@"CCTwirl"];

            effectAction = [CCTwirl actionWithPosition:turtleSprite.position twirls:10 amplitude:10 grid:ccg(50,50) duration:10 ];

            break;

            

        case 7:

            [effectlabel setString:@"CCWaves"];

            effectAction = [CCWaves actionWithWaves:5 amplitude:20 horizontal:YES vertical:NO grid:ccg(15,10) duration:5];

            break;

            

        case 8:

            [effectlabel setString:@"CCWaves3D"];  

            effectAction = [CCWaves3D actionWithWaves:18 amplitude:15 grid:ccg(15,10) duration:10];

            break;

            

        case 9:

            [effectlabel setString:@"CCFadeOutBLTiles"];

            effectAction = [CCFadeOutBLTiles actionWithSize:ccg(50,50) duration:5];

            break;

            

        case 10:

            [effectlabel setString:@"CCFadeOutTRTiles"];

            effectAction = [CCFadeOutTRTiles actionWithSize:ccg(50,50) duration:5];

            break;

            

        case 11:

            [effectlabel setString:@"CCFadeOutUpTiles"];

            effectAction = [CCFadeOutUpTiles actionWithSize:ccg(50,50) duration:5];

            break;

            

        case 12:

            [effectlabel setString:@"CCFadeOutDownTiles"];

            effectAction = [CCFadeOutDownTiles actionWithSize:ccg(50,50) duration:5];

            break;

            

        case 13:

            [effectlabel setString:@"CCJumpTiles3D"];

             effectAction = [CCJumpTiles3D actionWithJumps:2 amplitude:10 grid:ccg(50,50) duration:5];

            break;

            

        case 14:

            [effectlabel setString:@"CCShakyTiles3D"];

            effectAction = [CCShakyTiles3D actionWithRange:2 shakeZ:NO grid:ccg(50,50) duration:5 ];

            break;

            

        case 15:

            [effectlabel setString:@"CCShatteredTiles3D"];

            effectAction = [CCShatteredTiles3D actionWithRange:10 shatterZ:NO grid:ccg(50,50) duration:5 ];

            break;

            

        case 16:

            [effectlabel setString:@"CCShuffleTiles"];

            effectAction = [CCShuffleTiles actionWithSeed:2 grid:ccg(50,50) duration:5];

            break;

            

        case 17:

            [effectlabel setString:@"CCSplitCols"];

            effectAction = [CCSplitCols actionWithCols:4 duration:5];

            break;

            

        case 18:

            [effectlabel setString:@"CCSplitRows"];

            effectAction = [CCSplitRows actionWithRows:4 duration:5];

            break;

            

        case 19:

            [effectlabel setString:@"CCTurnOffTiles"];

            effectAction = [CCTurnOffTiles actionWithSeed:2 grid:ccg(50,50) duration:5];

            break;

            

        case 20:

            [effectlabel setString:@"CCWavesTiles3D"];

            effectAction = [CCWavesTiles3D actionWithWaves:5 amplitude:10 grid:ccg(50,50) duration:5];

            break;

            

    }

    


    effectIndex++;

    

    if(effectIndex == EFFECT_MAX)

        effectIndex=0;

    

    if(effectAction != nil)

    {

        [turtleSprite stopAllActions]; // 이전의 효과는 모두 종료시키고.

        [turtleSprite runAction: [CCRepeatForever actionWithAction: effectAction]]; //새로운 효과를 실행한다.

    }

}

 


아래 동영상은 위의 예제를 실행시킨 화면을 캡쳐한 것이다. 보는것과 같이 3D 효과는 잘 먹지 않는다. 이부분은 확인해보고, 어떻게 하면 잘나오는지 수정방법을 찾으면 업데이트 하도록 하겠다. 


다음 포스트는 터치 이벤트를 처리해서, 스프라이트를 이동하는 법에 대해서 이야기하겠다. 게임을 만들면 캐릭터들을 콘트롤 하는 방법에 대한 주제이다.
 

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

iOS용 게임 개발기 -8-  (0) 2011.08.20
iOS용 게임 개발기 -7-  (0) 2011.08.19
iOS용 게임 개발기 -6-  (0) 2011.08.17
VoodooHDA 64비트 빌드 그리고, nVidia HDMI 제거.  (2) 2011.08.15
iOS용 게임 개발기 -5-  (0) 2011.08.10
iOS용 게임 개발기 -4.1-  (0) 2011.08.02
블로그 이미지

rekun,ekun 커뉴

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

이번 포스트는 원래 effect들에 대해서 이야기 하려 하였으나, 그 이전에 Scene들을 전환할때의 효과를 주는 Transition Effect를 먼저 다루고 넘어가는 것이 좋을것 같아.  금번 포스트의 주제를 Transition Effect로 한정하여 이야기 하겠다.

사실 BlueOcean개발 당시에는 이런 효과들을 전혀 생각치 못하고 진행하는 바람에, 뭔가 Scene간 이동시에 허전한 느낌이 적지 않았는데, 이번에 정리하다보니 이런 좋은 기능이 있다는것을 발견하게 되었다.

cocos2d에서는 Scene들을 여러개 만들어서, 다른 Scene으로 전환할때  replaceScene이라는 메소드를 사용할수 있다.
이 때 위에서 말한 Transition을 지정하여 주면 다양한 효과를 줄 수 있다.

그러면 바로 소스코드를 들여다 보자.

Scene이동의 핵심은 다음 한줄에 다 표현가능하다.
 
[[CCDirector sharedDirectorreplaceScene:[CCTransitionXXXX transitionWithDuration:0.5 scene:[NewScene scene]]];
 

이전에 만들었던, 시계앱은 Scene이 하나 밖에 없으므로, 이번에는 하나의 Scene 에는 "HelloWorld"만 나오게 하고, 다른 Scene에서는 시간만 나오게 하여 두 Scene들을 터치입력시 이동하게 해보자.

 지금까지 사용하던 예제코드에서 파일 분리 작업이 필요한데, DateSceneLayer파일을 추가해서, 시간을 찍어주도록 하였다. 그리고 이전까지 사용하던 HelloWorldLayer는 초심으로 돌아가서, 진짜 문자열만 딱 찍어주는 코드로 다시 돌아갔다.
이번에는 소스가 변경되는 부분이 많지만, 핵심 부분인 위의 효과를 어떻게 쓰는지만 알면 앞으로필요한 효과를 찾아서 쓰기만 하면 된다.


 

//

//  DateSceneLayer.h

//  cocos2dTest



#import "cocos2d.h"



@interface DateSceneLayer : CCLayer {

    CCLabelTTF *label;

    

    int             _currentBg;

    NSMutableArray* _bgSpriteList;

    

}


+(CCScene *) scene;

@end

 


DateSceneLayer는 HelloWorldLayer의 파일을 조금만 수정해서 아래와 같이 init코드를 만들어주면 된다.
어떤 효과를 나타낼것인지 설명하는 문자열을 추가하돌고 하고, 터치입력을 받는 부분을 추가했다.
터치 입력은 CCLayer를 상속받은 경우,  init 시에 self.isTouchEnabled = YES; 만 추가해주면 된다.

그리고 각각 입력 시작, 움직임, 끝, 취소 등의 이벤트를 처리하는 아래 메소드들을 구현해주면 된다.HelloWorldLayer소스에 다 추가해두었음.

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;

- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;

- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event; 
- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event; 

그리고, 터치 인벤트들을 어떻게 처리하는지에 대해서 아래와 같이 추가해주면 된다.

- (void) registerWithTouchDispatcher {

    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

}
 
터치처리에 대해서는 다음에 하나의 주제로 해서 다룰 계획이므로, 지금은 효과에 대해서만 집중하자. 

//

//  DateSceneLayer.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])) {

        

        self.isTouchEnabled = YES;  

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

        // position the label on the center of the screen

        CGSize size = [[CCDirector sharedDirector] winSize];

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

// add the label as a child to this Layer

[self addChild: label z:2 tag:2];

        

        [self schedule:@selector(updateTime) interval:1];

    

    

        _bgSpriteList = [[NSMutableArray alloc] init];

    

        for(int i=0;i<3;i++)

        {

            CCSprite *sprite=[CCSprite spriteWithFile:[NSString stringWithFormat: @"scenario%02d.png",i]];

        

        

            [_bgSpriteList addObject:sprite];

        

        

            sprite.anchorPoint = CGPointZero;                        

            sprite.opacity=0;

            [sprite setPosition: ccp(0, 0)];

            [self addChild:sprite z:1 tag:1];

        }

        _currentBg=0

        [self bgControl];

    

        [self schedule:@selector(bgControl) interval:4];

    }

return self;

}

 

HelloWolrdLayer 전체 소스
 

//

//  HelloWorldLayer.m

//  



// Import the interfaces

#import "HelloWorldLayer.h"

#import "DateSceneLayer.h"

#define TRANSITION_DURATION 1.0f

#define TRANSITION_MAX      29


static int transitionIndex=0;


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

-(void)updateText

{

    [self unschedule:@selector(updateText)];

    // create and initialize a Label

    

    // ask director the the window size

    CGSize size = [[CCDirector sharedDirector] winSize];

    CCLabelTTF* trasitionlabel=nil;

    switch (transitionIndex)

    {

        case 0:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionRotoZoom" fontName:@"AppleGothic" fontSize:32];

            break;

        

        case 1:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionJumpZoom" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 2:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionMoveInL" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 3:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionMoveInR" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 4:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionMoveInT" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 5:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionMoveInB" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 6:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionSlideInL" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 7:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionSlideInR" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 8:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionSlideInB" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 9:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionSlideInT" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 10:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionShrinkGrow" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 11:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionFlipX" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 12:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionFlipY" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 13:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionFlipAngular" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 14:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionZoomFlipX" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 15:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionZoomFlipY" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 16:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionZoomFlipAngular" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 17:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionFade" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 18:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionCrossFade" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 19:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionTurnOffTiles" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 20:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionSplitCols" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 21:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionSplitRows" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 22:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionFadeTR" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 23:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionFadeBL" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 24:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionFadeUp" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 25:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionFadeDown" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 26:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionRadialCCW" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 27:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionRadialCW" fontName:@"AppleGothic" fontSize:32];

            break;

            

        case 28:

            trasitionlabel= [CCLabelTTF labelWithString:@"CCTransitionPageTurn" fontName:@"AppleGothic" fontSize:32];

            break;

            

    }

    

    // position the label on the center of the screen

    if(trasitionlabel != nil)

    {

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

    

        // add the label as a child to this Layer

        [self addChild: trasitionlabel z:2 tag:2];

    }

    

    CCLabelTTF* label= [CCLabelTTF labelWithString:@"coolkim.tistory.com" fontName:@"AppleGothic" fontSize:32];


    // position the label on the center of the screen

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

    

    // add the label as a child to this Layer

    [self addChild: label z:2 tag:2];

    

}

-(id) init

{

// always call "super" init

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

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

        self.isTouchEnabled = YES;  

        [self schedule:@selector(updateText) interval:TRANSITION_DURATION];


}

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];

}

- (void) registerWithTouchDispatcher {

    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];

}


- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint location = [touch locationInView: [touch view]];

    

CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

NSLog(@"ccTouchBegan : %f , %f",convertedLocation.x ,convertedLocation.y);

    

    return YES;

   

}


- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint location = [touch locationInView: [touch view]];

    

CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

NSLog(@"ccTouchMoved  %f , %f",convertedLocation.x ,convertedLocation.y);

    

    


}


- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {

    CGPoint location = [touch locationInView: [touch view]];

    

CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

NSLog(@"ccTouchEnded : %f , y : %f",convertedLocation.x ,convertedLocation.y);

    

    //touch up

    //replace scene 

    switch (transitionIndex)

    {

        case 0:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionRotoZoom transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 1:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionJumpZoom transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 2:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionMoveInL transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 3:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionMoveInR transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 4:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionMoveInT transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 5:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionMoveInB transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 6:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInL transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 7:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInR transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 8:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInB transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 9:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionSlideInT transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 10:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionShrinkGrow transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 11:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionFlipX transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 12:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionFlipY transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 13:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionFlipAngular transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 14:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionZoomFlipX transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 15:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionZoomFlipY transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 16:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionZoomFlipAngular transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 17:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 18:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionCrossFade transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 19:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionTurnOffTiles transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 20:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionSplitCols transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 21:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionSplitRows transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 22:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionFadeTR transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 23:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionFadeBL transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 24:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionFadeUp transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 25:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionFadeDown transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 26:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionRadialCCW transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 27:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionRadialCW transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

        case 28:

            [[CCDirector sharedDirector] replaceScene:[CCTransitionPageTurn transitionWithDuration:TRANSITION_DURATION scene:[DateSceneLayer scene]]];

            break;

            

    }

    transitionIndex++;

    

    if(transitionIndex == TRANSITION_MAX)

        transitionIndex=0;

    


}


- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event {

    

}

@end


 

터치가 입력되면, 총 29개의 이펙트를 순차적으로 돌아가면서 하나씩 하나씩 해볼수 있게 구현하였다. 많은 이펙트들이 있는데, 직접 그 이펙트가 무엇인지 확인해보지 못하면, 언제 써야 될지 알수 없으므로, 위의 예제 코드를 실행시킨 아래 동영상을 보면 아 이놈이 이놈이구나 할수 있을것이다.


Scene두개를 만들어서 한번 위의 효과들을 적용해서 테스트 해보면, 금방 사용할수 있을것이다. 

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

iOS용 게임 개발기 -8-  (0) 2011.08.20
iOS용 게임 개발기 -7-  (0) 2011.08.19
iOS용 게임 개발기 -6-  (0) 2011.08.17
VoodooHDA 64비트 빌드 그리고, nVidia HDMI 제거.  (2) 2011.08.15
iOS용 게임 개발기 -5-  (0) 2011.08.10
iOS용 게임 개발기 -4.1-  (0) 2011.08.02
블로그 이미지

rekun,ekun 커뉴

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

오늘은 sprite에 대해서 이야기 해보자.
sprite는 우리가 게임을 만들때,(2d게임) 반드시 사용하게 되어 있는 이미지들을 말한다.

iOS용 앱에서는 주로 png 파일을 많이 사용하는데, cocos2d에서는 개발자가 따로 처리를 하지 않아도, 이미지들을 쉽게 콘트롤하고 가지고 놀수 있게 많은 api들을 제공하고 있다.  

4.1에서 만들었던, 정말 간단한(?) 시계에 이제는 이미지를 넣고, 약간의 효과를 줘보자.!!!
시계 이미지의 배경은 바로, 본인이 개발했던 BlueOcean게임의 배경들을 일정한 시간을 두고 FadeIn/Out 효과를 주고 바뀌도록 하는 것으로 한번 만들어 보겠다. 

이번에도 역시 두개의 파일만 수정하면 된다.  

배경이미지들을 이 예제에서는 3개룰 사용하여 정해진 시간이 되면, 배경이미지를 교체해주도록 하기위해서 아래 굵게 표시된 부분처럼, 인덱스하는 정수형 변수 하나(나중에 배열의 인덱서로 사용된다.), 배경이미지들을 관리할수 있도록 배열을 하나 선언한다.
 

//

//  HelloWorldLayer.h

//  

//



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

#import "cocos2d.h"


// HelloWorldLayer

@interface HelloWorldLayer : CCLayer

{

    CCLabelTTF *label;

    

    int             _currentBg;     // 배경화면 이미지가 무엇인지 확인하기 위한 인덱스.

    NSMutableArray* _bgSpriteList;  // 배경화면 이미지들을 저장할 배열.

}


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

+(CCScene *) scene;


@end


 
objective-C 언어는 C언어의 문법을 그대로 사용할수 있다. 위에서 보는 바와 같이 int 형 변수를 선언하는 것도, C와 똑같이 하면 된다. 
NSMutableArray 는 정적 배열이 아닌(처음부터 그 크기가 정해진 배열) 동적 배열이다, 자바의 ArrayList와 비슷하다고 생각하면 된다. 
아래 소스에서 확인할수 있겠지만, 생성후 필요할때 오브젝트들을 마음대로 추가해주고 꺼내 쓸수 있다. 그리고 그 오브젝트들을 지우는 것도 간단하게 할수 있다.



원래 시간을 찍어주던 부분에서, 배경 이미지들을 생성해서 배열에 넣어주고, 스케쥴러를 이용해서, 4초마다 이미지들을 빠꿔주게 하는 부분이 추가 되었다.아래 굵은 부분만 수정되고 추가된 부분이다. 해당 주석들을 참고하면 어떤것인지 바로 이해할수 있다.

//

//  HelloWorldLayer.m

//   

-(void)bgControl

{

   

    CCSprite *sprite = (CCSprite *)[_bgSpriteList objectAtIndex:_currentBg];  // 배열에서 이미지를 하나 꺼내온다.

    

    id action1 = [CCFadeIn actionWithDuration:2.0f];    // FadeIn Effect를 2초동안에 걸쳐 동작하게 함.

    id action2 = [CCFadeOut actionWithDuration:2.0f];  // FadeOut Effect를 2초동안에 걸쳐 동작허게 함.

    [sprite runAction:[CCSequence actions:action1, action2,nil]]; // FadeIn -> FadeOut순서로 효과가 동작되게 지정함.   

    _currentBg++; // 다음이미지를 불러올수 있게 인덱서를 증가 시켜줌.

    if(_currentBg==3) // 이미지는 3개 밖에 없으므로 다시 0으로 초기화 해준다.

        _currentBg=0;

}

-(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.position =  ccp( size.width /2 , size.height/4 );

// add the label as a child to this Layer

[self addChild: label z:2 tag:2];

        

                [self schedule:@selector(updateTime) interval:1];

        

        

                _bgSpriteList = [[NSMutableArray alloc] init];  // 배열 생성.

        
                // 루프를 돌면서, 이미지들을 생성하고, 배열에 넣는다. 

                for(int i=0;i<3;i++)

                {

                     CCSprite *sprite=
                            [
CCSprite spriteWithFile:[NSString stringWithFormat: @"scenario%02d.png",i]];

            

            

                     [_bgSpriteList addObject:sprite]; // 배열에 추가.


            

                     sprite.anchorPoint = CGPointZero;// 해당 이미지의 기준이 되는 점을 정해줌. 이후 포지션등을 지정할때 기준이 됨.                        

                     sprite.opacity=0; //FadeIn Effect를 사용할것이므로, 이미지가 보이지 않게 한다. 

                     [sprite setPosition: ccp(0, 0)];  // 위에서 anchorPoint를 0,0으로 정의하고, 여기서 이미지의 위치를 0,0으로

                                                              // 정의했으므로,  이미지는 화면의 0,0좌표에 이미지의 0,0좌표를 맞게 설정한다.

                     [self addChild:sprite z:1 tag:1]; // layer에 sprite를 추가해줌.(이부분이 없으면 아무것도 안된다.

                }

                _currentBg=0; 

                [self bgControl];


                [self schedule:@selector(bgControl) interval:4]; // 배경이미지를 효과를 주고 교체해줌.

}

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)

          [self unschedule:@selector(updateTime)];   // 스케쥴러 해제

        [self unschedule:@selector(bgControl)];     // 스케쥴러 해제

        [_bgSpriteList release];  // 배열 해제

        _bgSpriteList=nil;

    

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

[super dealloc];

}

 


백문이 불여일견이다. 어떻게 동작하는지 아래 동영상을 보자.

 

사실 구현을 위해서 정말 진짜!!! 진짜!! 기본적인 내용들로만 구현했지만, 위의 코드들 이용해서 이미지들을 수백개정도를 관리하도록(이때는 파일명만 리스토에 넣고 그때 그때 sprite를 생성하돌고 해야 메모리 부족이 생기지 않는다.) 하고, 단순하게 4초 마다가 아니라, 특정 시간이 변하거나,할때마다 이미지들을 교체하게 해주면, 정말 그럴사한 슬라이드 어플이 될수 있다.  생각보다 효과 넣는것도 쉽고, 코드만들기도 쉬우므로, 다른 이펙트들을 찾아서 한번 응용해보는것도 좋다.

다음 포스트에서 Effect들을 더 많이 알아보도록 하겠다.
 

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

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

rekun,ekun 커뉴

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

오늘 포스트는, 어제 잠시 보았던 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.1-  (0) 2011.08.02
iOS용 게임 개발기 -4-  (0) 2011.08.01
iOS용 게임 개발기 -3.1-  (0) 2011.07.11
iOS용 게임 개발기 -3-  (0) 2011.07.11
블로그 이미지

rekun,ekun 커뉴

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

티스토리 툴바