* - You can add MenuItem objects in runtime using addChild:
* - But the only accecpted children are MenuItem objects
*/
특징과 제한
- CCMenuItem 인스턴스를 넣고 싶은때 언제나 멤버로 넣을수 있다 .
- 다만. CCMenuItem 이나 이를 상속한 클래스만 을 넣을수 있다 .
그럼 이제 CCMenuItem에는 어떤것들이 있나 보겟습니다.
총 6개가 아래와 같이 있습니다.
CCMenuItemAtlasFont
CCMenuItemFont
CCMenuItemImage
CCMenuItemLabel
CCMenuItemSprite
CCMenuItemToggle
위에 이놈들은 직접적이든 간접적이든 CCMenuItem을 상속 받았습니다.
)
다만 요놈들끼리도 상속 구조를 이루는 부분들이 있는데 확인해보게습니다.
일단 CCMenuItem을 사용처에따라 분류해봅니다.
1.이미지 메뉴아이템을 만들때 :
CCMenuItemSplite 을 사용하세요
그리고 좀더 편하게 사용한다면
CCMenuitemImage 를 사용하세요( 파일 이름으로 바로 생성가능 -관련 강좌 클릭)
2.글자 메뉴아이템을 만들때 :
CCMenuItemLable를 사용하세요
그러나 다른 폰트및 사용자 폰트를 사용하려면
CCMenuitemFont 와 CCMenuItemAtlasFont 를 사용하세요
CCMenuitemFont는 디바이스 내장 폰트 사용하고
CCMenuItemAtlasFont 사용자 폰트를 사용합니다.
(CCMenuItemLable 을 이용하여 사용자 폰트도 만들수 있지만. 개인적인 생각으로 는 분명 특화된 클래스가 있는데 그걸 사용하지않고 다른걸 기본클래스를 사용한다는 것은 시간낭비적
요소가 있지 않나 싶습니다.물론 세부적인 컨트롤이 가능하다는 측면이 있지만 그런일은 별로
없을듯 합니다. )
3.메뉴아이템을에 여러가지 상태값을 넣고 변경하고자 한다면
CCMenuItemToggle을 사용하세요
위 관련내용중 CCMenuItemSplite와 CCMenuItemImage를 제외하고
다른 메뉴아이템은 클릭시에 기본액션은 글자확대=>복귀 이 있습니다.
진짜 상세히는 못다루었지만. 이제 어떤메뉴라도 충분히 다룰수 있지 않았나 합니다.
지금까지 전체 MenuTest관련 5강좌를 전부 읽고도
메뉴를 만들지 못하신다면 문의 주세요 만들어 드립니다. ㅎㅎㅎ
바로 CCMenuItemToggle입니다. 자자 가볼까요 ?
토글 말그대로 입니다. 2가지의 상태변화 입니다.
A => B , B => A
입니다. CCMenuItemToggle item1 =
CCMenuItemToggle.item(this, "menuCallback",
CCMenuItemFont.item("On"), CCMenuItemFont.item("Off")};
별거 없죠
첫번째 파라미터 타겟 CCNode
두번째 파라미터는 콜백함수
세번째와 네번째는 상태변화 될 MenuItem 입니다.
상태변화도리 MenuItem은 몇개든지 추가 될수 있습니다.
CCMenuItemFont.item("On"), CCMenuItemFont.item("Off"), CCMenuItemFont.item("On1"), CCMenuItemFont.item("On2"), CCMenuItemFont.item("On3"), CCMenuItemFont.item("On4"), CCMenuItemFont.item("On5"), CCMenuItemFont.item("On6"), CCMenuItemFont.item("On7"), CCMenuItemFont.item("On8"), CCMenuItemFont.item("On9")};
이렇게 말이죠 메뉴아이템은 콜백과 별도로
상태변화MenuItem들을 순차적으로 변화시켜줍니다. 맨 끝으로 변화 되면 다시 첫번째가 나타납니다. 한마디로 루프죠 .
다르게 추가 하는방법은
바로 아래에 나오는데요. CCMenuItemToggle item4 = CCMenuItemToggle.item(this, "menuCallback",
CCMenuItemFont.item("Off"));
ArrayList<CCMenuItemFont>
more_items = new ArrayList<CCMenuItemFont>();
alignMenusH(); }
생성자에서 만들었네요
CCMenuItemImage 를 이용해서 이미지버튼을 3개 만들고
각 버튼의 크기를 셋팅합니다.
첫번째 CCMenuItemImage는 원래 사이즈에서 가로 1.5배
두번째 CCMenuItemImage는 원래 사이즈에서 세로를 0.5배
세번째 CCMenuItemImage는 원래 사이즈에서 가로 0.5배
이버튼들을 Menu에 넣었습니다. 그리고 수평정렬 함수를 호출합니다. centeredMenu의 값은 ( 0 , 0 ) 입니다 앵커의값이죠
갤럭시 기준으로 하면 480 800 인니까 240 에 400 이 되겟네요
------------------2011년 9월 10일 추가 내용 TAG--------------------
제가 이부분을 깝빡 했네요
menu.setTag(kTagMenu); addChild(menu, 0, 100+i);
태그는 말그대로 꼬리표입니다.
안드로이드에서는 View클래스에 id 를 할당합니다.
그 아이디를 기반으로 R.java 클래스 변수로 등록되고 액티비티
어디에서든 접근 가능합니다.
그럼 cocos2d에 대한 구분자는 어떻게 할까요 ?
바로 TAG입니다
안드로이드 id는 유일한 값입니다 이는 어플리케이션 package에서 관리
하기때문입니다.
그럼 cocos2d에서는 tag는 어디서 관리할까요?
바로 자기 자신이 관리 합니다.
그럼 으로서 활용방법은 2가지 입니다.
Node의 독립성을 확보하기 위해 각기 고유 코드값으로 줄수도 있고
분류를 위한 비슷한 역활을 하는 Node들에서 공통의 값을 줄수도 있습니다.(2011년 9월 26일 수정)
바로 부모 CCNode에서 관리합니다.
결국 이말은 부모만 다르다면 같은 TAG 값을 가져도 됩니다. 이명제의 대우는 무엇일까요?
같은 부모를 가지는 CCNode는 서로 다른 값을 가져야 한다는 말과 같습니다. 즉 유니크 해야 한다는거죠 ㅎㅎㅎ
Tag에 대해서 간단히 살펴 보았습니다.
메뉴를 불러와서 하나는 CCMenu 에 있는 MenuItem 간의 간격이 을 결정합니다.
디폴트로 5가 삽입되어있구요 밑에는 40이라는 상수 값을 주었네요 . menu.setPosition(CGPoint.ccpAdd(p, CGPoint.ccp(0,30)));
menu.setPosition(CGPoint.ccpSub(p, CGPoint.ccp(0,30)));
그리고 위에는 센터에서 y좌표값이 +30 이니까 화면에서 위로 올라 가겟고
아래는 센터에서 30 내려 가는 것이니까 화면에서 내려 가겟네요 ^^;
menu.setOpacity((byte) 128); } opacity 는 불투명도는 나타내죠 그런데 255로 변화 시키니까 아에 안보이고
이벤트도 안먹네요 흠... 이벤트 안먹히고 이건 따로 한번 알아 볼께요
사라지는것 까지는 이해 했는데 이벤트라 ... 아시는분 댓글좀^^;;
publicvoid menuCallbackAlign (Object sender) {
alignedH = ! alignedH;
if( alignedH )
alignMenusH();
else
alignMenusV();
}
기건머 2말 할필요없죠 ^^
자 그럼 여기까지가 . Layer2엿습니다.
여기서 새롭게 알게 된거는
1.CCMenuItem 할 때 크기를 따로 지정한다
item1.setScaleX(1.5f);
2.CCNode 의 TAG
CCNode는 자식간의 구별과 접근 용이성을 높이기 위해 TAG을 할당한다. 입니다.
3.CCMenu 수직 수평 정렬할때 padding값을 주어서 간격을
조절한다. menu.alignItemsVertically(40);
menu.alignItemsHorizontally(40);
requestWindowFeature(Window.FEATURE_NO_TITLE);
==>타이틀바 를 삭제 합니다.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
==>상태바 (안테나 뜨는 부분을 삭제합니다)
mGLSurfaceView = new CCGLSurfaceView(this); setContentView(mGLSurfaceView); ==>CCGLSurfaceView 클래스 GLSurfaceView 를 상속합니다. 여기에 대해서 말할거리는 정말 많죠 그러나 일단은 성능 좋은 이미지뷰를 화면에
생성 한다 라고 만 알아둡시다 . 추후에 여기에 대해서 장기간에 걸쳐서 강좌를
진행해보겟습니다.
onCreate() 부분을 간단히 요약하자만 cocos2d를 사용하기 위해서
View 하나 생성 했다 입니다. 물론 전체 화면이니 나발이니 하는것은
하나의 옵션입니다. 이로써 준비는 끝났습니다. 실제 코드에 슬슬 들어 가보죠
주석이 참 친절하게 잘되어있네요 . CCDirector.sharedDirector().attachInView(mGLSurfaceView); 이전강좌에서 CCDirector의 개념을 잠시 언급한적이 있죠 감독이며 자혼자 뿐이라고
싱글스톤 입니다. CCDirecto 레퍼런스 변수 생성방법이 바로 요헐게
CCDirector.sharedDirector() 입니다. 그리고 난후에 위의 onCreate에서 생성했던 성능 좋은 이미지뷰를 감독에게 넘겨줍니다. 전권 위임입니다.
자그럼 프로그래머 입장에서 보면 감독을 한놈 정하고 그놈에서 전권을 맡긴 것이죠.
코드한줄에 주석이빠이 ㅎ. ㅎㅎ
CCDirector.sharedDirector().setLandscape(false);
이부분은 감독에서 세로모드로 영화를 찍어라고 하는겁니다
인자값이 true면 당연히 가로 16:9 와이드로 영화를 찍어라고 하는것이죠. 근데 막상 감독이라고 해놓고 보니 아직은 지혼자 할 줄 아는게 없네요 프로그래머가 일일이 지시해야 하고 에휴~~ 이래서 머리 좋은 시다바리를 둬야 한다는 거죠 . ㅎ 자자 각설하고
다음줄
CCDirector.sharedDirector().setDisplayFPS(true);
화면 귀퉁이 FPS를 숫자로 보여 줄것인가 말것인가를 감독에게 시킵니다. FPS는 초당 프레임수 초당 화면 갱신을 몇번하는가를 말합니다. 그러면 초당 몇번 보여라고 지정하는부분도 있겟죠 그게 바로 다음줄
CCDirector.sharedDirector().setAnimationInterval(1.0f / 60);
입니다. CCAction 기초강좌 에서도 보았듯이 cocos2d의 시간 단위는 1초입니다.
변수 타입은 float 입니다. 그러니까 1.0f는 1초 0.5f는 0.5초 입니다. 이를
60으로 나누었으니 초당 60번의 화면 갱신이 일어나게끔 한다는것입니다. 일반적인
에니메이션은 24프레임이고 디즈니가 36프레임인가로 알고 있는데 상당히 부드럽자나요 .
그것보다 더 부드럽게 움직이라고 하는겁니다. 실제 화면구동에서는 이보다 속도가 안나올수도있습니다 많이 내려갈때는 30프레임 까지 내려가더군요 . 그래도 상당히 아니 매우 빠른속도니까 화면의 대상은 부드럽게 움직입니다.
CCScene scene = CCScene.node();
드디어 이제 시작인가요 .ㅎ ㅎ 여기서 강좌끝내버리면 낚시겟죠 ㅎㅎ.
CCScene 인스턴스를 생성하는 방법입니다. 참쉽죠
CCScene.node();이렇게 클래스명적고 .node()라고 하면 되니까 ㅎ
이렇게 선언하면됩니다.
자기 이름도 영화관이면서 안에 1개짜리 영화관을 때려넣고 앞에 멀티플렉스라고 명명한
건물. 여기서도 동일하게 적용됩니다. CCLayer클래스인데 안에 멤버변수(ArryList)로 다른 CCLayer를 담을수 있는 이름도 거창한. CCMultiplexLayer 입니다.
그러고 보니까 안쪽에 레이어를 쳐담고 있죠 new로 생성해서요 .
" 어라 cocos2d에 Layer1()이란 클래스가 있었나 ?" 라는 궁긍증일어나겟죠
결론적으로 없습니다, 걍 다음 소스에서 도 나오겟지만. 예제 만든사람이 CCLaer클래스를 상속하여 만든것뿐입니다. 오해가 없으시길.
scene.addChild(layer, 0);
CCDirector.sharedDirector().runWithScene(scene);
어라 이제까지 우리가 만들어 놓은 걸 담고 있네요 . 이는 기본강좌 에도 나와 있지만. ^^ (거의 중간 광고 수준이네요 ㅋㅋㅋ 한번쯤 읽어 보라는 압력. ㄷㄷ )
CCDirector는 CCScene를 담을수 있고
CCSecen은 CCLayer를 담을수 있고
CCLayer는 CCSplite를 담을수 있습니다.
담는 방법은 위에 나와 있습니다.
scene.addChild(layer, 0);==>CCSecen은 CCLayer를 담을수 있고
CCDirector.sharedDirector().runWithScene(scene);==>CCDirector는 CCScene를 담을수 있고
입니다. add든 runWithScene든 결과는 담는 겁니다.
자이제 화면이 ON 되었습니다.
그럼 이제 화면이 어떻게 움직일까요? 우리가 보았듯이 이름만 거창한 멀플렉스레이어가 실제 우리 눈에 보이는 부분입니다.
그럼 이놈을 분석해보면 화면이 어떻게 돌아 가는지 알수 있겟죠 ㅎㅎ;
일단 중간 정리 한번하고 가죠 . OnCreate()에서 한일은
1.전체화면 만들기
2.성능좋은 이미지뷰 생성하기
OnStart()에서 한일은.
1. 감독을 만들어 성능 좋은이미지 뷰랑 연결해주기
2. 가로모드 세로모드 결정
3. FPS 정해주기
4. CCScene와 CCLayer를 생성
5. 그릇 순서에 따라 담기 .