역시 글을 쓴다는 것은 어려운 것 같다. 이번에도 시간이 자료를 준비하는데 꽤 많은 시간이 소요됬다. 그래도 재미있는 기능들이 많이 있으니까. 기대하시라. 그런데 강좌를 쓰다보니까. 상당히 길어서 2,3으로 끊어서 여기에 연재하기로 결정했다. 그래서 이번에는 유래없이 연이어 두개의 강좌글이 올라갈 것이다. ㅋㅋ


이번에는 그리 어렵지않게 이해할 수 있을지 모르겠지만 다음 장은 좀 어려우니까. 잘 보고 이해하길 바란다. 그럼 강좌를 시작하겠다. 


Cocos2d로 애니메이션 구현하기 2


2. Composable Actions


Composable Actions는 전 시간에 배웠던 Transformation Actions를 여러개를 순차적으로 또는 동시에 같이 애니메이션을 실행시키는 것을 말한다. 예를 들자면 빙빙 돌면서 특정 위치로 이동을 한다던가.. 점점 커지면서 사라진다던가 또는 커지고나서 다른 위치로 이동한다음 다시 원래의 상태로 돌아가는 순차적인 애니메이션 등을 구현할 수 있다. 
실행시키는 방법은 Transformation Action을 만든 방식과 동일하다. 단 만들 때 여러 Action들을 조합하므로 Array를 생성하는 방식으로 만들어야 한다. 다음과 같이 말이다.

    id action = [Sequence actions:
                 [MoveBy actionWithDuration: 2 position:ccp(240,0)],
                 [RotateBy actionWithDuration: 2 angle: 540],
                 nil];
                
이제 Composable Actions의 종류별로 하나씩 알아보도록 하자.


2.1 Sequence

이는 순차적으로 등록된 Action들을 실행시키게 하는 것이다. Action인 A, B, C를 차레로 등록했다면 A Action이 끝난 뒤에 B Action이 실행되고, B Action이 끝난 뒤에 C Action이 실행되는 식이다. 그리고 눈치가 빠르신 분은 알겠지만 A, B등 입력되는 Action이 역시 Composable Actions이어도 된다. 그래서 다음과 같은 것도 가능하다. (다음은 설명을 위해서 로직을 간단히 한거다.)

    id seq = [A, B, C, nil] : A -> B -> C 실행

    id subSeq = [B, D, E, nil];
    id seq = [A, subSeq, C, nil]; // 이는 A를 실행한 후에 subSeq에 등록된 B -> D -> E를 실행하고 나서 다시 E를 실행시킨다.

이제 실제로 코딩된 예제를 보자. 다음은 현재 위치에서 가로로 240만큼 이동한 후에 제자리에서 540를 돌는 예제이다.

    id action = [Sequence actions:
                 [MoveBy actionWithDuration: 2 position:ccp(240,0)],
                 [RotateBy actionWithDuration: 2 angle: 540],
                 nil];

    [someSprite runAction:action];

그리고, 주의 해야할 것이 NSArray를 사용해 봤으면 알겠지만 Composable Actions는 내부에서 NSArray로 관리되기 때문에 배열의 끝을 nil로 꼭 알려줘야 한다. 그렇지 않으면 실행 시에 에러난다.

2.2 Spawn


Spawn 은 등록된 모든 Action들을 동시에 실행시키는 Action이다. 즉, 점점 커지는 액션과 이동 액션을 등록했을 경우, 점점 커지면서 해당 위치로 이동을 한다. 그런데 여기서 주의해야할 것은 시작 시간이 같은 것이지 애니메이션이 끝나는 시간은 각각의 Action에서 지정한 시간에 따라 천차 만별이 될 수 있다. 개발을 할 때 동시에 애니의 끝까지 완료되게 하고 싶다면 각각의 Action들의 애니메이션 시간을 동일하게 해줘야 한다. 만약, 끝나는 시간이 다른 Spawn Action을 Sequence Action의 element로 등록을 했다면 가장 애니메이션이 긴 액션을 완료한 후에 다음에 등록된 Action이 실행된다.

