블로그 정리중 발견한 글 옮김(2008년 8월 26일 글)

두개의 32비트 Register에서 상하위 의 16비트 값씩을 조합해서 새로운 값을 만들어 낼때 유용하게 사용할수 있는 명령어가 바로 PKHBT,TB 명령어 이다.

이 명령어는 ARM v6 ARCH에 추가된 명령어로  v6 아키텍쳐를 지원하는 모든 ARM cpu에서 사용할수 있다.

아래의 예제를 보면, 실제 사용예를 이해할수 있다.

참고: H : 상위 16비트
        L  : 하위 16비트

r9 == C(H)A(L)  : r9 레지스터의 상위 16비트에 C가, 하위 16비트에 A가 저장되어 있다.
r1 == D(H)B(L)  : r1 레지스터의 상위 16비트에 D가, 하위 16비트에 B가 저장되어 있다.
 
PKHTB  r12,r1,r9, ASR #16 ; 
PKHBT  r9,r9,r1, LSL #16 ; r9 = B ,A

결과 >
r12 = D(H)C(L) , 즉, r1의 TOP(상위16비트)와 r9를 16비트 ASR한 BOTTOM(하위 16비트)를 packaging!
r9 == B(H)A(L) , 즉, r9의 BOTTOM(하위 16비트)과 r1를 16비트 LSL한 TOP(상위16비트)을 packaging!

이런 방법을 사용하지 않고 다르게 할수 있는 방법은 Register를 하나 더 사용해서, AND연산과 ORR연산을 사용하는 방법이 있다. 그러나, 위의 두방법처럼 하나의 명령어로 처리되지는 못하므로, LOOP사용시 훨씬더 많은 비용을 소모하게 된다.

이런 방법을 그래픽 렌더링 엔진쪽에서 ASM 코딩으로 최적화 해주면, 지금 나오는 Embedded 단말보다 훨씬 빠른 UI를 경험할수 있을것이다. 

블로그 이미지

커뉴

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

,

아주 오래전에 적어두었던 글을 블로그 정리중 발견하여 옮겨적습니다.(2008년 8월 27일 글)

 

그래픽 처리하는 루틴이나 라이브러리의 경우 C언어나 CPP로 아무리 컴팩트하게 프로그래밍을 했다고 해도, 컴파일러가 사람만큼 스마트 하지 못하기 때문에 비효율적이게 되는 부분이 발생하게 된다. 

컴파일러의 첫 목적은 사용자가 의도한 대로 안전하게 어셈블링 해주는 것이기 때문에 이런 비효율은 피할 수 없는 것이다.

만약 사용자가 어셈블리에 관한 지식과 해당 H/W에 대한 지식이 조금이라도 있다면, 어셈블리 레벨에서 최적화를 시도해 볼 수 있는데, 그 실제적인 예를들어 설명하겠다.

<C CODE>

typedef _DWORD DWORD
struct _DWORD
{
    unsigned short  a ;  
    unsigned short  b ;  
    unsigned short  c ;  
    unsigned short  d ;  
};

typedef _DWORD2 DWORD2
struct _DWORD2
{
    unsigned int   A;  
    unsigned int   C ;  
};

void Loop(DWORD2 *dst,DWORD *src,int loopsize)
{
    while(loopsize--)
    {
         int d = 256 - src->d;
         dst->A=(DWORD2*)src->A+((dst->A*d)>>8)&0x1F001F00;
         dst->C=(DWORD2*)src->C+((dst->C*d)>>8)&0x1F001F00;
         dst++;
         src++;
   }       
}

위의 코드를 C언어 레벨에서 분석하였을때, 구조체가 사용이 덜 최적화 되었다는 것을 알수 있다.
즉, (DWORD2*)src->C값은 src->d 값을 포함하고 있기 때문에, C코드상에서도 메모리 Access를 1회 제거하는데 큰 공헌을 할수는 있다. 

CPU상에서 연산되는 것보다, 메모리 IO에 의한 성능저하가 상당하기 때문에 위와 같이 메모리 IO를 1회 줄이는것만으로도 성능향상을 확인할 수 있다.

앞으로, 우리가 튜닝을 할때에는 C언어로 무결한 코드를 완전히 컴팩트하게 구성한다음에 어셈블리 언어로 최적화 하면 된다.

위 C코드의 컴파일 결과 : ASM 코드(armcc 사용,LE, arm1136j-S)

