'분류 전체보기'에 해당되는 글 105건

  1. 2013.06.26 (너목들 완전정복 13탄) 이제는 제작진도 스포한다.(제작진의 7회 스포?)
  2. 2011.10.12 구글 다트 VS 아마존 실크
  3. 2011.10.10 배열과 포인터
  4. 2011.10.10 이중 포인터의 실체
  5. 2011.10.10 메모리 할당
  6. 2011.10.10 void 포인터
  7. 2011.10.10 포인터 연산(C언어)
  8. 2011.10.10 변수 VS 포인터변수
  9. 2011.10.09 [Box2D 2.2.0 한글화] Chapter 2 Hello Box2D (Box2D v2.2.0 User Manual)
  10. 2011.10.04 [예제분석] TileMap 관련 정보들
  11. 2011.10.03 [예제분석] SceneTest.java (cocos2d 안드로이드강좌)
  12. 2011.09.29 [Box2D 2.2.0 한글화] Chapter.1 Introduction (Box2D v2.2.0 User Manual)
  13. 2011.09.29 [JBox2D] 1.기초자료 (cocos2d 안드로이드강좌)
  14. 2011.09.26 [예제분석] EaseActionsTest.java (cocos2d 안드로이드강좌)
  15. 2011.09.26 [예제분석] DrawPrimitivesTest.java (cocos2d 안드로이드강좌)
  16. 2011.09.26 [예제분석] CocosNodeTest.java (cocos2d 안드로이드강좌)
  17. 2011.09.17 SchedulerTest.java (cocos2d 안드로이드 예제 분석강좌)
  18. 2011.09.15 CCSprite 정의와 생성방법 (cocos2d for android)
  19. 2011.09.15 CCEaseAction 의 라스트 정리 (또 다른 시선) (cocos2d for android)
  20. 2011.09.15 CCEaseSineIn / CCEaseSineInOut / CCEaseSineOut 클래스 분석 (cocos2d for android)
  21. 2011.09.15 CCEaseRateAction 와 상속 클래스 분석 (cocos2d for android)
  22. 2011.09.15 CCEaseExponentialIn / CCEaseExponentialInOut / CCEaseExponentialOut 클래스 분석 (cocos2d for android)
  23. 2011.09.15 CCEaseElastic 와 상속 클래스 분석 (cocos2d for android)
  24. 2011.09.15 CCEaseBounce 와 상속 클래스 분석 (cocos2d for android)
  25. 2011.09.15 CCEaseBackIn / CCEaseBackInOut / CCEaseBackOut 클래스 분석 (cocos2d for android)
  26. 2011.09.14 CCEaseAction (cocos2d for android)
  27. 2011.09.14 CCCameraAction 와 CCOrbitCamera (cocos2d for android)
  28. 2011.09.14 CCIntervelAction의 상속 클래스들 분석.
  29. 2011.09.14 CCIntervelAction과 CCInstantAction (cocos2d for android)
  30. 2011.09.14 CCAction 와 CCFiniteTimeAction (cocos2d for android)

최초작성일 2013년 6월 26일                                                     최종수정일 2013년 6월 26일




이제는 제작진도 스포일링한다.?


일전에 제작진의 예고동영상이 스포일리의 일종이라고 한적이 있는데 결국 7회도 제작진이 스포일 하는군요. YouTube영상과 미리보기에 적혀있는 글을 읽어보면


1.미리보기 전문

 혜성의 어머니는 혜성이 물에 빠져 죽는 꿈을 꾼다.

늘 맞아떨어졌던 어머니의 꿈.. 혜성은 자꾸 꿈이 신경이 쓰이는데..
마치 꿈이 예견한 듯 혜성은 의뢰인에게 테러를 당하는데..


2.YouTube영상


영상만 보면 마치 혜성이가 민준국한데 테러는 당하는것보 보이게 편집을 했지만 실은 그냥의뢰인에게 테러를 당한것일뿐.... 별걱정없이 그냥 보면 됩니다.




Posted by 수다쟁이증후군 :
구글에서 웹 프로그래밍 엔진을 발표 했다. 이름 하여 다트?

현재 pc 환경엣 웹페이지의 로딩 속도에 불편함을 느낀적이 있는가라고 물으면  어떠한가?
머 별로?  4~5년전에 나온 PC 라면 모를까 웹페이지 로딩에 대해서 불편함을 느낀적은
없다.

그런 데 구글이 다트를 발표했다. javascript 보다 속도가 획기적으로 빠르다라는것이다.
불편함을 느끼지 않는데 왜 속도에 중점을 맞춘 웹프로그래밍 언어를 개발 한거지?

답은 모바일이이다. 현재 스마트폰에서 웹페이지 볼려면 진짜 속터진다. 마치 2000년도 쯤에
pc로 웹페이지를 보던 경험을 다시 느끼고 있다. 그래서 요즘에 속도를 한층 높인. LTE 4세대통신이 뜨고있지 않은가?  아직 전국적으로 망이 깔리려면 시간이 좀더 걸리겟지만. 말이다.

그런데 구글은 이 답답함을 하드웨어적 접근이 아닌 소프트웨적으로 접근한다.
아예 속도저하의 하나인 js를 대체 하겟다는 것이다.  역시 구글 답다라는 생각이 든다. 
 
얼마전에 아마존에서 실크라는 웹브라우저를 발표했다. 이는 웹페이지를 클라우스서버에서 한번 가공하여 사용자에게 전달해주는 방식인데 이또한  모바일 웹환경에 대한 속도의 문제를 위한 해결책이 었다. (개인정보가 클라우드에 저장된다는 문제가 남아 있지만. ) 

실크는 이미 킨틀의 내장 브라우저이고 다트는 본격적인 행보를 시작한다라고 외쳤다.


아마도 곧 구글의 다트는 안드로이드 운영체제의 웹브라우져에 버추얼머신(VM)이 탑제 될것이다.
이는 저의 지극히 개인적인 생각입니다. 그렇지만 가장 간단하면서도 확실히 저변을 확대할수
 방법을 두고 구글이 돌아 갈 필요가 있을까요? 이렇게 VM이 기본탑제가 된다면 기존의 포털은
사용자에게 보다 쾌적하게 서비스를 제공해줄 방법으로 다트를 외면하긴 어려울겁니다.

" 아!!!. 네XX 스마트폰에서 느려서 못해먹겟다 아 젠장. "이말보다는
" 역시 네XX 로딩속도 좋아 ㅎㅎㅎ" 이말이 더좋을겁니다. 

현재는 어떠한 싸이트던지 속도가 거기서 거기니까 별 차이점이 없겟지만. 
한 군데라도 차이가 나기 시작한다면 후발업체는 당연히 따라가겟죠 결국 다트는 안정정인 기반을
다지게 됩니다.

과연 방향은 어디로 흘러갈까요? ㅎ
Posted by 수다쟁이증후군 :


포인터 배열은 문자형배열 즉 스트링형에 주로 쓰인다. 
문자열 배열을 Ragged 배열이라고 한다.

 포인터 배열
결국 문자열을 다루기 위해서 작성된것이다. 
이를 이용하면 메모리를 동적으로 할당 할 수 있고
또한 메모리의 쓸모없는 부분을 줄여준다.

이것이 포인터 배열이다
그럼 배열 포인터는 무엇인가?
2차원이상의 배열을 부분 배열로 접근할수 있게 해주는 포인터이다.
 
배열포인터의 활용 :  
다차원 배열의 첨자 접근 할 때 에러를 줄여준다.

배열명 그 자체는 포인터 상수이기 때문에 한번 정해지면 
다른 번지를 카리킬수없다 





































 

'c/c++ 내용정리' 카테고리의 다른 글

이중 포인터의 실체  (0) 2011.10.10
메모리 할당  (0) 2011.10.10
void 포인터  (0) 2011.10.10
변수 VS 포인터변수  (0) 2011.10.10
Posted by 수다쟁이증후군 :
C언어 자료형 중에 
문자열 관련 자료형은 없다.
다만 char  배열만 있을뿐이다.

뒤집어 생각하면 char배열은 문자열 자료형이다 라고 선언하고
이를 접근하는 변수가 char * 이다.
그러니 문자열을 콜바이레퍼런스로 사용하면 char* 의 포인터 가
필요하다.

이것이 2중 포인터가 생겨난 이유다.  

'c/c++ 내용정리' 카테고리의 다른 글

배열과 포인터  (0) 2011.10.10
메모리 할당  (0) 2011.10.10
void 포인터  (0) 2011.10.10
변수 VS 포인터변수  (0) 2011.10.10
Posted by 수다쟁이증후군 :


1. 배열로 할당

2. malloc 그냥 할당
    calloc 초기화 할당
    realloc 메모리양을 늘린다.
    free 로 해제

3. 할당된 메모리에 접근하기위해 포인터를 이용한다. 
 

'c/c++ 내용정리' 카테고리의 다른 글

배열과 포인터  (0) 2011.10.10
이중 포인터의 실체  (0) 2011.10.10
void 포인터  (0) 2011.10.10
변수 VS 포인터변수  (0) 2011.10.10
Posted by 수다쟁이증후군 :


기본
1. void 포인터 는 어떠한 포인터도 받을수 있다 반대는 캐스팅해야 한다.

2. 포인트 캐스팅 (int *)는 이런식 으로 할 것.

3. 캐스팅 하지않으면 포인트 연산 할 수 없다.
 

활용방법
==> void 포인터의 특징을 생각해보면 알 수 있다.
==> 몇개식 잘라야 하는지 알수 없으므로 메모리 
      바이트 단위로 접근할 때 이용하면 좋을듯 하다.
 

'c/c++ 내용정리' 카테고리의 다른 글

배열과 포인터  (0) 2011.10.10
이중 포인터의 실체  (0) 2011.10.10
메모리 할당  (0) 2011.10.10
변수 VS 포인터변수  (0) 2011.10.10
Posted by 수다쟁이증후군 :




1. 포인터끼리는 더할수 없다
    ==>의미 없기때문

2, 포인터 뺄셈은 가능        
    ==>거기를 나타내기 때문

3.포인터에 정수를 더하거나 뺄수 있다.
    ==>포인터 타입에 따른다.

4.포인터에 소숫점 연산은 안된다.

5.포인터에 곱셉이나 나눗셈은 할 수 없다. 

6.비교는 가능 
    ==> 위치비교를 위해서 
Posted by 수다쟁이증후군 :


포인터변수는  변수의 주소값을 저장 하는 변수이다.
(포인터도 일종의 변수이다.)

변수명에서 뽑아 낼 수 있는 정보는 
저장데이터와 저장위치 이렇게 2가지인데


변수 VS 포인터변수

저장데이터는 변수명을 이용해서 뽑아내고 
저장위치는 & 연산자를 이용해서 뽑아낸다.

저장데이터는 변수에 저장하고 
저장위치는   포인터변수에 저장한다. 

변수의          선언은 자료형 변수명
포인터 변수의 선언은 자료형 *변수명





추가 사항 포인터변수에 포인터연산자 * 를 이용하면 
저장 데이터를 얻어 낼수 있다





 

'c/c++ 내용정리' 카테고리의 다른 글

배열과 포인터  (0) 2011.10.10
이중 포인터의 실체  (0) 2011.10.10
메모리 할당  (0) 2011.10.10
void 포인터  (0) 2011.10.10
Posted by 수다쟁이증후군 :



( 들어 가면서 )

1. 한글화 목적 : jbox2d 를 위한 기초작업
                     작성자 : 나
                     번역 태클 : 언제든지 해주세요 !!!!!

2. 출처 http://box2d.org/manual.pdf



Box2D의 배포버전에는 Hello World project이 포함 되어 있습니다. 
프로그램은  커다란 ground박스와 하나의 작은 박스를 생성합니다. 
이코드 에는 그래픽적 요소가 없습니다. 
당신이 볼수 있는것은 모든 시간에 대해서 box의 위치를 콘솔로 텍스트로 볼 수 있을 겁니다.

이것은 box2d의 실행과 어떻게 시작해야 할지에 대한 좋은 예를 제공 할수 있습니다.

 
2.1 Creating a world 
모든 box2d 프로그램은  b2World object를 생성하는 것으로 시작한다. 
b2World는 물리공간과 프로그래머의 연결점입니다. b2World는 메모리, 객체, 시뮬레이션
을 관리합니다. 물리공간을 stack과 heap 과 section에 위치 시킬수 잇습니다.

Box2D world 생성하는 것은 매우 쉽습니다. 
첫번째로  중력 벡터를 정의 해야 합니다. (중력의 방향과 중력의 값)
또한 바디들 비활성상태 상태 인지 아닌지를 결정하는 것을 world가 알게 해주어야 한다. 
비활성 상태를 sleep이라고 하는데  sleep 상태이 바디들은 시뮬레이션요청을 받지 않는다.

b2Vec2 gravity(0.0f, -10.0f);
bool doSleep = true;

월드 오브젝트를 생성한다. 아래에 나오는 것은 stack에 world를 생성하는 것이다,
이때 월드는 범위(무슨 범위?) 안에 있어야 한다.
 b2World world(gravity, doSleep);

정리 코드

b2Vec2 gravity(0.0f, -10.0f);
bool doSleep = true;
b2World world(gravity, doSleep); 



이제 물리월드(물리 공간)이 생성되었고 이제 다른요소들을 추가 해보자.

 
2.2 creating a ground Box (바닥 상자 만들기)
바디를 생성하기 위한 단계는 아래와 같다. 

step1. 바디의 위치와 제동(damping)을 정의한다. 
step2. world object를 이용해서 body를 생성하라.
step3. shape와 friction 과 densitiy 와 함께 fixtures 을 정의하라. 
step4. body위에 fixtures을 생성하라




첫번째 단계을 위해서 그라운드 바디를 생성한다. 
이때 생성되는 바디의 정의가 필요하다. 이 정의를 가지고 
그라운드 바다의 초기위치를 정한다.

b2BodyDef groundBodyDef;

groundBodyDef.position.Set(0.0f, -10.0f);



두번째 단계에서는 바디의 정의가 바다의 생성을 위해서 월드 오브젝트로 전달된다. 
월드 오브젝트는 바디정의 에 대한 레퍼런스를 유지하지 않는다 . 바디들은 초기화에 대해
고정적이다. 이 고정적인 바디 (static bodies)들은 다른 static body와 충돌하지 않고
움직이지 안는다. 

b2Body* groundBody = world.CreateBody(&groundBodyDef);



세번재 단계로 그라운드 폴리곤을 생성한다. SetAsBox를 이용해서 그라운드 폴리곤을
box shape 으로 만들어라, 이 박스는 부모의 바디원형에 센터에 자리 잡는다.

b2PolygonShape groundBox;

groundBox.SetAsBox(50.0f, 10.0f);


SetAsBox 함수는 인자값으로 높이와 길이의 1/2값을 받는다  (센터에 맞추니까)
그래서 이 경우에 그라운드 바디는 x축 100단위이고  y축 20 단위이다. 
Box2D의 단위는 KMS 단위로 조정된다.  그래서 위에 넣은 값은 미터단위로  생각해볼수 있다
Box2D 는 오브켁트가 실세계의 사이즈를 기초로 했을때 잘 동작한다.
예를 들어 베럴(오크통)은 높이가 1미터 정도이다. 부동소숫점 연산의 제한때문에 
glaciers(빙하?)나 먼지 입자의 움직임 모델링은 좋은  생각이 아니다. 



마지막 4번째로 shape fixture을 만들어야 한다. 이번 단계에서 간단한 방법이 있다. 
기본 fixture의 요소의 속성을 변화 시킬필요 없다. 픽스쳐의 정의없이 그냥 shape를 바로 body에 전달한다. 이후에 커스터마이징을 위한 fixture을 알아 보겟다. 두번째 파라미터는 shape의 입방미터당 킬로그램 즉 밀도이다.  static body는 디폴트로 0 이다. 그래서 이번 경우에는 사용하지 않는다 

groundBody->CreateFixture(&groundBox, 0.0f);



Box2d 는 shape의 레퍼런스를 유지하지않는다 그 데이터는(레퍼런스) b2Shape 오브젝트에 복사된다. 


주의: 모든 fixture는 부모 body를 가져야한다. (단연한 말이다) 심지어 static(전역?) 이라도 말이다. 그러나  모든 static fixture를 하나의 static body에 붙일수는 있다. 



2.3 Creating a Dynamic Body

지금까지 그라운드 바디를 생성한는 방법을 알았다. 이 방법(테크닉)을 이용해서 다이나믹 바디를 
만들어 보겟다. 그라운드 바디와 다이나믹 바디의 차이점이 있는데 가장 큰 차이점은
다이나믹 바디의 mass 속성을 지정해주어야 한다. 

첫번째로 CreateBody 를 이용해서 body 를 만든다. 디폴트 바디는 static 이기 때문에 
b2BodyType를  다이나믹 바디 오브젝트를 만들때 준비해야 한다. 

b2BodyDef bodyDef;

bodyDef.type = b2_dynamicBody;

bodyDef.position.Set(0.0f, 4.0f);

b2Body* body = world.CreateBody(&bodyDef);

주의 :   body type 을 b2_dynamicBody 으로 설정해한다. 사용자의 입력에 따른 반을을 할려면 말이다. 



다음으로 fixture 정의 를 이용해서 폴리곤 shape를 생성하고 할당한다. 
첫번재로 boxshape를 생성하고 

b2PolygonShape dynamicBox;

dynamicBox.SetAsBox(1.0f, 1.0f);


다은으로 box를 이용해서 fixture정의를 생성한다. 밀도 density는 1로 정해준다.
디폴트 밀도는 0 이다 shape의 마찰(friction)은 0.3으로 하자. 

b2FixtureDef fixtureDef;

fixtureDef.shape = &dynamicBox;

fixtureDef.density = 1.0f;