다음은 Spawn을 사용한 예제이다. Sequence와 동일한 방식으로 사용할 수 있다.

    id action = [Spawn actions:
                 [JumpBy actionWithDuration:2 position:ccp(300,0) height:50 jumps:4],
                 [RotateBy actionWithDuration: 2 angle: 720],
                 nil];

    [someSprite runAction:action];

2.3 Reverse


처 음엔 이 Action은 왜 있을까라는 생각도 했지만, 아주 유용하게 쓸모있는 Action이다. Action을 반대로 실행하게 한다. 그러니까. 만약, A에서 B로 이동하는 Action을 다음과 같이 reverse를 호출하면 B에서 A로 이동하게 된다. 

    id action = [MoveTo actionWithDuration:1 position:ccp(250, 250)];
    id reverseAction = [action reverse];

만약, Sequence와 다음에 배우게 될 Repeat이나 RepeatForever를 사용한다면 스타크래프트의 순찰지정과 같이 무한반복도 가능한다.

다음은 Sequece를 활용해서 가로로 250 이동하고 나서 세로로 50 이동한다음 다시 처음위치로 원위치되는 애니메이션을 구현한 예제이다. 간단하게  [seq reverse]로 원래 위치로 이동시킬 수 있다.

    id move1 = [MoveBy actionWithDuration:1 position:ccp(250,0)];
    id move2 = [MoveBy actionWithDuration:1 position:ccp(0,50)];
    id seq = [Sequence actions: move1, move2, [move1 reverse], nil];
    id action = [Sequence actions: seq, [seq reverse], nil];

    [someSprite runAction:action];

2.4 DelayTime


DelayTime은 지정된 시간동안 대기시키는 Action이다. Sequence로 각 Action들을 등록할 때 일정시간 동안 지연효과를 줄 때 아주 유용하게 사용할 수 있다. 다음과 같이 초단위 시간으로 지연시킬 수 있다.

    [DelayTime actionWithDuration:초단위 시간]; 

다음은 DelayTime을 사용해서 가로로 150이동했다가 2초동안 지연후 다시 가로로 150이동하는 애니메이션을 구현한 예제이다.

    id move = [MoveBy actionWithDuration:1 position:ccp(150,0)];
    id action = [Sequence actions: move, [DelayTime actionWithDuration:2], move, nil];

    [someSprite runAction:action];

2.5 Repeat, RepeatForever


Repeat과 RepeatForever는 단어에서도 볼 수 있듯이 Repeat은 지정한 횟수만큼 반복하는 것이다. RepeatForever는 영원히 등록된 Action들을 반복시키는 Action이다.
Repeat는 횟수를 지정하기 위해서 다음과 같이 times 파라미터가 추가되지만 RepaetForever는 반복할 Ation들을 등록하는 파라미터만 입력하면 된다.

    [Repeat actionWithAction:times:]
    [RepeatForever actionWithAction:]

다음은 Reverse시에 사용한 것을 Repeat을 사용해서 3번 반복 시키는 예제이다.

    id move1 = [MoveBy actionWithDuration:1 position:ccp(250,0)];
    id move2 = [MoveBy actionWithDuration:1 position:ccp(0,50)];
    id seq = [Sequence actions: move1, move2, [move1 reverse], nil];
    id action = [Repeat actionWithAction:[Sequence actions: seq, [seq reverse], nil]
                                   times:3];

이를 무한 반복 시키려면 다음 같이 사용하면 된다.

    id action = [RepeatForever actionWithAction:[Sequence actions: seq, [seq reverse], nil]];



여기까지 간단하게 Cocos2d의 Composable Actions에 대해서 알아봤다. 예제를 SpriteTest2.zip  보면서 실행해보면 쉽게 이해할 수 있을 것이다.