Loop
     SUBS    R3,R2,#1
     BXCC   R14
     PUSH   {R14}
     LDRH    R2,[R1,#6]
     LDR      R4,[R0,#0]
     LDR      R12,[R1,#0]
     RSB      R2,R2,#0X100
     SUBS    R3,R3,#1
     MUL     R4,R2,R4
     ADD      R12,R12,R4,LSR #8
     BIC       R12,R12,#0x1F000000
     BIC       R12,R12,#0x1F00
     STR      R12,[R0,#0]
     LDR      R4,[R0,#4]
     LDR      R12,[R1,#4]
     ADD      R1,R1,#8
     MUL     R2,R4,R2
     ADD      R2,R12,R2,LSR #8
     BIC       R2,R2,#0x1F000000
     BIC       R2,R2,#0x1F00
     STR      R2,[R0,#4]!
     ADD      R0,R0,#4
     BCS      {PC} -0x4C
     POP      {R14}
     BX         R14

위의 ASM 코드를 보면 상당히 많은 부분이 개선가능하다는 것을 발견할 수 있다. 

두 말 할 것 업이 바로 최적화 작업에 돌입한다.!!!

개선된 코드

Loop_opt
    SUBS     R3,R2,#1
    BXCC     R14
    PUSH     {R4-R9}   ; 레지스터를 더 많이 쓰기 위해, 스택에 저장
    MOV      R8,#0x1F00
    ORR       R8,R8,R8, LSL #16
    MOV      R9,#0xFF
    ORR       R9,R9,R9 LSL #8
INLOOP
    LDM       R1!,{R6,R7}  ; 한번에 두개씩 읽어오자!!
    LDM       R0, {R4,R5}  ; 역시 한번에 두개 씩  읽어올것!!
    AND       R2,R9,R7, ASR #16   ;위에서 말했던, 메모리 Access 1회 줄이는 방법.!!!!
    RSB       R2,R2,#0x100 
    MUL      R4,R2,R4 ; STALL제거를 위해 위로 올라옴
    MUL      R5,R2,R5 ; STALL제거를 위해 위로 올라옴
    SUBS     R3,R3,#1
    ADD       R6,R6,R4, LSR #8 ;이놈은 줄이고 싶지만... 더 연구해봐야 됨.
    BIC        R6,R6,R8  ; 이런거 말고 방법이 있을거야~~
    ADD       R7,R7,R5, LSR #8 ;이놈도...
    BIC        R7,R7,R8 ; 이런거 말고 방법이 있을거야~~
    STM      R0!, {R6,R7} ; 두개 저장.
    BCS      INLOOP
    POP      {R4-R9}
    BX         R14

적용 테스트 결과 :루틴 자체의 성능이 약 3배 개선되었다. (시스템 점유율 12 % --> 4%로 개선)
최적화 방법 :
1. 메모리 접근 횟수를 줄임
2. LOOP내 인스트럭션의 수를 줄임
3. STALL 발생 횟수를 없앰.
4. BIT 연산을 한번에 가능하도록 함.

그러나, "나는 더 개선하고 싶다." 하는 사람은 아직 한가지 더 방법이 있다.
바로 Cache의 최대한 활용하는 방법을 연구하는 것과 SIMD(Single Instruction Multiple Data)를 사용하는 것이다.  ARM의 경우 Cache Line 사이즈가 32byte이므로 한 라인에 딱 맞는 Loop Code를 작성하면 캐시 Hit Ratio가 증가할것이고 이에 따라 성능향상도 기대할 수 있다.
그러기 위해서는 Thumb code는 16개, ARM code는 8개의 instruction으로 코드를 작성해야 한다. 

그리고 SIMD를 적용한다면, 아래 코드를 개선할수 있다.

MUL      R4,R2,R4 ; 
MUL      R5,R2,R5 ; 
ADD       R6,R6,R4, LSR #8 ;
BIC        R6,R6,R8  ;
ADD       R7,R7,R5, LSR #8 ;
BIC        R7,R7,R8 ;

구조체 구조가 32bit SIMD에서는 못써먹을 구조라서, 64bit SIMD가 되면 바로 적용해 볼 수 있을것 같다.

한줄요약 : RISC에서는 생각 보다 최적화는 어렵지 않다.

블로그 이미지

커뉴

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

,
이번에는 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용 게임 개발기 -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
블로그 이미지

커뉴

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

,
어제에 이어 오늘 포스트는 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용 게임 개발기 -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
블로그 이미지

커뉴

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

,
이번 포스트는 원래 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
VoodooHDA 64비트 빌드 그리고, nVidia HDMI 제거.  (2) 2011.08.15
iOS용 게임 개발기 -5-  (0) 2011.08.10
iOS용 게임 개발기 -4.1-  (0) 2011.08.02
블로그 이미지

커뉴

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

,