fixtureDef.friction = 0.3f;



픽스쳐의 정의를 이용하면  fixture를 생성할수 있다. 이것은 body의 mass를 자동으로 업데이트 해준다.  이것으로 많은 fixture를 원하는 body에 추가 할수 있다. 
각각의 요소는 전체 mass를 구성하는 역활은 한다. 



2.4 simulating the world (of Box2D)
지금까지 그라운드 박스를 만들고 다이나믹 박스도 만들어 보았다.
이제 거의 모든 준비는 다되었습니다. 
이제 몇가지만 고려하면 됩니다. 

Box2D 적분기(integrator)라는 컴퓨팅 알고리즘을 이용합니다. 
인터그래이터(알고리즘)는 물리공식을 이산시간에 대해서 시뮬레이션합니다. 
이산시간이란 ( 시간을 연속적으로 보지않고 일정한 간격으로 잘라 사용하는것을
의미합니다.) 전통적인 게임루프(플립북에서 대상이 움직이는 하나의 scene)와 같이 
진행이 된다. 그래서 Box2d를 위한 시간이 필요하다.  일반적으로 게임에서 물리엔진은 
60프레임정도이다. 이 프레임 보다 더 크게 시간을 분할할 필요는 없다. 그러나 생성한
world 오브젝트에 대한 정의를 주의깊게 준비해야 한다. 
다양한 time step은 다양한 결과를 야기 시킨다. 이것은 디버깅 하기도 어렵다 .
그러므로 진행하는 프레임에 time step을 엮지 말라. (진정으로 정말 원한다 하더라도
말이다. )
별다른 고생할 필요없이 여기 간단하게 time step을 설정할수 있다. 

float32 timeStep = 1.0f / 60.0f;


게다가 적분기에 , Box2d는 constraint solver 라고 불리는 코드의 더 많은 비트를
이용할수 있다. constraint solver은 시뮬레이션 제약에 대해서 해결책을 제공해준다. 
하나의 제한은 완전하게 해결할수 있다. 그러나 하나의 제한을 해결할때 또다른 
제한을 약간 방해 한다. 좋은  해결책은 모든 제한에 대해서 여러번 반복할 필요있습니다.

constraint solver 에 2개의 단계가 있다. : 속도 단계 위치 단계
속도 단계에서 solver 바디를 정확하게 움직이기 위해서는 필수적으로 impulses를 연산
할 필요가 있다. 위치 단계에서는 solver는 overlap 과 조인트 분리를 오차를 줄이기 위해서 
바디의 포지션을 조정한다. 각각의 단계는 자기자신의 iteration count 를 가지고 있다 
만약 에러가 작다면 위치 단계는 반복을 일찍 벗어난다.

box2d에서 추천하는 iteration은 속도 8이고 위치3 이다. 이 숫자는 임의로 조정할수 있다.
명심할것은 속도와 정확도는 trade-off 이다. 적은 숫자의 iteration은 속도를 증가 시키지만.
정호가도는 개판이다. 반대로  많은 iteration은 속도를 줄이지만 시뮬레이션의 정확도는 좋다
간단한 예제에서 많은 iteration은 필요없다. 
여기에 우리가 선택한 iteration counts가 있다. 

int32 velocityIterations = 6;

int32 positionIterations = 2;


time step 과 iteration counts은 아무 상관이 없다. iteration은 sub-step 이 아니다. 
하나의 solver iteration 은 time step내의 모든 constraints(제약조건)을 한번씩은 통과해야 한다
(확인해야 한다.)최소한 한번이다. 이말은 여러번 반복할수 있다라는 말이다. 

우리는 시뮬레이션 루프시작을 준비한다. 당신의 게임에서 시뮬레이션루프는 게임루프에 
통합된다.당신의 게임루프전체의 각각의 단계에서 당신은 b2World::step를 호출할수 있다.
일반적으로 당신의 프레임과 물리 time step 에 따라  다릅니다.

Hello World 프로그램은 심플하게 디자인(구성)되어 있다. 그래서 
그래픽적 아웃풋은 없다. 코드는 다이나믹바디의 위치와 회전값을 출력한다. 
여기에 시뮬레이션 루프가 있다. 이는 시뮬레이션 타임의 1초에서 60번의 time step을 
시뮬레이션한다.

for (int32 i = 0; i < 60; ++i)

{

    world.Step(timeStep, velocityIterations, positionIterations);

    b2Vec2 position = body->GetPosition();

    float32 angle = body->GetAngle();

    printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);

}


출력되는 데이터는 박스의 떨어짐과 그라운드 박스에 안착하는 것을 보여준다.
아마도 당신이 볼수 있는 데이터는 

0.00 4.00 0.00

0.00 3.99 0.00

0.00 3.98 0.00

...

0.00 1.25 0.00

0.00 1.13 0.00

0.00 1.01 0.00


이럴것이다.


2.5 Cleanup
world 가 범위를 벗어나거나 pointer에 삭제가 호출될때 bodies,fixtures,joints에 남겨놓은
모든 메모리는 해제된다. 이것은 퍼포먼스를 향상시키고 당신의 삶을 좀더 쉽게 해주기위해서
이다.

그러나 당신이 가지고 있는 bodies,fixtures,joints의 포인터를 해제할 필요가 있을것이다.
그것들은 필요가 없어 질것이기 때문이다. 


2.6 The Testbed 
HelloWorld 예제를 정복하기 위해서는 Box2d의 testbed를 보아야 할것이다. 
testbed는 프레임워크와 메모환경을 unit 단위로 테스트 할수 있다. 
여기에 몇가지 특징이 있다. 

• Camera with pan and zoom.

• Mouse picking of shapes attached to dynamic bodies.

• Extensible set of tests.

• GUI for selecting tests, parameter tuning, and debug drawing options.

• Pause and single step simulation.

• Text rendering.



testbed 는 box2d 사용에 대한 많은 예제를 가지고 있다. 많이 고치고 찾아보아라.

testbed는 freeglut와 GLUI를 사용해서 작성되었다. testbed는 box2d 라이브러리의 일부분이
아니다. box2d 라이브러리는 렌더링에 대해서 문외한이다.? 예제에 보여지는 것은 box2d를
사용하여 렌더링할수 없다 ?

 



























Posted by 수다쟁이증후군 :


타일 기반 게임의 장점
* 메모리를 절약할 수 있다. 
* 게임 세계의 효과적인 공간 분할에 따른 이점이 있다. 타일에 속성을 부여함으로써 충돌검사나 랜더링을 쉽게 할 수 있다. 캐릭터와 배경과의 상호작용을 처리하기가 쉽다.  
* 그래픽 디자이너가 아닌 누구라도, 디자이너가 만들어둔 타일셋으로 맵 디자인을 할 수 있다.

타일 기반 게임의 단점 
* 그래픽이 다소 지루하고 경직되어 보인다. 반복되는 타일 이미지가 많이 나타나며 유연성이 부족하다. 
* 타일 이미지 제작, 관리가 힘들고 불편하다.  
* 통짜맵에 비해 랜더링 알고리즘이 복잡하고 느리다.

<출처 : http://meat.tistory.com/9 >
 




TileMap 관련 내용
http://mamedev.org/devwiki/index.php/Tilemaps#The_problem




TileMap cocos2d-iphone 레퍼런스
http://www.cocos2d-iphone.org/wiki/doku.php/ko:prog_guide:tiled_maps






타일맵 관련 정말깔끔한 최종 정리
출처: 
http://cafe.daum.net/iLogic/915W/39?docid=1KHkj915W3920110612155237 

타일 맵

Cocos 2D 에서는 타일 맵을 생성하는 방법이 2 가지다.

  • TMX 타일 맵 형식 사용 (새로 나와서 다루기 쉬움, 추천)
  • PGU 타일 맵 형식 사용 (예전 것, 비추)                                                   

TMX 타일 맵 형식

Cocos 2D 는 타일로 생성된 맵을 제공한다.

Tiled 의 2 가지 버전:

  • Mac OS X, 윈도우, 리눅스에서 실행되는 자바 어플은 안정화된 버전이다.
  • 자바 버전의 모든 특징을 제공하는 QT 어플. 이 강좌를 작성하는 시점의 최근 버전은 0.4.0 이며 육각형 맵만 제외하고 모든 기능을 제공한다.

다음 링크된 페이지에서는 Tiled 를 사용하여 맵을 만드는 방법을 설명한다.

Cocos 2D 는 다음과 같은 TMX 맵을 제공한다.

  • 위치:
    • 지각 맵
    • 등각 맵
    • 육각 맵
  • 타일:
    • 연결된 타일은 제공되지 않는다. (즉, 연결된 이미지를 갖는 tileset).
    • embedded tileset 만 제공된다. (즉, tileset 은 연결되었지만 이미지는 아닌 것).
    • 레이어 별로 최대 1 개의 tileset 만 제공된다.
  • 레이어:
    • 레이어는 원하는 만큼 만들 수 있다.
    • 각 레이어는 내부적으로 CCSpriteSheet 의 자식 클래스인 CCTMXLayer 으로 표현된다.
    • 각 타일은 CCTMXLayer 의 자식 클래스인 CCSprite 으로 표현된다.
  • 객체 그룹:
    • 타일의 객체 그룹이 제공된다.

외부 이미지에서 연결된 tileset 생성하는 방법

Cocos 2D 는 tileset 에 연결된 이미지를 제공하지 않는다. 그러나, tileset 자체는 맵 파밀에서 연결된 그림이 되어야 한다. 대신, 자체적으로 sprite sheet 이미지(AKA: Texture Atlas)를 생성해야 한다.


Tiled 정보 설정

연결된 이미지를 갖는 tileset 으로 저장되지 않도록 tiled 에 설정한다.

$ cd bin/tiled-0.7.2/
$ java -jar tiled

tiled 에서 해야할 작업:

  • Edit → Preferences → Saving
  • Layer 옵션:
    • Use binary encoding: ON (“텍스트” 엔코딩은 Cocos 2D 에서 제공되지 않는다)
    • Compress layer data: ON (압축되지 않은 데이터도 또한 제공된다)
  • Tileset 옵션:
    • Embed images (PNG): OFF (연결 이미지는 제공되지 않는다)

새로운 맵을 생성할 때 맵의 크기는 맵의 픽셀 단위의 크기가 아닌 가로 세로의 tile 의 개수를 넣어야 한다. iPhone 에서 제공할 수 있는 맵의 크기는 제한된다. 작동할 때 44 픽셀 x 44 픽셀은 100 x 100 으로 보여진다. 400 x 200 의 타일은 모두 검정색으로 그려진다.


tileset 연결된 것 확인하기

맵용 tileset 은 맵 파일 내에 포함되어야 한다. tiled 에서는 Tileset → Tileset Manager 로 접근할 수 있는 "Tileset Manager"로 조절된다. tileset 목록에서 tileset 이름의 오른쪽 행에 Embedded 를 볼 수 있다. 대신에 경로가 보인다면, 목록에서 열을 선택하고 embedded tileset 으로 변환하는 오른쪽의 Embed 아이콘을 선택해야 한다.

다른 도구를 사용하거나 확인해보려면 텍스트나 XML 편집기에서 *.tmx 파일을 열고 <tileset> 노드를 확인해볼 수 있다. 파일 명을 갖는 source 속성을 포함하면 Cocos 2D iPhone 에서 동작하지 않는 외부 tileset 을 보고 있는 것이다.


sprite sheet 생성

유용한 이미지를 묶어주는 도구들이 있다.

  • zwoptex 비주얼 텍스처 아트라스 생성기 (flash)
  • mkatlas.pl 도스 실행형 텍스처 아트라스 생성기 (perl)
  • Packer 비주얼 텍스처 아트라스 생성기 (java)
  • TexturePacker 강력한 명령행 도구, XCode-통합용

이 도구들은 개별 이미지로부터 sprite sheets 를 생성하도록 도와준다.

sprite sheet 의 제한:

  • 최대 크기: iPhone 3GS 에서는 2048×2048 이고 이전 iPhone 에서는 1024×1024
  • 타일은 모두 같은 크기여야 한다.

옵션:

  • 여백: 픽셀 단위의 공백
  • 간격: 타일 간의 공백

여백과 간격은 2 를 사용하는 것이 추천된다.


spritesheet artifact fixer

맵을 이동할 때 타일의 경계 사이의 선이 깜빡이는 경험이 있다면, 이 도구는 고쳐야 한다. 이들 선은 시뮬레이터에서는 나타나지 않고 장치에서 실행할 때만 나타난다.

spritesheet-artifact-fixer 는 spritesheet 를 고치는 Cocos 2D 에 있는 작은 도구이다.

실제로 해야할 일은 타일의 경계선을 여백 안으로 복사하는 것이다. 이론적으로는 여백은 렌더링되지 않아야 하지만, 때때로 렌더링된다. 특히, 안티-앨리어싱 텍스처나 3D 투영을 사용한 것이라면 더 그렇다.

도구를 사용하는 방법:

$ cd cocos2d/tools
$ python spritesheet-artifact-fixer.py -f spritesheet.png -x 32 -y 32 -m 2 -s 2

다른 도구는 –extrude 옵션으로 TexturePacker 을 사용하는 것이다.

$ TexturePacker *.png --extrude 1 --plist test.plist --sheet test.png

좌표와 GID

좌표

64×32 맵에서 tiled 에서 사용되는 좌표 시스템은 다음과 같다.

  • (0,0): 왼쪽 상단 모서리
  • (63,31): 오른쪽 하단 모서리


GID

타이틀의 GID 는 타이틀의 전역적으로 구별하는 식별 기호이다. 이 값은 unsigned int 형이며 1 부터 타일의 개수까지 차례대로 번호가 부여된다.

5 개의 다른 타일이 있다면

  • Tile 0 은 GID 1
  • Tile 1 은 GID 2
  • Tile 2 은 GID 3
  • 등등.

GID 0 은 빈 타일을 표현하는 데 사용된다.


TMX 노드 생성

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"hexa-test.tmx"];
[self addChild:map];

디폴트로 모든 타일은 앨리아싱된다. 안티-앨리어싱 타일을 원하면 다음과 같이 작업해야 한다.

// TMX 맵 생성
CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];
[self addChild:map];
 
// 모든 레이어를 반복하면서 'antialias' 로 설정한다
for( CCTMXLayer* child in [map children] ) {
    [[child texture] setAntiAliasTexParameters];
}

완전한 소스:

타일 얻기/추가/삭제/수정

특정 좌표에서 타일(CCSprite) 얻기

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
CCSprite *tile = [layer tileAt:ccp(0,63)];
tile.anchorPoint = ccp(0.5f, 0.5f);

특정 좌표에서 타일의 GID 얻기

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
unsigned int gid = [layer tileGIDAt:ccp(0,63)];

특정 좌표에 새로운 타일의 GID 설정하기

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
[layer setTileGID:gid2 at:ccp(3,y)];

특정 좌표에 타일 제거하기

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
[layer removeTileAt:ccp(15,15)];

레이어 반복

CCTMXTiledMap *map = [CCTMXTiledMap tiledMapWithTMXFile:@"orthogonal-test2.tmx"];		
CCTMXLayer *layer = [map layerNamed:@"Layer 0"];
 
CGSize s = [layer layerSize];
for( int x=0; x

z 오더와 깊이 버퍼

이 정보는 v0.99.1 이후 버전부터 유효하며, Isometric 과 orthogonal 맵 에서는 가능하며 hexagonal 맵에서는 불가능하다.

만들고자 하는 게임이 sprite 의 Y 위치를 따라서 어떤 타일의 앞쪽이나 뒤로 sprite 를 위치시켜야할 때, 2 가지 옵션을 사용할 수 있다.

  • OpenGL ES 깊이 버퍼 사용
  • 멀티 TMX 레이어와 z-오더 사용

깊이 버퍼 사용

이 옵션은 OpenGL ES 깊이 버퍼를 사용한다. 그래서, 우선 적으로 해야할 작업은 z-버퍼와 2D 프로젝션을 생성하는 것이다.

// 직접적으로 윈도우 뷰에 붙기 전에 AppDelegate 에서 작성한다.
// kDepthBuffer24 로 24 비트 버퍼를 사용할 수도 있다.
[[CCDirector sharedDirector] setDepthBufferFormat:kDepthBuffer16];
 
 
// 이 코드는 아무 곳이나 원하는 위치에 넣을 수 있다. 실행 중에 프로젝션 방법을 바꿀 수 있다.
[[CCDirector sharedDirector] setProjection:CCDirectorProjection2D];

2 TMX 레이어로 맵을 생성하는 것이 중요하다.

  • 배경 레이어. 예: grass
  • 전경 레이어. 예: trees

grass 레이어는 뒤쪽의 스프라이트가 되어, vertexZ 값이 가능한 가장 작은 값이 될 것이다. 예: -1000. trees 레이어는 타일들마다 다른 vertexZ 값들을 갖는다. 아래 쪽에 있는 타일은 위에 있는 타일보다 더 큰 vertexZ 값을 갖는다.

그래서, 해당 작업은 다음과 같다:

  1. Tiled 열기
  2. 배경 레이어 선택 (예: grass)
  3. Tiled → Layer → Layer Properties
  4. 추가: cc_vertex = -1000
  5. 전경 레이어 선택 (예: trees)
  6. Tiled → Layer → Layer Properties
  7. 추가: cc_vertexz = automatic

가장 중요한 작업은 스프라이트를 GL_ALPHA_TEST가 가능한 상태로 드로잉하는 것이다. 예제:

// MySprite 는 CCSprite 를 상속받은 클래스이다.
// CCSpriteSheet 를 사용하여 스프라이트를 드로잉한다면, CCSprite 가 아니라 CCSpriteSheet 를 상속받아야 한다.
// 전역적으로 GL_ALPHA_TEST 를 설정할 수 있다. 설정하면, CCTMXLayer#draw 함수를 주석처리해야 한다.
// 다른 방법은 아래 예제와 같다.
@implementation MySprite
-(void) draw
{
   glEnable(GL_ALPHA_TEST);
   glAlphaFunc( GL_GREATER, 0 );
   [super draw];
   glDisable(GL_ALPHA_TEST);
}
@end


 

Q: cc_vertexz 의 작업 방식은 ?

A: cc_vertexz 는 자동으로 word 형식이나 정수를 받게 된다.

  • 값이 음수나 양수인 정수라면, 숫자는 레이어의 모든 타일의 vertexZ 로 사용될 것이다.
  • 값이 자동이라면, 타일의 첫 번째 열은 vertexZ 는 -1 이 되고, 두 번째 열은 vertexZ 가 -2 등을 자동으로 할당된다.

남은 작업은 Y 위치에 따라서 스프라이트의 vertexZ 값을 변경하는 것이다. 예제:

-(void) repositionSprite:(ccTime)dt
{
  // 타일 높이는 101x81
  CGPoint p = [sprite position];
  [sprite setVertexZ: -( (p.y+81) /81) ];
}

샘플의 작동은 TileMapTest.m 를 참고해라.


Q: cc_alpha_func 는 언제 사용해야 하나?

Acc_alpha_func 는 cc_vertexz=automatic 일 때 사용된다. 디폴트 값은 0 이다. 이 값은 GL_GREATER 함수를 사용하여 타일을 그릴 때 사용된다. 다음은 CCTMXLayer 로 타일을 그리는 방법이다. 

// CCTMXLayer 드로잉 함수
-(void) draw
{
  if (useAutomaticVertexZ_) {
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, alphaFuncValue_);
  }
 
  [super draw];
 
  if (useAutomaticVertexZ_) glDisable(GL_ALPHA_TEST);
}

 

예제:

등거리 vertex Z 예제. "trees" 와 "grass" 로 2 개의 레이어를 갖는다. "trees" 레이어에 대해서 cc_vertex = automatic 를 사용한다. "grass" 레이어에는 cc_vertexz = -1000 를 사용한다.
직각 vertex 예제. “trees” 와 “grass” 로 2 개의 레이어를 갖는다. "trees" 레이어에 대해서 cc_vertexz = automatic 와 cc_alpha_func = 0.5 를 사용한다. "grass" 레이어는 cc_vertexz = -1000 을 사용한다.


다중 TMX 레이어와 z-오더 사용법

이 정보는 아직 가능하지 않다. 그러나 예제는 TileMapTest.m 에서 볼 수 있다.


스크린 샷

3D 프로젝션과 안티 앨리어싱 타일을 갖는 직각 맵.  타일들은 spritesheet-fixer 도구를 사용하여 고정된다. 3D 프로젝션과 안티 앨리어싱 타일로 표현되는 구조는 나타나지 않았다.
직각 맵. 맵의 타일 크기는 타일들 보다 더 적다.
2D 프로젝션과 앨리어싱 타일을 갖는 등거리 맵.
2D 프로젝션과 앨리어싱 타일을 갖는 육각맵. 가장자리는 좌우에 위치하며, 상하 가장자리는 아직 제공되지 않는다.


PGU 타일 맵 형식

PGU 타일 맵 형식도 사용할 수 있다.

이 형식은 크기 제한을 가지므로 유연하지 않고, 편집기 자체에도 약간의 버그를 갖기 때문에, 이 형식은 잘 다뤄지지 않는다. 예전 게임에 이 형식을 사용했다면 계속적으로 사용할 수 있지만, 추천되지 않는 형식이다. 대신 TMX 타일 맵이 추천된다.

이 형식에 대한 정보는 다음과 같다.


 

Posted by 수다쟁이증후군 :


0.SceneTest에 나오는 내용들

1.scene 전환 방법
2.scene 전환 액션  


 
1. 예제 분석 목적
==> scene 전환방법의 기본을 알고 scene action의 원리를 알아본다.



2.전체적 개요

전체 3개의 scene을 구성하면 각 scene당 Layer1 ,Layer2, Layer3 이 할당된다.
Layer1_Scene에서 Layer2_Scene로 전환될때는 push를 사용하고 이때 화면전환은
단순장면 전환 및 scene_action전환을 이용한다. 
Layer2_Scene에서 Layer1_Scene로 전환은 push의 반대 개념은 pop를 이용한다.


Layer2_Scene에서 Layer3_Scene로 전환 될때는 replace를 사용하고 이때 화면전환은
단순장면 전환 및 scene_action전환을 이용한다.
Layer3_Scene에서 pop를 이용하면 Layer1_Scene로 이동한다. 

 

3-1. Layer1 클래스  분석

public Layer1() {

            CCMenuItemFont item1 = CCMenuItemFont.item("Test pushScene", this,                                                                                                          "onPushScene");

            CCMenuItemFont item2 = CCMenuItemFont.item("Test pushScene w/transition",                                                                                    this, "onPushSceneTran");

            CCMenuItemFont item3 = CCMenuItemFont.item("Quit", this, "onQuit");


            CCMenu menu = CCMenu.menu(item1, item2, item3);

            menu.alignItemsVertically();


            addChild(menu);

        }

        public void onPushScene(Object sender) {

            CCScene scene = CCScene.node();

            scene.addChild(new Layer2(), 0);

            CCDirector.sharedDirector().pushScene(scene);

        }

        public void onPushSceneTran(Object sender) {

            CCScene scene = CCScene.node();

            scene.addChild(new Layer2(), 0);

            CCDirector.sharedDirector().pushScene(
                                                 CCSlideInTTransition.transition(1, scene));

        }

        public void onQuit(Object sender) {

            CCDirector.sharedDirector().popScene();

        }


==>MenuItem으로 3가지 메뉴를 만들고 클릭 되었을때 실행될 콜백을 각각 지정한다.
     push에서 봤다 시피 Scene을 담는 통의 구조는 스택으로 구성되어 있다.

     CCDirector.sharedDirector().runWithScene(scene);
     코드를 사용하여 디렉터에서 기본적으로 화면에 보여줄 scene을 전달한후에는
     
     CCDirector.sharedDirector().pushScene(scene);
     CCDirector.sharedDirector().popScene();
     CCDirector.sharedDirector().replaceScene(scene);
     이용해서 장면전화을 한다. 
     
     replaceScene 는 별거 없는것이 . pop 한 후에 push 한것  뿐이다.  보다 쓰기 쉽게만들어
     놓은 api 뿐이니 별 고민 할 필요 없다. 몰라도 된다 걍 남들이 쓰면 이런게 있다 정도로만 
     알아 두자 .
     Scene 라고 별거 없다 그냥 layer 라고 생각하면 된다. 다만 디렉터에서 관리하는
     Layer일 뿐이다.

     디렉터에서 관리하는 Layer는 Scene이다.  

==>Scene_Action 장면전환 효과가 있는 Scene 라고 하나의 패키지로 나와있는데 
     이것은 어이없는게도 CCNode+Action 일뿐이다. 
     이전 까지는 CCNode와 CCAction을 따로 선언하여 하나로 합쳐서 액션을
     사용했지만. 장면전환효과가 있는 Scene라고 거창한 이름을 붙여놓은것은
    CCScene에 기본 액션을 디폴트로 집어 놓았을뿐이다. 별거없다. 내부 함수들을
    살펴보면 알겟지만 더이상 없다. 이런 기본적인 것들을 알아 보았으니
    우리도 이와 비슷한것을 수십가지를 만들어 낼수 있다. 
    action에 action을 추가해서 CCSecne를 상속한 클래스에 박아 넣기만 하면
    되니까 말이다.  



나머지 Layer2와 Layer3도 별다른 차이점이 없다 여기서 설명한 내용이 전부 일뿐이다.
그런데 어떻게 글을쓰다 보니까 반말이 되었네요^^;;
글 수정하기도 ~~ 좀 그러니 ㅎㅎㅎ 이번만 양해 해주세요 

추가로 이상하다거나 헷갈리는 부분이 있으면  댓글로 ^^


Posted by 수다쟁이증후군 :
(들어가면서 :

1. 한글화 목적 : jbox2d 를 위한 기초작업
                     작성자 : 나
                     번역 태클 : 원추!!!!!!  강추!!!!!!

2. 출처 http://box2d.org/manual.pdf


제 1장 개요

1.1 box2d란 
box2d 란 게임을 위한 강체 시뮬레이션 라이브러리 이다. 
프로그래머는 게임을 이용하는 사람들이 어떠한 물체를 이동시킬수 있게 하고 좀 더 반응성이
좋은 게임을 만들기 위해 이 엔진을 사용한다.
게임 엔진의 관점에서 물리엔진은 단지 에니메이션을 처리하는 시스템일 뿐이다. 

Box2d 는 포터블C++로 작성 되었다 . 이 엔진에서 대부분의 타입은 b2라는 접두어가 붙어 있다 
이건 게임엔진을 사용하면서 네이밍하는데 있어서 중복을 피할수 있게 도움을 줄것이다. 

1.2 Box2D 를 사용하기에 앞서 
이 메뉴뉴얼은 당신이 기본 물리개념(mass, force, torque impulses...)을 좀더 친숙하게 해줄
수 있지만. 이게 전부 가 아니다. 구글링이나 위키를 이용하기 바란다. 

Box2d는 게임 개발자 컨퍼런스에서 물리강좌의 한부분으로 만들어졌다.  box2로 만든 이강좌는 
홈페이지에서 다운받을수 있다. 

Box2D가 C++로 작성되었기때문에 c++ 프로그래밍 경험은 당연히 있어야 한다. 
Box2D가 C++ 입문으로써는 적합하지 않다. 최소한 컴파일과 링크와 디버깅은 능숙하게 
다루어야 한다. 

1.3 이 메뉴얼에 관해서 
이 메뉴얼은  배부분의 Box2d API를 다루고 있다 글그러나 그게 전부는 아니다.
좀더 공부하고자 한다면 Box2D를 포함하는 Testbed를 충분히 보기 바란다 . 또한.
Box2D 코드는 Doxygen 으로 되어있다 그래서 api문서를 만들기는 좋을 것이다.

이문서는 새로운 버전에 맞추어져 있을며 최신 버전이다.

1.4 피드백과 버그리포팅
Box2D관련 질문이 있다면  포럼에 글을 남기세요. 매우 많은 사람들이 사용하니까
토론장소로 최고다.
Box2D관련 이슈는 구글코드프로젝트를 이용된다.  이건 이슈를 추적하기 좋고 포럼속에
묻히는걸 방지해준다 . ㅋ
여기에 있다 : http://code.google.com/p/box2d/

 
1.5 중요컨셉

Box2D 는 몇가지 몇 가지 중요 objects 가 있다. 여기에서는 간단히 정리하고 
자세한 내용은 관련 챕터에서 알아 본다. 

shape
.원이나 폴리곤 같은 2차원 기하객체이다. 

rigid body

물체(body)를 구성하는 두 입자의 거리가 절대로 바뀌지 않을 때 그러한 물체를 강체라고 한다.

다이아몬드처럼 단단한 물체이다.

물리현상에서 실제로 존재하지 않지만 단순화된 물리 법칙을 구현하기 위해 가정하는 형태이다.

일반적으로 생각할 때 단단한 고체 정도로 생각하면 될 것 같다.
(해석이 잘안되서 차용함 : 출처 : http://cafe.naver.com/uiaa.cafe)

fixture
fixture(고정장치) 는 body에 shape를 연결한다. 밀도 마찰 반발력과 같은 물체속성을 추가한다. 

constraint
constraint는 물체의 자유도를 없는 물리적연결이다. 
2차원에서 body는 자유도 3을 가진다.(2개의 이동축과 1개위 회전축)만약 body를
벽에 고정한다면 이것 벽에 body를 constraint한것이다.  그 고정점을 기분으로  body는
회전할수 있다. 그래서 constraint는 자유도 2를 제거한다.

constact constraint 
special constraint 는 강체의 침투(강체가 부딧쳤을때 움푹파이는 정도)를 막기 위해 만들어졌다 
또한 마찰 과 반발력을 시뮬레이션 할수 있게한다. 직접 만들수 없고. Box2D가 자동으로
생성한다.


joint
2가지 이상의 body를 하나로 만들어주는 constraint 이다. Box2d는  revolute, prismatic, distance... 과 같은 joint 타입을 제공한다. 몇가지 joint는 제약을 가진다. 


joint limit
joint limit 는 조인트의 움직이는 범위를 제한한다. 에를 들러 사람의 팔꿈치는 일정한 번위만큼만 
회전한다. 


joint motor
조인트 모터는 조인트의 허용되는 각도에 따라 연결된 바디의 움직임을 유발한다.
예를 들면 모터를 팔굼치를 회전 시키기 위해 사용할수 있다.

world
프로그래밍상의 물리공간이다.Box2D는  복수의 물리공간을 만들수 있으나 
별로 추천하지는 않는다 . 

solver
물리공간은 solver를 가진다. 이놈은 좀더 나은 타이머를 사용할수 있게 해주며
접촉과 joint제약을 해결해준다. Box2d에서 이놈은 성능이 좋다 

continuous collision
solver는 물체는 점진적으로 이동시킨다. 별도의 상호작용없이 turnneling
을 이끌어준다. 
Box2D는 turnneling을 위해 특별한 알고리즘을 사용한다. 
첫번째로 충돌 알고리즘 은 첫번째 impace를 찾기위해 2개의 바디의 움직임을 보간한다.
(아  힘드네 이거 생각보다 )

일단 요까이 ~~ ㄷㄷㄷ
2011/09/29

1.6 모듈
Box2d 는 3가지 모듈(Common, Collision,Dynamics)로 구성된다. 
Common 모듈은 allocation,math,settings과 관련된 코드를 가진다. 
Collision 모듈은 shapes,broad-phase, collision function/queries 를 정의한다. 
마지막으로 
Dynamics 모듈은 simulation world,bodies,fixture,joints 를 제공한다. 




1.7 단위(Units)
Box2d는 부동소수전연산을 하고 허용오차는 Box2d가 좀 더 동작을 잘하도록 도와준다. 
이러한 허용오차는 미터, 킬로그램,초 단위와도 잘 작동하도록 조정되었다.
특별히 Box2d는 0.1미터와 10미터 사이에서 잘동작되도록 조정 되어있습니다.
즉 이말은  0.1과 10 사이에서  soup cans와 buese 사이의 물체는 작동이 잘됩니다.(이말이
먼말인지 모르겟네) 정적 물체는 50미터 까지는 큰 문제 없을 겁니다.

2D 물리 엔진 이기 때문에 사용자가 이용하는 화면의 픽셀단위로 변경 하고 싶어 질겁니다.
불행히도 이것은 시뮬레이션 결과가 부정확해질겁니다.  200픽셀 길이의 물체가 Box2D 에서는 
45층 건물정도의 크기 입니다. (단위를 조심할것.)
**주의 **
**Box2d는 MKS 단위입니다.물체는 대략적으로 0.1에서 10미터 를 움직이는 것으로 유지해라.
**화면에 무언가를 렌더링 할 때 아마도 단위변환 시스템이 필요할것입니다.  Box2d testbed는
**opengl viewport 변형을 이용한다. 픽셀 단위를 사용하지 마세요. 

이미지를 붙이는 하나의 판처럼  box2d 바디를 생각하는 가장 좋습니다. 미터단위로 그 판을 움직
일수 있습니다. 그 반면에 간단한 요소를 이용하여 픽셀 좌표로도 변형 할수 있다. 
이는 스프라이트 같은 요소를 움직이기 위해 픽셀좌표를 이용할수 있습니다. 

box2d는 각도를 위해 라디안을 이용합니다. 바디의 회전은 라디안으로 값을 저장하고 증가 또는 
축소 할 수 있습니다. 각도의 크기가 너무 크다면 바디의 회전을 정규화 해야 합니다. 


1.8 Factories 와 Definetions
메모리 관리는 box2d api 에 있어서 중요한 역활은 합니다.  그래서 
b2body 나 b2joint 의 객체를 만든다면 b2world 의 팩토리 함수를 호출할 필요가 있습니다. 
다른방법으로 이런것들을(바디 조인트....)을 할당할 필요없습니다.

생성함수는 와 같습니다. 
b2Body* b2World::CreateBody(const b2BodyDef* def)
b2Joint* b2World::CreateJoint(const b2JointDef* def)
 
그리고 이와 반대의 메모리 해제는 아래와 같습니다.
void b2World::DestroyBody(b2Body* body)
void b2World::DestroyJoint(b2Joint* joint)

바디와 조인트를 만들때 definution을 필요로 한다.  그 definitions에는 바디와 조인트를 만드는데
필요한 정보들이 포함되어 있어야 한다.
이러한 접근법은
객체생성에서 에러를 줄일수 있고,
파라미터의 수를 줄일수 있고,
알맞은 정의를 제공할수 있고,
접근자의 수도 줄일수 있다.

fixtures 는 바디를 부모로 해야 하기때문에 b2Body의 팩토리 메소드를 이용해서 생성하도 해제 한다. 
b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def)
void b2Body::DestroyFixture(b2Fixture* fixture)

shape와 density로 부터 바로 fixture를 생성하는 방법이 있습니다. 
b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float32 density)

팩토리는 정의에 대한 참조를 유지하지 않는다. 그렇기 때문에 stack에 대한 정의를 만들어야 한고 임시 resources에 유지 해야 한다. 



1.9 유저 데이터 
b2Fixture 와 b2Body 그리고 b2Joint 클래스들은 void 포인트로서 user data에 접근해야 한다.
이것은
Box2D 자료 구조를 검토(?)할 때
게임엔진에서 엔티티에  어떻게 관계 지어야 할지를 결정할때 
유용합니다

예를 들면 강체에 actor 포인터를 붙이것이 일반적이다 . 이것은 연산 레퍼런스를 준비해야 한다.
만약 actor를 가지고 있다면 body획득할수 있다. 반대로 바디를 가지고 있다면 actor를 얻을수 있다. 
GameActor* actor = GameCreateActor();
b2BodyDef bodyDef;
bodyDef.userData = actor;
actor->body = box2Dworld->CreateBody(&bodyDef);

유저 데이터가 필요한 case가  몇가지 있다.
*충돌 결과를 이용하는 actor에 데미지(?)를 적용 할 때.
*플레이어가 축-정렬(axis-aligned) 박스안에 있다면 scripted event를 동작 시킬때
*조인트가 파괴 될것을 Box2d가 우리에게 알려줄때 겜임 구조에 접근.

유저 데이터는 하나의 옵션이고 어디에든지 위치 시킬수 있다라는 것을  명심해야 한다. 
그럼에도 불구하고 개발자는 항상 일관되어야 합니다(?) 예를 들어 
actor 포인트를 바디에 저장한다면  actor 포인트를 전체바디에 유지 해야한다.
하나의 바디에 actor 포인터나 첫번째 포인터를 다른 bosy에 저장하지 말것. 
첫번째 포인터를 actor 포인터로 캐스팅하는 것은 충돌을 일을킬수 있다. 

유저 데이터는 기본적으로 NULL 이다. 




Box2d를 이해하고 메뉴얼을 해석하는 것이 아니기 때문에 
번역상의 이상한점이아 오류들이 많을수 있습니다. 지적 해주시면 감사 하겟습니다.



 




































 
Posted by 수다쟁이증후군 :
1.JBox2d 란
==> Box2d를 자바환경에 변형한것이다. 

2.관련 문서들

box2d 매뉴얼
http://www.box2d.org/manual.pdf

한글화 작업 및 관련 강좌는 아래의 싸이트에 정리 잘되어있습니다. 
http://cafe.naver.com/uiaa.cafe

jbox2d 공식사이트
http://www.jbox2d.org

구글 코드 싸이트
http://code.google.com/p/jbox2d/

 
Posted by 수다쟁이증후군 :
0. EaseActionsTest 에 들어가며
==> 기본클래스 심화에 EaseAction에서 상세히 다루어서 그 관련 글들만 잘 보신다면.
    분석 하는데 별무리 없을듯 보입니다. 그래서 EaseAction클래스 심화내용중
    중요부분만 발췌하여 이번 분석예제를 대체하고 자 합니다. 
 
1.EaseAction의 기본 적인 내용


1. 클래스 설명

Base class for Easing actions


==> 액션을 쉽게 하게위한 기본 클래스 입니다. 
==> 말그대로 쉬운 액션 입니다. 액션을 보다 쉽고 재밌게 쓰기 위한 기본클래스입니다. 

==> 이렇게 클래스 소스에서 뽑아 낼수 있는 자료는 별로 없네요 그래서 홈페이지 있는
    자료를 참고 해봅니다.     

Ease 액션은 내부의 액션의 기간을 수정하는 특별한 composition액션입니다. 

Flash에서는 이러한 액션을 Tweening 또는 Easing 액션이라고 합니다.


이 액션을 내부 액션의 속도를 수정하지만 전체 동작 시간을 수정하지는 않습니다. 

내부 액션이 5초 동안 수행된다면 전체 시간은 5초 동안 진행될겁니다.


Ease 액션은 동작 시간을 선형적으로 수정합니다.
 

예를 들면 내부 액션을 가속화하거나 저속화합니다.

이 액션을 3가지 타입으로 구분할 수 있습니다. :


In actions: 액션의 처음부분을 가속화

Out actions: 액션의 끝 부분을 가속화

InOut actions: 처음/끝과 끝에서 가속화

easing 또는 tweening 액션은 다음 페이지를 참조하세요. :


http://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html

http://www.robertpenner.com/easing/easing_demo.html 

위에 2페이지를 찾아 보시면 정말 깔끔하게 잘 정리 되어있습니다.  

 



2. 추가된 멤버 변수 

public static final float M_PI_X_2 = (float) (Math.PI * 2.0f);
protected CCIntervalAction other;


==>첫번째 멤버변수 M_PI_X_2  가 있는 것을 보니 액션을 사용할때 수학적인 요소를 사용하려
    나 봅니다.
==>
두번째 멤버변수  other  CCIntervalAction을 멤버변수로 하나더 가지고 있습니다. 이걸 왜 
    가지고 있을까요? 위에서 설명한바와 같이 액션의 기간을 수정하기위함입니다. 
    이는 기본액션의 인스턴스를 생성자의 파라미터로 가지기 때문입니다.
    그럼 기본액션들은 어떨까요?. 다른 기본액션들은 속성에 대한 데이터를 액션 생성자의  
    파라미터로 넘깁니다. 여기에 중요한 포인트입니다. 
    한마디로 EaseAction은  다른 기본액션을 담는 통이라는것입니다. 이와 유사한것을로
    시퀀스, 리핏, 무한리핏 또한 이런류의 액션을 담는 통입니다.  

    
3. 클래스 상속 관계도


(출처 :http://www.cocos2d-iphone.org/api-ref/0.99.0/interface_c_c_ease_action.html)
 
==>중간 중간 헷갈리수도 있으니 일단 참고하세요 

4. CCEaseAction을 상속하는 클래스들 (업데이트되는 분석글을 보려면 초록색글자 클릭)

CCEaseBackIn.java (2011/9/15 추가)

CCEaseBackInOut.java (2011/9/15 추가)

CCEaseBackOut.java (2011/9/15 추가)
 

CCEaseBounce.java (2011/9/15 추가)
* CCEaseBounceIn / CCEaseBounceInOut / CCEaseBounceOut  포함


CCEaseElastic.java (2011/9/15 추가)
CCEaseElasticIn /  CCEaseElasticInOut / CCEaseElasticOut 포함


CCEaseExponentialIn.java (2011/9/15 추가)

CCEaseExponentialInOut.java (2011/9/15)

CCEaseExponentialOut.java (2011/9/15)


CCEaseRateAction.java (2011/9/15)
CCEaseIn / CCEaseInOut / CCEaseOut  포함


CCEaseSineIn.java (2011/9/15)

CCEaseSineInOut.java (2011/9/15)

CCEaseSineOut.java (2011/9/15)


==> 위를 6개묶음으로 분류한것은 내부액션의 기간 수정 방법에 대한것입니다. 
     (결과값을 만들어내는 수식의 종류에 따라)


5. 쓰이는 곳 

==> 실제적으로 코드에서 사용할일은 없을듯합니다. CCEaseAction 클래스를 기반으로 
      확장된 클래스(4번참고)를 사용하세요 
==> cocos2d는 아직 확장중인 엔진으므로 혹시 사용자가 나만의 EaseAction을 구현할때나 
     쓰일 것 입니다.

6. 최종정리
 
  어떻게 하다보니 org.cocos2d.actions.ease 관련 클래스를 모두 정리하였습니다. 
막상정리하고 보니 별것도 없고 그냥 그렇네요 그런데 어떤 EaseAction을 쓸것인가
에 대한 고민을 안할수가 없네요 . 어떻게 해야 할까요? 하나하나 정리 테스트 해보면
좋겟지만. 먼가 감도 안오고 흠... 그래서 준비 했습니다. 

휘어지는 정도가 한눈에 보이네요 ㅎㅎㅎ 그럼 
잘 골라서 쓰세요 ㅎㅎ
 
 
Posted by 수다쟁이증후군 :
0.DrawPrimitivesTest 에 나오는 내용들

1.  Node를 이용하여 그리는것이 아닌 opengl의 기본 api를 1차 작업하여 
   좀더 쉽게 기본 선,원, 사각형 및 부드러운 곡선을 그리는 방법을 알수 있습니다. 



1. 예제 분석 목적. 
   기존의 화면 구성 방식에서 기본도형을 화면에 그리기 위한 api를 확인

2. 확인 속성. 

Primitives.drawLine    == > 선그리기
Primitives.drawPoint   == > 원그리기
Primitives.drawPoints == > 점을 여러개 
Primitives.drawCircle  == > 원그리기
Primitives.drawPoly    == > 점연결하여 선그리기
Primitives.drawQuadBezier 4점 Bezier 

Primitives.drawCubicBezier 3점 Bezier 





3. 기본도형 그리기 소스

public void draw(GL10 gl) {

   CCSize s = Director.sharedDirector().winSize();



   // draw a simple line

   // The default state is:

   // Line Width: 1

   // color: 255,255,255,255 (white, non-transparent)

   // Anti-Aliased

   gl.glEnable(GL10.GL_LINE_SMOOTH);

   

   Primitives.drawLine(gl, CCPoint.ccp(0, 0), CCPoint.ccp(s.width, s.height));


   // line: color, width, aliased

   // glLineWidth > 1 and GL_LINE_SMOOTH are not compatible

   // GL_SMOOTH_LINE_WIDTH_RANGE = (1,1) on iPhone

   gl.glDisable(GL10.GL_LINE_SMOOTH);

   gl.glLineWidth(5.0f);

   gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);

   Primitives.drawLine(gl, CCPoint.ccp(0, s.height), CCPoint.ccp(s.width, 0));


   // TIP:

   // If you are going to use always the same color or width, you don't

   // need to call it before every draw

   //

   // Remember: OpenGL is a state-machine.


   // draw big point in the center

   gl.glPointSize(64);

   gl.glColor4f(0.0f, 0.0f, 1.0f, 0.5f);

   Primitives.drawPoint(gl, s.width / 2, s.height / 2);


   // draw 4 small points

   CCPoint points[] = {CCPoint.ccp(60, 60), CCPoint.ccp(70, 70), CCPoint.ccp(60, 70), CCPoint.ccp(70, 60)};

   gl.glPointSize(4);

   gl.glColor4f(0.0f, 1.0f, 1.0f, 1.0f);

   Primitives.drawPoints(gl, points, 4);


   // draw a green circle with 10 segments

   gl.glLineWidth(16);

   gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);

   Primitives.drawCircle(gl, s.width / 2, s.height / 2, 100, 0, 10, false);


   // draw a green circle with 50 segments with line to center

   gl.glLineWidth(2);

   gl.glColor4f(0.0f, 1.0f, 1.0f, 1.0f);

   Primitives.drawCircle(gl, s.width / 2, s.height / 2, 50, CCMacros.CC_DEGREES_TO_RADIANS(90), 50, true);


   // open yellow poly

   gl.glColor4f(1.0f, 1.0f, 0.0f, 1.0f);

   gl.glLineWidth(10);

   CCPoint vertices[] = {CCPoint.ccp(0, 0), CCPoint.ccp(50, 50), CCPoint.ccp(100, 50), CCPoint.ccp(100, 100), CCPoint.ccp(50, 100)};

   Primitives.drawPoly(gl, vertices, 5, false);


   // closed purple poly

   gl.glColor4f(1.0f, 0.0f, 1.0f, 1.0f);

   gl.glLineWidth(2);

   CCPoint vertices2[] = {CCPoint.ccp(30, 130), CCPoint.ccp(30, 230), CCPoint.ccp(50, 200)};

   Primitives.drawPoly(gl, vertices2, 3, true);


   // draw quad bezier path

   Primitives.drawQuadBezier(gl, 0,s.height, s.width/2,s.height/2, s.width, s.height, 50);


   // draw cubic bezier path

   Primitives.drawCubicBezier(gl, s.width/2, s.height/2, s.width/2+30, s.height/2+50,

  s.width/2+60, s.height/2-50, s.width, s.height/2,100);



   // restore original values

   gl.glLineWidth(1);

   gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

   gl.glPointSize(1);

        }




기존에는 텍스쳐를 이용한 렌더링을 하였습니다. 이제 모든 그리기 라이브러리의 기초인 
기본도형 그리기를 cocos2d가 어떻게 구현하는지에 대해서 나와 잇습니다. 
크게 어려운 부분이 없을뿐더러 소스에는 친절한 주석이 나와있으므로 이를 간단하게 해석하는 
것으로 이번 강좌는 정리하겟습니다.

 // TIP:

   // If you are going to use always the same color or width, you don't

   // need to call it before every draw

   //

   // Remember: OpenGL is a state-machine.
같은 색깔이나 동일한 두께를 표현하기 위해서 매번 따로 설정할필요 없습니다.
한번 바뀐 속성은 계속 지속됩니다.
이는 opengl이 정적이기 때문입니다. 이를 잘기억하세요  







// TIP:

Every CocosNode has a "draw" method.

모든 cocosNode는 "draw" 함수를 가지고 있다
 

In the "draw" method you put all the code that actually draws your node.

이함수 안에서 node에 실제그려지므로 여기에 코드를 놓을수 있다. 
 

And Test1 is a subclass of TestDemo, which is a subclass of Layer, which is a subclass of CocosNode.

TestDeomo는 Layer의 서브 클래스 이고 Layer는 CoccosNode의 서브 클래스이다. 
 

As you can see the drawing primitives aren't CocosNode objects. They are just helper

여기에서는 cocosNode의 object를 그리지 않고 기본도형을 그리기볼수 있는데 이것들은
 

functions that let's you draw basic things like: points, line, polygons and circles.

 기본적인 도형을 그리는것을 도와주는 함수 들이다.

        //
 

TIP:

Don't draw your stuff outside the "draw" method. Otherwise it won't get transformed.

"draw"메서드 밖에서 그리지 마세요 . 그러면 재대로 적용이 되지 않는다.

        //

TIP:

If you want to rotate/translate/scale a circle or any other "primtive", you can do it by rotating

the node. eg:

   this.rotation = 90;

만약 도형의 회전/이동/크기의 변화를 주고 싶다면. Node의 속성을 이용하세요 

 






















Posted by 수다쟁이증후군 :
0. CocosNodeTest에 나오는 내용들

1. 앵커의 정의화 position과의 관계
2. 부노노드의 앵커의 변화에 따른 자식노드에 끼치는 영향 과 부노노드에 액션이 작용할때
      자식노드가 어떤 영향을 받는가?
3. Z-order에 대한 설명 간략히
4. Tag의 유일성과 중첩성(분류)
5. removechild()의 영향과 자식 노드의 재사용에 대해서 
6. 부모노드가 할매노드에서 제거 될때 자식노드의 상태 
   액션 콜백과 콜백. 
 





1.예제 분석 목적: 
=>CCNode 주요속성의 변경방법과 속성이 변경될때 화면에 어떻게 나타 나는가를 확인



2.확인속성

Test1.class==>Transform Anchor
Test2.class==>Transform Anchor and Children
Test3.class==>Z Order
Test4.class==>Tags
Test5.class==>Remove
Test6.class==>Remove with Children
Test7.class==>Stress Test #1







* 코드 설명중 속성의 변화에 따른 액션 부분은 제외 하였습니다.
3-1 Test1 ( Transform Anchor  )

Sprite sp0 = Sprite.sprite("grossini.png");

Sprite sp1 = Sprite.sprite("grossinis_sister1.png");

Sprite sp2 = Sprite.sprite("grossinis_sister2.png");

Sprite point0 = Sprite.sprite("r1.png");

Sprite point1 = Sprite.sprite("r1.png");

Sprite point2 = Sprite.sprite("r1.png");


point0.scale(0.25f);

point1.scale(0.25f);

point2.scale(0.25f);


sp0.setPosition(s.width/2, s.height / 2);

point0.setPosition(sp0.getPositionX(), sp0.getPositionY());

sp0.setAnchorPoint(0.5f, 0.5f);


sp1.setPosition(s.width/2 - 100, s.height / 2);

point1.setPosition(sp1.getPositionX(), sp1.getPositionY());

sp1.setAnchorPoint(0, 0);


sp2.setPosition(s.width/2 + 100, s.height / 2);

point2.setPosition(sp2.getPositionX(), sp2.getPositionY());

sp2.setAnchorPoint(1, 1);


addChild(sp0);

addChild(sp1);

addChild(sp2);


addChild(point0, 1);

addChild(point1, 1);

addChild(point2, 1);



사전 필요 지식
1. sprite는 기본적으로 앵커점을 0.5f 0.5f 로 잡고 시작합니다.(이미지의 센터점)
2. cocos2d의 좌표계는 Top-Left 가 아니라 Bottom-Left 입니다. 
   이에 반해 안드로이드의 화면 좌표계는 Top-Left 라서 처음 cocos2d를 접하시는 분들이 
   좀헷갈려합니다. 

코드 설명
sp0, sp1,sp2 를 화면센터에 수평정렬입니다.
point0,point1,point2 는 sp0, sp1, sp2의 앵커 포인트를 가리키고 있습니다. 
그리고 나서 sp0 sp1 sp2 의 앵커 포인트를 변형합니다. 그리고 나타난 화면은 
처음 앵커 포인트를 알게된사람들은 언듯 이해가 가지 않습니다.

이에 대해서 자세한 설명은 앵커포인트와 비슷한 이름을 지닌 position 과 비교하면 좀 더 
이해가 잘 될듯합니다. 
position은 부모Node 의 0,0 좌표에서 얼마나 떨어져 있는 지를  x와 y로 나타 낸것입니다.
Node가 (100,200)이면  부모노드에서 x 100만큼 y 200만큼 떨어진 곳에 이란것입니다.
이때 자신의 기준은 무엇일까요? 머 앵커를 설명하는 자리니까 당연히 앵커가 되겟죠.

다시말해 사이즈 가로50 세로50인 이미지를 부모노드에서 (100,200)만큼 움직이라고 하는데 
어디를 기준으로 잡아야 할까요? 이미지의 왼쪽아래? 오른쪽아래? 정가운데?
이게 바로 앵커입니다. Node의 크기가 사용자마다 다르니 특정 크기값으로 하지 말고 
이미지=Node의 원래 사이즈를 가로 세로 1 로 잡고 그 비율로 나타낸것입니다.내부적으로 화면
에 표시 될때는 이미지크기에 맞추어 특정 좌표로 표현되지만 우리가 그것까지 볼필요는
업습니다. 
(추후 강좌를 전체적인 업데이트 할 때 이미지도 포함하여 반영하겟습니다.)




3-2 Test2 (  Transform Anchor and Children  )

Sprite sp1 = Sprite.sprite("grossinis_sister1.png");

Sprite sp2 = Sprite.sprite("grossinis_sister2.png");

Sprite sp3 = Sprite.sprite("grossinis_sister1.png");

Sprite sp4 = Sprite.sprite("grossinis_sister2.png");


sp1.setPosition(100, s.height / 2);

sp2.setPosition(s.width - 100, s.height / 2);

addChild(sp1);

addChild(sp2);


sp3.scale(0.25f);

sp4.scale(0.25f);


sp1.addChild(sp3);

sp2.addChild(sp4);


IntervalAction a1 = RotateBy.action(2, 360);

IntervalAction a2 = ScaleBy.action(2, 2);


Action action1 = RepeatForever.action(Sequence.actions(a1, a2, a2.reverse()));

Action action2 = RepeatForever.action(Sequence.actions(a1.copy(), a2.copy(), a2.reverse()));


sp2.setAnchorPoint(0, 0);


sp1.runAction(action1);

sp2.runAction(action2);


이미 3-1에서 설명을 잘 이해 하셨다면 이번 내용은 어렵지 않겟 받아 들일것이라 생각합니다.
자식Node의  위치=position은 부모의 0.0 점을 기준으로 해서 결정된다 라고 위에서 이야기 드렸습니다. 그럼 그 부모노드가 속해있는 부모노드 그러니까 할배노드라 합시다. 
부모노드의 position은 할배노드의 0,0을 기준하겟죠, 결국 자식노드의 위치는 부모노드뿐만 아니라 할배노드에게도 영향을 받습니다.

이것을 액션의 rotate(회전변화)을 이용하여 상당히 적절하게 표현되고 있습니다. 실제 코드를 
돌려보기 전에 머리속으로 한번 그려보세요
할배노드 = Test2
부모노드 = sp1, sp2
자식노드 = sp3, sp4
입니다. 그와 더불어 부모노드에 대한 액션은 자식 노드에도 영향을 끼칩니다.
(강좌 업데이트때 이미지추가)





3-3 Test3 (Z Order)

Sprite sp1 = Sprite.sprite("grossinis_sister1.png");

Sprite sp2 = Sprite.sprite("grossinis_sister2.png");

Sprite sp3 = Sprite.sprite("grossini.png");


sp1.setPosition(20, 80);

sp2.setPosition(70, 50);

sp3.setPosition(s.width / 2, s.height / 2);
 

sp3.addChild(sp1, -1, kTagSprite1);
sp3.addChild(sp2, 1, kTagSprite2);


xy 축에 더불어 한가지 축 z축 입니다. z값이 양수면 화면앞 그러니까 사용자의 눈쪽 
가까이 위치하고 음수면 ,화면 너머에 위치합니다. 그러니까 이미지가 겹쳐질때 맨위로 오느냐 
맨뒤로 가서 가려지느냐의 차이를 설명한것입니다.
(참고이미지는 강좌 업데이트 하면서추가 하겟습니다.)








3-4 Test4 (Tags )

{
Sprite sp1 = Sprite.sprite("grossinis_sister1.png");

Sprite sp2 = Sprite.sprite("grossinis_sister2.png");


sp1.setPosition(100, s.height / 2);

sp2.setPosition(s.width - 100, s.height / 2);


addChild(sp1, 0, 2);

addChild(sp2, 0, 3);


schedule("delay2", 2.0f);

schedule("delay4", 4.0f);

}


public void delay2(float dt) {

     CocosNode node = getChild(2);

     IntervalAction action1 = RotateBy.action(1, 360);

node.runAction(action1);

}


public void delay4(float dt) {

     unschedule("delay4");

     removeChild(3, false);

}



태그는 말그대로 꼬리표입니다. 
안드로이드에서는 View클래스에 id 를 할당합니다. 
그 아이디를 기반으로 R.java 클래스 변수로 등록되고 액티비티 
어디에서든 접근 가능합니다.

그럼 cocos2d에 대한 구분자는 어떻게 할까요 ?
바로 TAG입니다  

안드로이드 id는  유일한 값입니다 이는 어플리케이션 package에서 관리
하기때문입니다. 
그럼 cocos2d에서는 tag는 어디서 관리할까요?
바로 자기 자신이 관리 합니다. 
그럼 으로서 활용방법은 2가지 입니다. 
Node의 독립성을 확보하기 위해 각기 고유 코드값으로 줄수도 있고
분류를 위한  비슷한 역활을 하는 Node들에서 공통의 값을 줄수도 있습니다.






3-5 remove and cleanup

public Test5() {

super();


CCSprite sp1 = CCSprite.sprite("grossinis_sister1.png");

CCSprite sp2 = CCSprite.sprite("grossinis_sister2.png");


sp1.setPosition(CGPoint.make(100, 160));

sp2.setPosition(CGPoint.make(380, 160));


CCIntervalAction rot = CCRotateBy.action(2, 360);

CCIntervalAction rot_back = rot.reverse();

//CCRepeatForever은 CCAction으로 받을것

CCAction forever = CCRepeatForever.action(

CCSequence.actions(rot, rot_back));

CCAction forever2 = forever.copy();


// forever.setTag(101);

// forever2.setTag(102);


addChild(sp1, 0, kTagSprite1);

addChild(sp2, 0, kTagSprite2);


sp1.runAction(forever);

sp2.runAction(forever2);


schedule("addAndRemove", 2.0f);

}


public void addAndRemove(float dt) {

CCNode sp1 = getChildByTag(kTagSprite1);

CCNode sp2 = getChildByTag(kTagSprite2);


removeChild(sp1, false);

removeChild(sp2, true);


addChild(sp2, 0, kTagSprite2);

addChild(sp1, 0, kTagSprite1);

}


부모노드에서 제거될때 자식노드의 상태에 대해서 
기술됩니다. 이는 단지 화면에서만 사라지는 것이 아니라 
자식노드가 가지고 있는 액션과 콜백/selector 는 어떻게 되는 것인가에 대한 예
보여 주고 있습니다

removeChild(sp1, false);
removeChild(sp2, true);
에서 보는 바와 같이 두번째 파라미터를 true로 하면  부모노드에서 자식노드를 삭제함과
동시에 자식노드의 액션과 콜백을 전부 초기화 하여 버립니다.
false로 한다면 액션과 콜백을 남겨두고 단지 소속만을 없애 버릴뿐입니다.
 


액션은 어디에 저장 되어 있을까?
removeChild(sp1, false);
removeChild(sp2, true);
분명 Layer의 child를 제거 했는데도 불구하고 
액션이 남이 있다면 .child의 action은 최소한 부모에게로 등록되지 않는다. 
그럼 ActionManager에 등록될때 child의 정보가 넘어간다는 소리인것 같은데 ㅎㅎ. ㅎ
소스 찾아 들어 가보니 역시 거기에 남아 있었다 . 
ActionManager 의 ConcurrentArrayHashMap 에 저장 되어 있어다 .
private final ConcurrentArrayHashMap<CCNode, HashElement> targets;
그러니까 다시 활성화 되게 layer에 등록시키면 AcManager가 알아서 찾아서 쓴다 
멀보고 할까?
addchild 안에 들어 가보면 뒤에 true와 false로 나뉜다 
ActionManager는 이것을 보고 액션은 실행시킬지 말지를 결정한다. 
무한 리핏액션이 아니면 액션이 종료되는 순간 이값은 false가 된다.









3-6 Test6 ( Remove with Children )

public Test6() {

            CCSize s = Director.sharedDirector().winSize();


            Sprite sp1 = Sprite.sprite("grossinis_sister1.png");

            Sprite sp11 = Sprite.sprite("grossinis_sister1.png");


            Sprite sp2 = Sprite.sprite("grossinis_sister2.png");

            Sprite sp21 = Sprite.sprite("grossinis_sister2.png");


            sp1.setPosition(100, s.height / 2);

            sp2.setPosition(s.width - 100, s.height / 2);



            IntervalAction rot = RotateBy.action(2, 360);

            IntervalAction rot_back = rot.reverse();

            Action forever1 = RepeatForever.action(Sequence.actions(rot, rot_back));

            Action forever11 = forever1.copy();


            Action forever2 = forever1.copy();

            Action forever21 = forever1.copy();


            addChild(sp1, 0, kTagSprite1);

            sp1.addChild(sp11);

            addChild(sp2, 0, kTagSprite2);

            sp2.addChild(sp21);


            sp1.runAction(forever1);

            sp11.runAction(forever11);

            sp2.runAction(forever2);

            sp21.runAction(forever21);


            schedule("addAndRemove", 2.0f);

        }


        public void addAndRemove(float dt) {

            CocosNode sp1 = getChild(kTagSprite1);

            CocosNode sp2 = getChild(kTagSprite2);


            removeChild(sp1, false);

            removeChild(sp2, true);


            addChild(sp1, 0, kTagSprite1);

            addChild(sp2, 0, kTagSprite2);

        }



이번번 예제는 할배노드에서 부모노드를 삭제할때 자식노드의 액션과 콜백은 어떻게 되느
냐를 묻는 건데요.결론만 먼저 말하자면 모두 삭제 됩니다.
자세한 내용은 cocos2d 내부 소스를 보시면 이해가 빠를겁니다.^^  결론은 간단한데 
그 내부를 설명하려면 몇단계를 거쳐야 하기때문에 일단 여기서는 제외합니다.



3-7 번 보류 StressTest
Posted by 수다쟁이증후군 :
1. 목적 
==> Action 과 밀접한 관련을 가지 scheduler 를 정확하게 인지 함으로 써 
     보다 나은 시스템을 구현하고자 합니다. 

2. 소스 분석. 
  2-1 안로로이드 activity 생명주기와  관련된 cocos2d 기본 셋팅.

==>이것은 기본 셋팅부분입니다. 이전 MenuTest 첫번째 강좌에서도 분석이 했기에 생략합니다. 


2.2. 기본 셋팅을 제외한 나머지 분석. 

2.2-1 멤버변수 

public static final int kTagAnimationDance = 1;
 

/*레이어 인덱스 번호*/
static
int sceneIdx=-1;

/* 구현될 클래스 */
static
Class<?> transitions[] = {

  SchedulerAutoremove.class,

  SchedulerPauseResume.class,

  SchedulerUnscheduleAll.class,

  SchedulerUnscheduleAllHard.class,

  SchedulerSchedulesAndRemove.class,

  SchedulerUpdate.class,

  SchedulerUpdateAndCustom.class,

  SchedulerUpdateFromCustom.class,

};



2.2-2  static classSchedulerTestLayer extendsCCLayer 

static class SchedulerTestLayer extends CCLayer {

    publicSchedulerTestLayer() {

      super();

 

      CGSize s = CCDirector.sharedDirector().winSize();

 

      CCLabel label = CCLabel.makeLabel(title(),"DroidSans", 24);

      addChild(label);

      label.setPosition(CGPoint.make(s.width / 2, s.height / 2 - 50));

 

      String subtitle = subtitle();

      if (subtitle!= null) {

        CCLabel l = CCLabel.makeLabel(subtitle(),"DroidSans", 16);

        addChild(l, 1);

        l.setPosition(s.width/2, s.height-80);

      }

 

      CCMenuItemImage item1 = CCMenuItemImage.item("b1.png", "b2.png", this, "backCallback");

      CCMenuItemImage item2 = CCMenuItemImage.item("r1.png", "r2.png", this, "restartCallback");

      CCMenuItemImage item3 = CCMenuItemImage.item("f1.png", "f2.png", this, "nextCallback");

 

      CCMenu menu = CCMenu.menu(item1,item2, item3);

      menu.setPosition(0, 0);

      item1.setPosition(s.width / 2 - 100, 30);

      item2.setPosition(s.width / 2, 30);

      item3.setPosition(s.width / 2 + 100, 30);

      addChild(menu, 1);

}

==> 레이어 공통을 따로 뽑아 구현 


2.2-3 
SchedulerTestLayer상속해서 구현해야 할 클래스들 

static class SchedulerAutoremove extendsSchedulerTestLayer
static classSchedulerPauseResume extendsSchedulerTestLayer
static classSchedulerUnscheduleAll extends chedulerTestLayer
static class chedulerUnscheduleAllHarextend SchedulerTestLayer 
static classchedulerSchedulesAndRemovextends chedulerTestLayer
static classTestNode extendsCCNode implements                                                        UpdateCallback

static classSchedulerUpdateAndCustom extends                          SchedulerTestLayer implementsUpdateCallback 

static classSchedulerUpdateFromCustom extends                        SchedulerTestLayer implementsUpdateCallback  
 
 



3. 주요 클래스 분석
3.1 static class SchedulerAutoremove extendsSchedulerTestLayer 

static class SchedulerAutoremove extends SchedulerTestLayer {

    float accum;

    publicSchedulerAutoremove() {

      super();

      schedule("autoremove", 0.5f);

      schedule("tick", 0.5f);

      accum = 0;

    }

    public void tick(float dt) {

      ccMacros.CCLOG(LOG_TAG, "Thisscheduler should not be removed");

    }

    public void autoremove(float dt) {

      accum += dt;

      String s = String.format("Time: %f", accum);

      ccMacros.CCLOG(LOG_TAG, s);

      if( accum > 3 ) {

        unschedule("autoremove");

        unschedule("tick");

        ccMacros.CCLOG(LOG_TAG, "schedulerremoved");

      }

    }

    public Stringtitle() {

      return "Self-remove an scheduler";

    }

    public Stringsubtitle() {

      return "1 scheduler will be autoremoved in 3seconds. See console";

}

}

==>schedule("tick", 0.5f);

   public void tick(float dt) {

      ccMacros.CCLOG(LOG_TAG, "Thisscheduler should not be removed");

   }
   에서 볼수 있듯이 기본본적으로 로그를 확인해야 알수 있다 .
==>Log 사용법은 tick(float dt)에 나와 있듯이 사용하면됩니다. 
==>schedule 함수 에서 알수 있듯이  첫번째 파라미터는 콜백함수 두번째 파라미터는 
   반복적으로 호출되어질 주기를 설정한다.
==>콜랙함수를 String 타임으로 넘기는것을 selector 라고 한다  당장은 이걸 왜 
   빨간색으로 했는지는 모르겟지만 뒤에 이것에 대한 것이 나온다 . 일단 알고갑시다.
==>
unschedule("autoremove"); 에서 볼수 있듯이 스케쥴의 해제는           unschedule(String selector)을 쓴다. 
==>특별히 어려운건 없습니다.  

3.2 static classSchedulerPauseResume extends chedulerTestLayer 

  static class SchedulerPauseResume extends SchedulerTestLayer {

    publicSchedulerPauseResume() {

      super();

      schedule(newUpdateCallback() {

        @Override

        public void update(float d) {

          tick1(d);

        }

      } , 0.5f);

      schedule(newUpdateCallback() {

        @Override

        public void update(float d) {

          tick2(d);

        }

      } , 1);

      schedule(newUpdateCallback() {

       

        @Override

        public void update(float d) {

          pause(d);

        }

      } , 3);

    }

    public void tick1(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick1");

    }

    public void tick2(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick2");

    }

    public void pause(float dt) {

      CCScheduler.sharedScheduler().pause(this);

    }

    public Stringtitle() {

      return "Pause / Resume";

    }

    public Stringsubtitle() {

      return "Scheduler should be paused after 3seconds. See console";

    }                 

  }

==>schedule(new UpdateCallback() {

        @Override

        public void update(float d) {

          tick1(d);

        }

      } , 0.5f);
    에서 볼수 있듯이 좀전과는 다르게 selector를 사용하지 않고  
UpdateCallback()
    인터페이스를 구현 해서 스케쥴하였습니다. 뒤에 0.5f 는 당연히 주기겟죠
    좀전에 selector를 기어억하라고 했던것은 이 때문입니다. 
==>
schedule을 구현하는데 있어서 2가지 방법이 바로 selector                                          와 UpdateCallback()구현입니다. 잘기억해두세요 

3.3 static classSchedulerUnscheduleAll extends                                                   SchedulerTestLayer 

static class SchedulerUnscheduleAll extends SchedulerTestLayer {

    publicSchedulerUnscheduleAll() {

      super();

      schedule("tick1", 0.5f);

      schedule("tick2", 1);

      schedule("tick3", 1.5f);

      schedule("tick4", 1.5f);

      schedule("unscheduleAll", 4);

    }

    public Stringtitle() {

      return "Unschedule All selectors";

    }

    public Stringsubtitle() {

      return "All scheduled selectors will beunscheduled in 4 seconds. See console";

    }

    public void tick1(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick1");

    }

    public void tick2(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick2");

    }

    public void tick3(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick3");

    }

    public void tick4(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick4");

    }

    public void unscheduleAll(float dt) {

      unscheduleAllSelectors();

    }

}

==> 이번에 하는것은 첫번째 것을 잘 보셨다면 무리 없이 진행 하실수 있을것입니다. 
     selector를 이용한 스케쥴링입니다. 
==> 다만 새롭게 나온것은  unscheduleAllSelectors(); 별거 없습니다. 
   selector로 등록했으니까 AllSelectors란 접미사가 붙는건 당연합니다. 
   selector로 등록한 모든 콜백을 삭제하라입니다. 


3.4 static class SchedulerUnscheduleAllHard extends                                                    SchedulerTestLayer 

static class SchedulerUnscheduleAllHard extends SchedulerTestLayer {

    publicSchedulerUnscheduleAllHard() {

      super();

      schedule("tick1", 0.5f);

      schedule("tick2", 1);

      schedule("tick3", 1.5f);

      schedule("tick4", 1.5f);

      schedule("unscheduleAll", 4);

    }

    public Stringtitle() {

      return "Unschedule All selectors #2";

    }

    public Stringsubtitle() {

      return "Unschedules all selectors after 4s.Uses CCScheduler. See console";

    }

    public void tick1(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick1");

    }

    public void tick2(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick2");

    }

    public void tick3(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick3");

    }

    public void tick4(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick4");

    }

    public void unscheduleAll(float dt) {

      CCScheduler.sharedScheduler().unscheduleAllSelectors();

    }

  }

==> 3.3의 살짝 변형인데요 모두 동일하고  
    3.3은 CCNode의 unscheduleAllSelectors() 함수를 이용했고
   3.4는 
sharedScheduler를 직접 이용했습니다. 
==> 바로 여기서 결정적인 차이가 나는데요 . CCNode의 schedule()함수를사용
   하면 해당 CCNode의 스케쥴만 헤제되는데 비해서 3.4처럼 해줘버리면
   cocos2d 전체의 스케쥴 걸어놓은것이 다 멈추어 버립니다. 그래서 제목에
   Hard가 붙은것이죠  

3.5 static classSchedulerSchedulesAndRemove extends                                                       SchedulerTestLayer 

static class SchedulerSchedulesAndRemove extends                                                     SchedulerTestLayer {

    publicSchedulerSchedulesAndRemove() {

      super();

      schedule("tick1", 0.5f);

      schedule("tick2", 1);

      schedule("scheduleAndUnschedule", 4);

    }

    public Stringtitle() {

      return "Schedule from Schedule";

    }

    public Stringsubtitle() {

      return "Will unschedule and scheduleselectors in 4s. See console";

    }

    public void tick1(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick1");

    }

    public void tick2(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick2");

    }

    public void tick3(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick3");

    }

    public void tick4(float dt) {

      ccMacros.CCLOG(LOG_TAG, "tick4");

    }

    public void scheduleAndUnschedule(float dt) {

      unschedule("scheduleAndUnschedule");

      unschedule("tick1");

      unschedule("tick2");

      schedule("tick3", 1);

      schedule("tick4", 1);

    }

}

==>지금까지는 대부분이 생성자에서 스케쥴링하는것인데 비해서 
   이번것은 selector에서 스케쥴을 생성해도 되는 것이냐 인데  됩니다. ㅎ
   이것도 흐름만을 잘읽어 간다면 무리없을듯 합니다.

3.6 static classSchedulerSchedulesAndRemove extends                                                SchedulerTestLayer 

static class TestNode extends CCNode implements UpdateCallback {

    String string_;

    publicTestNode(String string, int priority) {

      super();

      string_ = string;

      scheduleUpdate(priority);

    }

    public void update(float dt) {

      ccMacros.CCLOG(LOG_TAG, string_);

    }

}

static class SchedulerUpdate extendsSchedulerTestLayer {

    publicSchedulerUpdate() {

      super();

      //schedule in different order... just another test

      TestNode d = new TestNode("---", 50);

      addChild(d);

      TestNode b = new TestNode("3rd", 0);

      addChild(b);

      TestNode a = new TestNode("1st", -10);

      addChild(a);

      TestNode c = new TestNode("4th", 10);

      addChild(c);

      TestNode e = new TestNode("5th", 20);

      addChild(e);

      TestNode f = new TestNode("2nd", -5);

      addChild(f);

      schedule("removeUpdates", 4.0f);

    }

    public Stringtitle() {

      return "Schedule update with priority";

    }

    public Stringsubtitle() {

      return "3 scheduled updates. Priority shouldwork. Stops in 4s. See console";

    }

    public void removeUpdates(float dt) {

      if(getChildren() != null) {

        for (CCNodenode : getChildren()) {

          node.unscheduleAllSelectors();

        }

      }

    }

}


==>위의 예제는 2가지를 담고 있습니다. 한가지는 자식 노드의 스케쥴방법과 스케쥴의 
   우선순위 입니다.
==> 잘생각해본다면 우리가 구현하고자 하는 레이어의 어디에서 스케쥴을 정했는지 알수 
   있습니다. 바로 생성자에서 지정했습니다. 그리고 레이어쪽만 하다 잠시 까먹을 수도 
   있지만. 레이어도 Scene의 자식 CCNode 입니다. 똑같죠  ㅎㅎㅎㅎ
==> 자그럼 이번에 할것은 스케쥴이 동시에 발생하면 어느것이 먼저 발생할까요? 그거야    먼저 실핼됐던놈이 먼저 시작되는게 원칙이겟죠 ㅎㅎ



3-7 static classSchedulerUpdateAndCustom                                extends SchedulerTestLayer implements pdateCallback

static class SchedulerUpdateAndCustom extends                               SchedulerTestLayer implementsUpdateCallback {

    publicSchedulerUpdateAndCustom() {

      super();

      scheduleUpdate();

      schedule(newUpdateCallback() {       

        @Override

        public void update(float d) {

          tick(d);

        }

      });

      schedule(newUpdateCallback() {

        @Override

        public void update(float d) {

          stopSelectors(d);

        }

      }, 4.0f);

    }

    public Stringtitle() {

      return "Schedule Update + customselector";

    }

    public Stringsubtitle() {

      return "Update + custom selector at the sametime. Stops in 4s. See console";

    }

    public void update(float dt) {

      String s = String.format("update called:%f", dt);

      ccMacros.CCLOG(LOG_TAG, s);

    }

    public void tick(float dt) {

      String s = String.format("custom selector called:%f", dt);

      ccMacros.CCLOG(LOG_TAG, s);

    }

    public void stopSelectors(float dt) {

      unscheduleAllSelectors();

    }

}

==> 여기에서는 scheduleupdate() 함수와 커스텀 updatecallback 를 썩어 놓았습니다. 동작은 매 프레임마다 update()와 tick() 이 호출됩니다. 
이두개는 현제 레이어에 포함되어 있으므로 최종적으로 unscheduleAllSelectors();에 의해서 모두 제거 됩니다. 



3.8 static classSchedulerUpdateFromCustom extends                               SchedulerTestLayer implementsUpdateCallback

static class SchedulerUpdateFromCustom extends SchedulerTestLayer implementsUpdateCallback {

    publicSchedulerUpdateFromCustom() {

            super();

      schedule("schedUpdate", 2.0f);

    }

    public Stringtitle() {

      return "Schedule Update in 2 sec";

    }

    public Stringsubtitle() {

      return "Update schedules in 2 secs. Stops 2sec later. See console";

    }                 

    public void update(float dt) {

      String s = String.format("update called:%f", dt);

      ccMacros.CCLOG(LOG_TAG, s);

    }

    public void stopUpdate(float dt){

      unscheduleUpdate();

      unschedule("stopUpdate");

    }

    public void schedUpdate(float dt) {

      unschedule("schedUpdate");

      scheduleUpdate();

      schedule("stopUpdate", 2.0f);

    }

}

 

==> 여기서도 진행상에는 무리가 없습니다. 클래스명에서도 알수 있듯이 
    커스텀으로 만든 selector 에서 scheduleUpdate(); 를 사용하였습니다. 
    어찌보면 당연한 말이지요. 왜 이렇게 까지 했나 싶기도 하거든요. ㅎㅎㅎ


ScheduleTest.java 힘들고 복잡할꺼라 생각했는데 생각보다 별내용은 없네요
정리 하자면 이렇습니다.

1. 스케쥴을 생성하는 방법으로 3가지 있습니다. 
  1-1, selector이용
  1-2, updateCallback() 의 구현.
  1-3, update() 이용 입니다. 
  ==> 1-2와 1-3 거의 같은 말입니다.

2, 스케쥴 우선순위
3, 스케쥴 해제 방법

요렇게 3가지 정도로 압축되네요.  

Posted by 수다쟁이증후군 :
1. 정의
스프라이트 별거 없습니다 그냥 2D이미지입니다. 단지 용어가 익숙하지 않을뿐다시 반복하자면 에스아이 s p r i t e  스프라이트.  2D 이미지 간단히 사진이라 그림,글자 그림 이라고 생각하시면 됩니다
==>cocos2d 를 배우는 이유가 화면에 이미지띄우고 왔다리 갔다리 하기위한거니까 
     생성방법은 숙지하세요... 사실 숙지고 머고간에 너무 간단해서 그냥 한번만 보면되요 ㅎ
 


2. 생성 방법
2-1. 파일이름으로 생성하기(첫번째)

CCSprite tamara = CCSprite.sprite("grossinis_sister1.png");

==> 간단하죠  파일은 Assets 폴더에 넣어주세요 .
==> 파일이름은 확장자 포함입니다.  
==> png / bmp / jpeg 파일 지원 



2-2. 파일 이름으로 생성하기(두번째)

CCSprite spriteNormal = CCSprite.sprite("menuitemsprite.png",                                                                           CGRect.make(0,23*2,115,23));

==> 위와 같이 동일하게 파일 이름을 이용하지만 CGRect.make(top,left,bottm,rigth) 를
      이용하여 이미지 파일의 특정영역으로 부터 CCSprite 객체를 생성합니다.
==> CGRect 클래스는  간단하게 자바클래스 RectF클래스와 유사하다고 생각해주세요  
      바로 보실분들은 보세요^^;;    
2-3 2D텍스쳐 이용하여 만들기

CCTexture2D tex2 = CCTextureCache.sharedTextureCache().addImage("grossini.png");

CCSprite grossini = CCSprite.sprite(tex);

Posted by 수다쟁이증후군 :
1. 라스트 정리 
  어떻게 하다보니 org.cocos2d.actions.ease 관련 클래스를 모두 정리하였습니다.
막상정리하고 보니 별것도 없고 그냥 그렇네요 그런데 어떤 EaseAction을 쓸것인가
에 대한 고민을 안할수가 없네요 . 어떻게 해야 할까요? 하나하나 정리 테스트 해보면
좋겟지만. 먼가 감도 안오고 흠... 그래서 준비 했습니다.

휘어지는 정도가 한눈에 보이네요 ㅎㅎㅎ 그럼 
잘 골라서 쓰세요 ㅎㅎ





2.EaseAction 강의 바로가기(해당 클래스를 클릭하면 정리 강좌로 바로갑니다.)

CCEaseBackIn.java (2011/9/15 추가)

CCEaseBackInOut.java (2011/9/15 추가)

CCEaseBackOut.java (2011/9/15 추가)
 

CCEaseBounce.java (2011/9/15 추가)
* CCEaseBounceIn / CCEaseBounceInOut / CCEaseBounceOut  포함


CCEaseElastic.java (2011/9/15 추가)
CCEaseElasticIn /  CCEaseElasticInOut / CCEaseElasticOut 포함


CCEaseExponentialIn.java (2011/9/15 추가)

CCEaseExponentialInOut.java (2011/9/15)

CCEaseExponentialOut.java (2011/9/15)


CCEaseRateAction.java (2011/9/15)
CCEaseIn / CCEaseInOut / CCEaseOut  포함


CCEaseSineIn.java (2011/9/15)

CCEaseSineInOut.java (2011/9/15)

CCEaseSineOut.java (2011/9/15)


==> 위를 6개묶음으로 분류한것은 내부액션의 기간 수정 방법에 대한것입니다. 
     (결과값을 만들어내는 수식의 종류에 따라)




Posted by 수다쟁이증후군 :
1.클래스 설명
 
==> sin 함수,cos함수를 시뮬레이션화 한 클래스들 입니다.  
==> 네이밍만 이 싸인함수라고했지만. 
     실제로는 CCEaseSineIn /CCEaseSineInOut  이 2개는 코사인 함수를 이용합니다. 

==> 단지 MoveAction 만을 위한 클래스는 아니며 CCNode 속성에 있는 모든 값을 
     대상으로 합니다.  
==> (참고 : 
EaseAction 이란 ?


2. 클래스 관계도




3.추가된 멤버 변수 / 함수
==>추가된 멤버 변수는 없습니다. 
==> 없습니다. 라고 단호하게 말할까 했지만. 클래스 멤버 변수가 없다는것뿐이지
      EaseAction의 핵심 함수 update(오버라이드됨)에 있습니다.
      이는 EaseAction의 특성을 구별지을수 있는 핵심 부분이기에 각 클래스별 
      오버라이딩된 update(float t)를 살펴보겟습니다.
==> EaseAction의 동일한 반복입니다. 

CCEaseSineIn

@Override

    public void update(float t) {

        other.update(-1 * (float)Math.cos(t * (float) Math.PI / 2) + 1);

    }

 

CCEaseSineInOut

@Override

    public void update(float t) {

        other.update(-0.5f * ((float)Math.cos(Math.PI * t) - 1));

    }

 

CCEaseSineOut

    @Override

    public void update(float t) {

        other.update((float)Math.sin(t * (float) Math.PI / 2));

    }



==> 클래스 관계도의 특성표는 위에 오버라이딩된 함수공식에 따른것입니다. 

==> 바로 여기에서 알수 있듯이 CCEaseAction을 상속해서 여기처럼 update() 부분을
    오버라이딩해서 쓴다면 사용자별 
CCEaseRateAction을 만들수 있을것 입니다. 
    (솔직히 저거 쓸수 있는 사람은 별로 안되겟죠^^) 

   


4-4.사용법및 적용가능한곳.

public static CCEaseSineIn action(CCIntervalAction action) {

        return new CCEaseSineIn(action);

    }


    protected CCEaseSineIn(CCIntervalAction action) {

        super(action);

    }

--------------------------------------------------------------------------------- 


public static CCEaseSineInOut action(CCIntervalAction action) {

        return new CCEaseSineInOut(action);

    }


    protected CCEaseSineInOut(CCIntervalAction action) {

        super(action);

    }

--------------------------------------------------------------------------------- 


    public static CCEaseSineOut action(CCIntervalAction action) {

        return new CCEaseSineOut(action);

    }


    protected CCEaseSineOut(CCIntervalAction action) {

        super(action);

    }


==>파라미터 값으로 inner Action 에 대입할 action을 넣습니다 
==> CCNode의 속성을 변경시키는 액션은 어떤것이든지 적용이 가능합니다. 그리고
   일대일 대응이기때문에  CCSequence 또는 CCSpawn 액션또한  자신이 원했던 결과물을 
   얻을수 있을겁니다.
Posted by 수다쟁이증후군 :
1.클래스 설명

Base class for Easing actions with rate parameters 

==> rate 파라미터롤 가속도를 나타냅니다. (시간변위당 속도변위)
==> 가속도 효과를 나타내기 위해서 내부 액션의 가속도를 변경
      변경시키기 위한 추상화 클래스가 아닙니다. 기존에는 추상화 해놓고이거는 왜 
    추상화 안해 놓았는지 .... cocos2d가 아직 완성이 안되었다는걸가요? 흠... 
    조금더 고민을 해보아야 할듯합니다. 

==> 단지 MoveAction 만을 위한 클래스는 아니며 CCNode 속성에 있는 모든 값을 
     대상으로 합니다.  
==> (참고 : 
EaseAction 이란 ?


2. 클래스 관계도




3.추가된 멤버 변수 / 함수
==>추가된 멤버 변수는 이고  

/** rate value for the actions */
float rate;


==> 추가된 멤버 함수(추상화 함수 가 아닌 단지 오버라이드 함수 입니다.)
==> 멤버변수가 늘어난것이니만큼 기존의 copy()와 reverse()를  새롭게 정의하는것은 
     당연합니다. 

 @Override

    public CCEaseRateAction copy() {

        return new CCEaseRateAction(other.copy(), rate);

    }


    @Override

    public CCIntervalAction reverse() {

        return new CCEaseRateAction(other.reverse(), 1 / rate);

    }






4.CCEaseRateAction를 상속하는 클래스들

CCEaseIn.java

CCEaseInOut.java

CCEaseOut.java


==> 기존의 네이밍 규칙과 좀 다르네요 머 제가 한게 아니니까 일단 그려려니 할께요^^;;
==> 위의 클래스 설명을 따로 뺄까생각해보았지만. 
 
    좀 비효울적인듯 하여 아래에 추가로 올립니다. 






4-1 CCEaseIn/ CCEaseInOut  / CCEaseOut 클래스 설명 
 
==>기존의 CCRateAction을 상속하여 지수함수를 시뮬레이션 합니다.
==>CCEaseExponential~~ 류의 클래스와 거의 비슷하게 나오지만 조금 다르네요 쪼끔...
    개인적인 생각으로 굳이 이럴필요 있나 싶을정도로 말이죠. 





4-2. 클래스 관계도


==> 진짜 보면 볼수록 너무 유사하군요. 왜 이런류의 클래스를 만들어서 사람 귀찮게시리 . 쯧..





4-3. 추가된 멤버변수/함수
==> 없습니다. 라고 단호하게 말할까 했지만. 클래스 멤버 변수가 없다는것뿐이지
      EaseAction의 핵심 함수 update(오버라이드됨)에 있습니다.
      이는 EaseAction의 특성을 구별지을수 있는 핵심 부분이기에 각 클래스별 
      오버라이딩된 update(float t)를 살펴보겟습니다.
==> EaseAction의 동일한 반복입니다. 

CCEaseIn

 @Override

    public void update(float t) {

        other.update((float) Math.pow(t, rate));

    }

 

CCEaseInOut

   @Override

    public void update(float t) {

        int sign = 1;

        int r = (int) rate;

        if (r % 2 == 0)

            sign = -1;


        t *= 2;

        if (t < 1)

            other.update(0.5f * (float) Math.pow(t, rate));

        else

            other.update(sign * 0.5f * ((float) Math.pow(t - 2, rate) + sign * 2));

    }

 

CCEaseOut

   @Override

    public void update(float t) {

        other.update((float) Math.pow(t, 1 / rate));

    }



==> 클래스 관계도의 특성표는 위에 오버라이딩된 함수와 float rate변수 의 공식에 
    따른것입니다. 

==> 바로 여기에서 알수 있듯이 CCEaseRateAction을 상속해서 여기처럼 update() 부분을
    오버라이딩해서 쓴다면 사용자별 
CCEaseRateAction을 만들수 있을것 입니다. 
    (솔직히 저거 쓸수 있는 사람은 별로 안되겟죠^^) 

   


4-4.사용법및 적용가능한곳.

public static CCEaseIn action(CCIntervalAction action, float rate) {

        return new CCEaseIn(action, rate);

    }


    protected CCEaseIn(CCIntervalAction action, float rate) {

        super(action, rate);

    }
--------------------------------------------------------------------------------- 


   public static CCEaseInOut action(CCIntervalAction action, float rate) {

        return new CCEaseInOut(action, rate);

    }


    protected CCEaseInOut(CCIntervalAction action, float rate) {

        super(action, rate);

    }
--------------------------------------------------------------------------------- 


   public static CCEaseOut action(CCIntervalAction action, float rate) {

        return new CCEaseOut(action, rate);

    }


    protected CCEaseOut(CCIntervalAction action, float rate) {

        super(action, rate);

    }


==> 보시다 싶이 지금까지와는 달리 인자값을 2개를 모두 주어야 합니다.
    (inner action값과 rate 값 두개) 

==> CCNode의 속성을 변경시키는 액션은 어떤것이든지 적용이 가능합니다만. 
   일대일 대응이기때문에  CCSequence 또는 CCSpawn 액션또한  자신이 원했던 결과물을
   얻을수 있을겁니다.
Posted by 수다쟁이증후군 :
1.클래스 설명

어떤 변수는 한번 이상을 트리거하게 됩니다.(이 함수는 일대일대응이 아닙니다.) 
그래서 내부 액션은 이 변수값에 다시 영향을 받게 됩니다. CCMoveBy, CCScaleBy, CCRotateBy 같은 간단한 액션은 EaseBack 액션에 적용하는 것이 무방하지만 CCSequence 또는 CCSpawn 액션은 예기치 못한 결과를 얻을 수 있습니다.
<출처 :http://www.cocos2d-iphone.org/wiki/doku.php/ko:prog_guide:actions_ease

 
==>이전의 이런설명과 달리 이 클래스의 시간변수는 일대일 대응이 됩니다. 
   그러므로 CCSequence 와  CCSpawn Action을 사용해도 무방합니다. 
==> 지수함수를 시뮬레이션 해놓은 클래스 입니다.  


2. 클래스 관계도


==> 지수함수를 시뮬레이션 해놓은 클래스 입니다.  

3. 추가된 멤버변수/함수
==> EaseAction의 핵심 함수 update(오버라이드됨)에 중요한 수식이 있습니다. 
    이는 EaseAction의 특성을 구별지을수 있는 핵심 부분이기에 각 클래스별 
    오버라이딩된 update(float t)를 살펴보겟습니다.

   

CCEaseExponentialIn 
@Override

    public void update(float t) {

        other.update((t == 0) ? 0 : (float) Math.pow(2, 10 * (t / 1 - 1)) - 1 * 0.001f);

    }


CCEaseExponentialInOut 

 @Override

    public void update(float t) {

    t /= 0.5f;

        if (t < 1)

            t = 0.5f * (float) Math.pow(2, 10 * (t - 1));

        else

            t = 0.5f * (-(float) Math.pow(2, -10 * (t - 1) ) + 2);

        other.update(t);

    }


CCEaseExponentialOut 

 @Override

    public void update(float t) {

        other.update((t == 1) ? 1 : ((float) (-Math.pow(2, -10 * t / 1) + 1)));

    }


==>클래스 관계도의 특성표는 위에 오버라이딩된 함수의 공식에 따른것입니다. 
==> 바로 여기에서 알수 있듯이 EaseAction을 오버라이딩하고 여기처럼 update() 부분을
    오버라이딩해서 쓴다면 사용자별 EaseAction을 만들수 있을것 입니다. 
    (수학책을 방정식 공석을 찾아 한번 해보세요 ㅎㅎㅎ 나중에 저도 도전해볼려고 합니다)
==> 오버라이딩된 함수 내부를 상세하게 설명할까 고민했지만 이건 별의미 없는것 같아서 
    패스 합니다. 



4.사용법및 적용가능한곳.

 public static CCEaseExponentialIn action(CCIntervalAction action) {

        return new CCEaseExponentialIn(action);

    } 

 
public static CCEaseExponentialOut action(CCIntervalAction action) {

        return new CCEaseExponentialOut(action);

    }
 

public static CCEaseExponentialOut action(CCIntervalAction action) {

        return new CCEaseExponentialOut(action);

    } 

 


==> 이처럼 동일합니다. 
==> CCNode의 속성을 변경시키는 액션은 어떤것이든지 적용이 가능합니다만. 
    CCSequence 또는 CCSpawn 액션은 자신이 원했던 결과물을 얻을수 있습니다.
Posted by 수다쟁이증후군 :
1.클래스 설명

These actions alters the time simulating an elastic. Elastic actions will use time values greater than 1 and lower than 0, so the inner action should be prepared to handle this special values.

==> 이 액션은 고무밴드를 시뮬레이션(흉내내는) 액션입니다. Elastic action은 사용되는    시간변수는 1보다 크고 0보다 작습니다. 내부부액션(EaseAction이 멤버변수로 가지고 있는
    는 CCIntervalAction 레퍼런스변수) 이 특수한 변수를 다루기 위해서이다. 
 
==> 말 그대로 탄력성이 느껴지는 효과를 나타내기 위해서 내부 액션의 가속도를 변경
      변경시키기 위한 추상화 클래스입니다. 
==> 단지 MoveAction 만을 위한 클래스는 아니며 CCNode 속성에 있는 모든 값을 
     대상으로 합니다.  
==> (참고 : EaseAction 이란 ?


2. 클래스 관계도



3.추가된 멤버 변수 / 함수
==>추가된 멤버 변수는 이고  

/** period of the wave in radians. default is 0.3 */
protected float period_;


==> 추가된 멤버 함수(추상화 함수 )
==> 멤버변수가 늘어난것이니만큼 기존의 copy()와 reverse()를  새롭게 정의하는것은
     당연합니다. 

 @Override

    public abstract CCEaseAction copy();


    @Override

    public abstract CCIntervalAction reverse();






4.CCEaseBounce 를 상속하는 클래스들

CCEaseElasticIn.java

CCEaseElasticInOut.java

CCEaseElasticOut.java


==> 위의 클래스 설명을 따로 뺄까생각해보았지만. 
      좀 비효울적인듯 하여 아래에 추가로 올립니다. 




4-1 CCEaseElasticIn / CCEaseElasticInOut  / CCEaseElasticOut클래스 설명 

어떤 변수는 한번 이상을 트리거하게 됩니다.(이 함수는 일대일대응이 아닙니다.) 
그래서 내부 액션은 이 변수값에 다시 영향을 받게 됩니다. CCMoveBy, CCScaleBy, CCRotateBy 같은 간단한 액션은 EaseBack 액션에 적용하는 것이 무방하지만 CCSequence 또는 CCSpawn 액션은 예기치 못한 결과를 얻을 수 있습니다.
<출처 :http://www.cocos2d-iphone.org/wiki/doku.php/ko:prog_guide:actions_ease

 
==> 음... 설명이 조금 애한데요 
      원활한 설명을 위해서 클래스 관계도 를 먼저 보겟습니다




4-2. 클래스 관계도



==> 이제 클래스 설명을 다시 보겟습니다. 애매한 단어가 

     "어떤 변수는 한번 이상을 트리거하게 됩니다" 이라는 말인데 위에 그림에 보면 이해가 좀더 
     잘 될것입니다 (여기서 변수라함은 시간변수입니다. update() 에 들어가는 시간값입니다.)
==> 바로 위에 설명은 반복되고 있어 뺄까 고민했지만. 아직은 필요한듯 하여 그냥 두기로
     했습니다 
==> 솔직히 이게 왜 탄력적인 느낌이 나는지 이해가 잘 안됩니다. 그냥 이런가보다 아~~ 하는
    정도죠 ㅎㅎ 






4-3. 추가된 멤버변수/함수
==> 없습니다. 라고 단호라게 말할까 했지만. 클래스 멤버 변수가 없다는것뿐이지
      EaseAction의 핵심 함수 update(오버라이드됨)에 있습니다.
      이는 EaseAction의 특성을 구별지을수 있는 핵심 부분이기에 각 클래스별 
      오버라이딩된 update(float t)를 살펴보겟습니다.
==> EaseAction의 동일한 반복입니다. 

CCEaseElasticIn
@Override

    public void update(float t) {

        float newT = 0;

        if (t == 0 || t == 1) {

            newT = t;


        } else {

            float s = period_ / 4;

            t = t - 1;

            newT = (float) (-Math.pow(2, 10 * t) * Math.sin((t - s) * M_PI_X_2 / period_));

        }

        other.update(newT);

    }

 

CCEaseElasticInOut
public void update(float t) {

        float newT = 0;


        if (t == 0 || t == 1)

            newT = t;

        else {

            t = t * 2;

            if (period_ == 0)

                period_ = 0.3f * 1.5f;

            float s = period_ / 4;


            t = t - 1;

            if (t < 0) {

                newT = (float) (-0.5f * Math.pow(2, 10 * t) * Math.sin((t - s) * M_PI_X_2 / period_));

            } else {

                newT = (float) (Math.pow(2, -10 * t) * Math.sin((t - s) * M_PI_X_2 / period_) * 0.5f + 1);

            }

        }

        other.update(newT);

    }

 

CCEaseElasticOut
@Override

    public void update(float t) {

        float newT = 0;

        if (t == 0 || t == 1) {

            newT = t;

        } else {

            float s = period_ / 4;

            newT = (float) (Math.pow(2, -10 * t) * Math.sin((t - s) * M_PI_X_2  / period_) + 1);

        }

        other.update(newT);

    }



==> 클래스 관계도의 특성표는 위에 오버라이딩된 함수와 period_변수 의 공식에 
    따른것입니다. 

==> 바로 여기에서 알수 있듯이 CCEaseElastic 을 오버라이딩하고 여기처럼 update() 부분을
    오버라이딩해서 쓴다면 사용자별 CCEaseElastic 을 만들수 있을것 입니다. 
    (솔직히 저거 쓸수 있는 사람은 별로 안되겟죠^^) 

   


4-4.사용법및 적용가능한곳.

public static CCEaseElasticIn action(CCIntervalAction action) {

        return new CCEaseElasticIn(action, 0.3f);

    }


    public static CCEaseElasticIn action(CCIntervalAction action, float period) {

        return new CCEaseElasticIn(action, period);

    }


    protected CCEaseElasticIn(CCIntervalAction action, float period) {

        super(action, period);

    }


==> 보시다 싶이 지금까지와는 달리 period 값을 추가로 줄수 있습니다. 실다면 
    디폴트로 0.3이 할당 됩니다. 

==> CCNode의 속성을 변경시키는 액션은 어떤것이든지 적용이 가능합니다만. 
    CCSequence 또는 CCSpawn 액션은 자신이 원했던 결과물을 얻을수 없을지도 모릅니다. 


Posted by 수다쟁이증후군 :
1.클래스 설명

 
==> 말 그대로 공이 통통 튕기듯한 효과를 나타내기 위해서 내부 액션의 가속도를 변경
      변경시키기 위한 추상화 클래스입니다.
==> 단기 MoveAction 만을 위한 클래스는 아니며 CCNode 속성에 있는 모든 값을
     대상으로 합니다.  
==>(참고 : EaseAction 이란 ?


2. 클래스 관계도


==> CCAction 에서부터 많이 흘러 왔네요 어디까지 흘러갈지 저도 궁금합니다. ㅎㅎㅎ

3.추가된 멤버 변수 / 함수
==>추가된 멤버 변수는 없습니다. 
==>추가된 멤버 함수는 있습니다. 

protected float bounceTime(float t) {

        if (t < 1 / 2.75) {

            return 7.5625f * t * t;

        } else if (t < 2 / 2.75) {

            t -= 1.5f / 2.75f;

            return 7.5625f * t * t + 0.75f;

        } else if (t < 2.5 / 2.75) {

            t -= 2.25f / 2.75f;

            return 7.5625f * t * t + 0.9375f;

        }


        t -= 2.625f / 2.75f;

        return 7.5625f * t * t + 0.984375f;

    }


==> 바운스 효과를 나타내기 위한 수학공식인듯합니다. 
      7.5625 / 2.75 / 2.25 / 0.984375
==> 이거 확인해봏수 있으면 좋지만 수학은 젬뱅이라. ㄷㄷ 어디 참고할만 거 없나요?


4.CCEaseBounce 를 상속하는 클래스들

CCEaseBounceIn.java

CCEaseBounceInOut.java

CCEaseBounceOut.java


==> 위의 클래스 설명을 따로 뺄까생각해보았지만. 
      좀 비효울적인듯 하여 아래에 추가로 올립니다. 




4-1 CCEaseBounceIn /CCEaseBounceInOut / CCEaseBounceOut 클래스 설명 

어떤 변수는 한번 이상을 트리거하게 됩니다.(이 함수는 일대일대응이 아닙니다.) 
그래서 내부 액션은 이 변수값에 다시 영향을 받게 됩니다. CCMoveBy, CCScaleBy, CCRotateBy 같은 간단한 액션은 EaseBack 액션에 적용하는 것이 무방하지만 CCSequence 또는 CCSpawn 액션은 예기치 못한 결과를 얻을 수 있습니다.
<출처 :http://www.cocos2d-iphone.org/wiki/doku.php/ko:prog_guide:actions_ease

 
==> 음... 설명이 조금 애한데요 
      원활한 설명을 위해서 클래스 관계도 를 먼저 보겟습니다




4-2. 클래스 관계도


==> 이제 클래스 설명을 다시 보겟습니다. 애매한 단어가 
     "어떤 변수는 한번 이상을 트리거하게 됩니다" 이라는 말인데 위에 그림에 보면 이해가 좀더 
     잘 될것입니다 (여기서 변수라함은 시간변수입니다. update() 에 들어가는 시간값입니다.)
==> 바로 위에 설명은 반복되고 있어 뺄까 고민했지만. 아직은 필요한듯 하여 그냥 두기로
     했습니다 






4-3. 추가된 멤버변수/함수
==> 없습니다. 라고 단호라게 말할까 했지만. 클래스 멤버 변수가 없다는것뿐이지
      EaseAction의 핵심 함수 update(오버라이드됨)에 중요한 지역변수가 있습니다. 
      이는 EaseAction의 특성을 구별지을수 있는 핵심 부분이기에 각 클래스별 
      오버라이딩된 update(float t)를 살펴보겟습니다.
==> EaseAction의 동일한 반복입니다. 

CCEaseBounceIn
public void update(float t) {

        float newT = 1 - bounceTime(1 - t);

        other.update(newT);

    }


CCEaseBounceInOut
 @Override

    public void update(float t) {

        float newT = 0;

        if (t < 0.5) {

            t = t * 2;

            newT = (1 - bounceTime(1 - t)) * 0.5f;

        } else

            newT = bounceTime(t * 2 - 1) * 0.5f + 0.5f;


        other.update(newT);

    }


CCEaseBounceOut
@Override

    public void update(float t) {

        float newT = bounceTime(t);

        other.update(newT);

    }


==> 클래스 관계도의 특성표는 위에 오버라이딩된 함수와 bounceTime() 의 공식에
    따른것입니다. 

==> 바로 여기에서 알수 있듯이 EaseAction을 오버라이딩하고 여기처럼 update() 부분을
    오버라이딩해서 쓴다면 사용자별 EaseAction을 만들수 있을것 입니다. 
    (수학책을 방정식 공석을 찾아 한번 해보세요 ㅎㅎㅎ 나중에 저도 도전해볼려고 합니다)






4-4.사용법및 적용가능한곳.

public static CCEaseBounceIn action(CCIntervalAction action) {

        return new CCEaseBounceIn(action);

    }

 public static CCEaseBounceInOut action(CCIntervalAction action) {

        return new CCEaseBounceInOut(action);

    }

 public static CCEaseBounceOut action(CCIntervalAction action) {

        return new CCEaseBounceOut(action);

    }


==> 이처럼 동일합니다. 
==> CCNode의 속성을 변경시키는 액션은 어떤것이든지 적용이 가능합니다만. 
    CCSequence 또는 CCSpawn 액션은 자신이 원했던 결과물을 얻을수 없을지도 모릅니다. 






















 


Posted by 수다쟁이증후군 :
1.클래스 설명

어떤 변수는 한번 이상을 트리거하게 됩니다.(이 함수는 일대일대응이 아닙니다.)
그래서 내부 액션은 이 변수값에 다시 영향을 받게 됩니다. CCMoveBy, CCScaleBy, CCRotateBy 같은 간단한 액션은 EaseBack 액션에 적용하는 것이 무방하지만 CCSequence 또는 CCSpawn 액션은 예기치 못한 결과를 얻을 수 있습니다.
<출처 :http://www.cocos2d-iphone.org/wiki/doku.php/ko:prog_guide:actions_ease

 
==> 음... 설명이 조금 애한데요 
      원활한 설명을 위해서 클래스 관계도 를 먼저 보겟습니다

2. 클래스 관계도

==> 이제 클래스 설명을 다시 보겟습니다. 애매한 단어가 
     "어떤 변수는 한번 이상을 트리거하게 됩니다" 이라는 말인데 위에 그림에 보면 이해가 좀더 
     잘 될것입니다 (여기서 변수라함은 시간변수입니다. update() 에 들어가는 시간값입니다.)

3. 추가된 멤버변수/함수
==> 없습니다. 라고 단호라게 말할까 했지만. 클래스 멤버 변수가 없다는것뿐이지
      EaseAction의 핵심 함수 update(오버라이드됨)에 중요한 지역변수가 있습니다. 
      이는 EaseAction의 특성을 구별지을수 있는 핵심 부분이기에 각 클래스별 
      오버라이딩된 update(float t)를 살펴보겟습니다.
   

CCEaseBackIn 클래스
 @Override

    public void update(float t) {

        float overshoot = 1.70158f;

        other.update(t * t * ((overshoot + 1) * t - overshoot));

    }


CCEaseBackInOut 
@Override

    public void update(float t) {

        float overshoot = 1.70158f * 1.525f;


        t = t * 2;

        if (t < 1) {

            other.update((t * t * ((overshoot + 1) * t - overshoot)) / 2);

        } else {

            t = t - 2;

            other.update((t * t * ((overshoot + 1) * t + overshoot)) / 2 + 1);

        }

    }


CCEaseBackOut 
@Override

    public void update(float t) {

        float overshoot = 1.70158f;


        t = t - 1;

        other.update(t * t * ((overshoot + 1) * t + overshoot) + 1);

    }


==>클래스 관계도의 특성표는 위에 오버라이딩된 함수의 공식에 따른것입니다. 
==> 바로 여기에서 알수 있듯이 EaseAction을 오버라이딩하고 여기처럼 update() 부분을
    오버라이딩해서 쓴다면 사용자별 EaseAction을 만들수 있을것 입니다. 
    (수학책을 방정식 공석을 찾아 한번 해보세요 ㅎㅎㅎ 나중에 저도 도전해볼려고 합니다)
==> 오버라이딩된 함수 내부를 상세하게 설명할까 고민했지만 이건 별의미 없는것 같아서 
    패스 합니다. 


4.사용법및 적용가능한곳.

public static CCEaseBackIn action(CCIntervalAction action) {

        return new CCEaseBackIn(action);

    }

 public static CCEaseBackInOut action(CCIntervalAction action) {

        return new CCEaseBackInOut(action);

    }

 public static CCEaseBackOut action(CCIntervalAction action) {

        return new CCEaseBackOut(action);

    }


==> 이처럼 동일합니다. 
==> CCNode의 속성을 변경시키는 액션은 어떤것이든지 적용이 가능합니다만. 
    CCSequence 또는 CCSpawn 액션은 자신이 원했던 결과물을 얻을수 없을지도 모릅니다. 








Posted by 수다쟁이증후군 :

1. 클래스 설명

Base class for Easing actions


==> 액션을 쉽게 하게위한 기본 클래스 입니다. 
==> 말그대로 쉬운 액션 입니다. 액션을 보다 쉽고 재밌게 쓰기 위한 기본클래스입니다. 

==> 이렇게 클래스 소스에서 뽑아 낼수 있는 자료는 별로 없네요 그래서 홈페이지 있는
    자료를 참고 해봅니다.     

Ease 액션은 내부의 액션의 기간을 수정하는 특별한 composition액션입니다. 

Flash에서는 이러한 액션을 Tweening 또는 Easing 액션이라고 합니다.


이 액션을 내부 액션의 속도를 수정하지만 전체 동작 시간을 수정하지는 않습니다. 

내부 액션이 5초 동안 수행된다면 전체 시간은 5초 동안 진행될겁니다.


Ease 액션은 동작 시간을 선형적으로 수정합니다.
 




예를 들면 내부 액션을 가속화하거나 저속화합니다.


이 액션을 3가지 타입으로 구분할 수 있습니다. :


In actions: 액션의 처음부분을 가속화

Out actions: 액션의 끝 부분을 가속화

InOut actions: 처음/끝과 끝에서 가속화

easing 또는 tweening 액션은 다음 페이지를 참조하세요. :


http://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html

http://www.robertpenner.com/easing/easing_demo.html 

위에 2페이지를 찾아 보시면 정말 깔끔하게 잘 정리 되어있습니다.  

 



2. 추가된 멤버 변수 

public static final float M_PI_X_2 = (float) (Math.PI * 2.0f);
protected CCIntervalAction other;


==>첫번째 멤버변수 M_PI_X_2  가 있는 것을 보니 액션을 사용할때 수학적인 요소를 사용하려
    나 봅니다.
==>두번째 멤버변수  
other  CCIntervalAction을 멤버변수로 하나더 가지고 있습니다. 이걸 왜 
    가지고 있을까요? 위에서 설명한바와 같이 액션의 기간을 수정하기위함입니다. (기간 수정
    이란 말은 액션의 속도를 바꾼다는 말입니다.)
   
3. 클래스 상속 관계도


(출처 :http://www.cocos2d-iphone.org/api-ref/0.99.0/interface_c_c_ease_action.html)
 
==>중간 중간 헷갈리수도 있으니 일단 참고하세요 

4. CCEaseAction을 상속하는 클래스들 (업데이트되는 분석글을 보려면 초록색글자 클릭)

CCEaseBackIn.java (2011/9/15 추가)

CCEaseBackInOut.java (2011/9/15 추가)

CCEaseBackOut.java (2011/9/15 추가)
 

CCEaseBounce.java (2011/9/15 추가)
* CCEaseBounceIn / CCEaseBounceInOut / CCEaseBounceOut  포함


CCEaseElastic.java (2011/9/15 추가)
CCEaseElasticIn /  CCEaseElasticInOutCCEaseElasticOut 포함


CCEaseExponentialIn.java (2011/9/15 추가)

CCEaseExponentialInOut.java (2011/9/15)

CCEaseExponentialOut.java (2011/9/15)


CCEaseRateAction.java (2011/9/15)
CCEaseInCCEaseInOut / CCEaseOut  포함


CCEaseSineIn.java (2011/9/15)

CCEaseSineInOut.java (2011/9/15)

CCEaseSineOut.java (2011/9/15)


==> 위를 6개묶음으로 분류한것은 내부액션의 기간 수정 방법에 대한것입니다. 
     (결과값을 만들어내는 수식의 종류에 따라)


5. 쓰이는 곳 

==> 실제적으로 코드에서 사용할일은 없을듯합니다. CCEaseAction 클래스를 기반으로 
      확장된 클래스(4번참고)를 사용하세요 
==> cocos2d는 아직 확장중인 엔진으므로 혹시 사용자가 나만의 EaseAction을 구현할때나 
     쓰일 것 입니다.

                 





Posted by 수다쟁이증후군 :

CCCameraAction 이 CCIntervalAction을 상속했다지만 다이렉트로 이 클래스를 사용할일은
현재까지는 별로 없을듯합니다.   하는 일이라고는 거의 초기화 관련 변수들을 초기화 해준는것말고는 없습니다.   

<출처 :http://www.cocos2d-iphone.org/api-ref/0.99.0/interface_c_c_orbit_camera.html>

위에 그림에서 보다 시피  실질적으로 쓰이는 부분은 CCOrbitCamera 입니다. 
즉  카메라 관련 Action을 하려면 CCOrbitCamera 을 쓰세요 

그럼 본격적으로 CCOrbitCamera 을 알아보고자 합니다.
일단 클래스 설명부터 

/** CCOrbitCamera action

 * Orbits the camera around the center of the screen using spherical coordinates

 */


구면자표계를 사용하여 화면가운데를 이동하는 카메라의 궤도이다? 정확안 해석은 아닌데
의미는 대충 알것네요.
(구면좌표계란 ? 
중심에서의 거리, 방위각, 위도를 이용하여 3차원 위치를 표시하는 방법. 구면에서 나타나는 현상이 나 구면 형태로 전파되는 현상을 기술하기에 편리함.(출처 네이버 지식사전))

멤버변수로 
    float radius; 거리 
    float deltaRadius; 목표 거리
    float angleZ; 방위각
    float deltaAngleZ; 목표방위각
    float deltaAngleX;  목표위도
    float angleX; 위도 
있습니다. 다른멤버 변수가 있기는 하지만. 이는 위에서 설정한 값을 
라디언값으로 바꾸어 부분이므로 우리가 참고 할 필요는 없습니다.
생성자는  아래와 같습니다. 

 protected CCOrbitCamera(float t, float r, float dr, float z, float dz, float x, float dx)


t 는 Action의 시간을 나타내고 
차례대로 위의 멤버변수와 맵핑됩니다.
이 멤버변수에 따라 결과 값이 상당히 달라지므로 충분한 테스트를 해보는것을 추천합니다. 
대충 이렇게 값을 넣으면 이렇게 나오겟지 하고 대충 넣으면 원치않던 결과값이 나올수 있습니다. 


관련 테스트 예제는
ActionsTest.java
CocosNodeTest.java 
EffectsAdvancedTest.java
SpritesTest.java 
에 포함되어있습니다.  참고해보세요 






 
 
Posted by 수다쟁이증후군 :

CCIntervelAction을 직접 상속하는 클래스는 
4개의 패키지로 나누어져 있습니다. 
해당 클래스를 클릭 하면 상세한 설명을 보실수 있습니다. (분석글이 있는것은 파란색입니다)

org.cocos2d.actions.camera

    CCCameraAction.java(2011/9/14 추가분)

org.cocos2d.actions.ease

    CCEaseAction.java(2011/9/14 추가분)

org.cocos2d.actions.grid

    CCAccelAmplitude.java

    CCAccelDeccelAmplitude.java

    CCDeccelAmplitude.java

    CCGridAction.java

org.cocos2d.actions.interval

    CCAnimate.java

    CCBezierBy.java

    CCBlink.java

    CCDelayTime.java

    CCFadeIn.java

    CCFadeOut.java

    CCFadeTo.java

    CCJumpBy.java

    CCMoveTo.java

    CCProgressFromTo.java

    CCProgressTo.java

    CCPropertyAction.java

    CCRepeat.java

    CCReverseTime.java

    CCRotateBy.java

    CCRotateTo.java

    CCScaleTo.java

    CCSequence.java

    CCSkewTo.java

    CCSpawn.java

    CCTintBy.java

    CCTintTo.java

 
Posted by 수다쟁이증후군 :
Intervel 이라 함은 간격을 나타냅니다.

/** An interval action is an action that takes place within a certain period of time.

It has an start time, and a finish time. The finish time is the parameter

duration plus the start time.


These CCIntervalAction actions have some interesting properties, like:

 - They can run normally (default)

 - They can run reversed with the reverse method

 - They can run with the time altered with the Accelerate, AccelDeccel and Speed actions.


For example, you can simulate a Ping Pong effect running the action normally and

then running it again in Reverse mode.



Interval Action은 일정기간동안에 실행되는 Action 이다. 음... 이건만 가지고는 너무 뜬구름 잡는소리라서 멤버 변수와 멤버함수를 확인해보았습니다. 

멤버 변수로는
protected float elapsed;
private boolean firstTick;
을 가지고있더군요 

elapsed는 경과된,., 이니까 경과된시간. ...아~~~
CCFinteTimeAction 에 일정 시간이 있으니까 
그 일정 시간과 비교할 다른 참고 변수를 가진다는거죠 
그리고 멤버 함수를 보니 아니나 다를까 . 

CCFinteTimeAction에서 선언한. duration과 
CCIntervelAction 에서 선언한 elapsed을 비교하는 구문이 있었습니다. 
바로 요놈 입니다. 

public boolean isDone() {

        return (elapsed >= duration);

    }


참이면 stop가 호출 되겟고 아니면 step이 호출되겟죠ㅎ


  여기서 한가지 의문점은 이럴꺼면 왜 궅이 CCFinteTimeAction 가 CCIntervelAction 을 분리시켰냐에 대한 의문이 들더군요, 단지 변수 하나 추가하고 함수 오버라이딩 할꺼면 한번에 다하면 되지 왜 궅이 이렇게  귀찮게 해야 하나 라는거죠 
  이렇게 클래스 분리함으로써 얻을수 있는 장점은 무엇일까요? 이를 설명하기 위해서는CCFinteTimeAction 을 상속한 또 다른 클래스  CCInstantAction을 알면 해결될수 있을것이라 생각합니다. 

그럼 CCInstantAction 을 살펴보면

/** Instant actions are immediate actions. They don't have a duration like

the CCIntervalAction actions.

*/

즉시 실행되는 액션이고 CCIntervalAction처럼 duration을 가지지 않는다. 

추가된 멤버변수도 없습니다. 
오히려 생성자에서 

protected CCInstantAction() {

        super(0);

    } 

@Override

    public boolean isDone() {

        return true;

    }


    @Override

    public void step(float dt) {

        update(1.0f);

    }


    @Override

    public void update(float t) {

        // ignore

    }


자신의 부모클래스의 멤버변수인 duration의 값을 0로 줘버리더군요 이말은  실행하는 즉시 결과가 화면에 도출된다는것을 의미합니다. 함수 오버라이딩 해놓은걸보면. 
step 이  바로 1로써 업데이트 되어 버립니다.

음.  이렇게 살펴 보았지만 위의 의문점은 해결이 안되는군요 .
이럴꺼 전부  CCFinteTimeAction 과 CCIntervelAction 과 CCInstantAction 을 하나의 클래스로 만들어서 멤버 변수의 값만 바꿔주면 되지 않나? 라는 생각이 들더군요 . 

의문점을 해결하고자 했는데 오히여 더 복잡해지네요 . . ㄷㄷㄷ
이에 대해서 좀더 알아보고자 한다면. 다른 클래스들을 살펴보아야겟네요.  파고 들어갈수록 점점 이상해지네요 . ㅋㅋㅋ 일단 의문점은 남겨두고 갈께요. Action에 대해서 어느 정도 정리가 되면 이 의문점에 대해서 생각해보겟습니다.





혹시 까먹을지도 모르니 아래와 같이 체크해놓고 ㅎㅎ

Q.이럴꺼 전부  CCFinteTimeAction 과 CCIntervelAction 과 CCInstantAction 을 하나의 클래스로 만들어서 멤버 변수의 값만 바꿔주면 되지 않나? 





Posted by 수다쟁이증후군 :
CCAction 클래스 자체는 별의미 없어보입니다. 

멤버 변수가
public CCNode target;
private CCNode originalTarget
private int tag;

이렇게 3개밖에 없네요

타겟노드 와  구분자 tag

그럼 멤버 변수가 머 볼거 없으니 멤버 함수를 확인해 보니. 
Action이 한프레임동안 하는 일들을 알수 있었습니다. 
바로 아래와 같은데요. 

//! called before the action start. It will also set the target.
    public void start(CCNode aTarget) {
        originalTarget = target = aTarget;
    }

    //! called after the action has finished. It will set the 'target' to nil.
    //! IMPORTANT: You should never call "[action stop]" manually. Instead, use: "[target stopAction:action];"
    public void stop() {
        // target = null;
    }

    //! return YES if the action has finished
    public boolean isDone() {
        return true;
    }

    //! called every frame with it's delta time. DON'T override unless you know what you are doing.
    public abstract void step(float dt);

    //! called once per frame. time a value between 0 and 1
    //! For example: 
    //! * 0 means that the action just started
    //! * 0.5 means that the action is in the middle
    //! * 1 means that the action is over
    public abstract void update(float time);


멤버 함수별 상세한 설명은 안에 잘되어 있으니 
하나의 프레임동안 호출되는 함수들의 순서를 정리하겟습니다. 

바로 이렇습니다. 여기서 유추할수 있는건 이런 액션멤버변수들을 호출하는 무언가가 있다라는것이죠 일단 지금은 그정도로만 알고 있죠 무언가가 액션의 멤버 변수를 호출한다.그것도 체계적으로 말이죠 

 

CCAction은 아래 클래스로 확장 됩니다. 

CCFiniteTimeAction  
CCRepeatForever and CCSpeed

그럼 이 2가지 놈들과 CCAction의 관계를 볼까요?

CCFiniteTimeAction   과  CCAction의 관계입니다. 



CCRepeatForever  과 CCAction의 관계입니다. 


CCSpeed과 CCAction의 관계입니다.   

출처: http://www.cocos2d-iphone.org/api-ref/0.99.0/annotated.htm 


 보시다 시피 나머지 2개는 아직 알아 보지 않는 CCIntervelAction을 멤버로 가지고 있습니다.  그럼 
CCFiniteTimeAction  을 먼저 살펴보는게 맞을듯합니다. 


CCFiniteTimeAction  는 말그대로 한정된 시간을 가지는 액션입니다. 
클래스 설명을 보면

/** Base class actions that do have a finite time duration.

 Possible actions:

   - An action with a duration of 0 seconds

   - An action with a duration of 35.5 seconds

 Infitite time actions are valid

 */


 시간을 가지는액션의 기본클래스 입니다. 
0seconds 는 바로 CCNode 의 속성을 즉시 변경한다는 말이고 .
35.5 seconds는 CCNode의 속성을 35.5초 동안 변경한다는 말입니다.

CCAction의 멤버 변수외에  float duration이 추가 되었습니다. 
물론 이에 대한. set ,get 함수는 추가 되었구요.
하나 눈여겨 볼만 한것은.
멤버 한수로써 

public CCFiniteTimeAction reverse() {
        ccMacros.CCLOG(LOG_TAG, "Override me");
        return null;
 }

이 추가 되었다는 것입니다.  그리고 나서 자기를 상속한 클래스보고 오버라이딩 해라고 친절하게 말해 주세요 ㅎㅎㅎ 


이제 남은 것은 
CCRepeatForever and CCSpeed 요건데 위에서 보시다 시피 CCIntervelAction이 머하는건지 알수 있다면 좀더 이해가 빠를 것이라 생각됩니다. 

그래서 다음 강좌는  
CCIntervelAction 에 대해서 다루어 보겟습니다. 
Posted by 수다쟁이증후군 :