메뉴관련 예제를 정리하고  마지막으로 총정리 해봅니다. 

CCMenu  클래스 설명입니다. 

/** A CCMenu
 * 
 * Features and Limitation:
 *  - 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강좌를 전부 읽고도 
메뉴를 만들지 못하신다면 문의 주세요 만들어 드립니다. ㅎㅎㅎ
 
 
 

 




 
Posted by 수다쟁이증후군 :

자자 거의 다와 가네요

이전 시간에는               

1.CCMenuItem 할 때 크기를 따로 지정한다
 item1.setScaleX(1.5f);

2.CCMenu 수직 수평 정렬할때 padding값을 주어서 간격을 
 조절한다. 

 
menu.alignItemsVertically(40);

 menu.alignItemsHorizontally(40);    

요거했네요 진짜 별거 없없죠 ㅎ
이번엔느 Layer3를 해보죠 이번에는 좀더 건질것이 많이 있기를 바라면서
전체 소스 한번 볼까요?

        

아 실망 스럽게도 메뉴 관련해서는 특이할만게 별로없고 다만 Action에 관한것 밖에 없에요 .            
두번째 강좌에서 이미  봤던내용의 반복입니다. 
CCAction 부분도 
기본개념 강좌 2
번째 강좌에서 다루었던내용이고  머 . .


CCJumpBy에대해서 상세하게 다루지 않았기에 간단히 정리 해봅시다.

CCIntervalAction jump = CCJumpBy.action(3.0f, CGPoint.ccp(400,0), 50, 4);

item2.runAction(                CCRepeatForever.action(CCSequence.actions(jump, jump.reverse())));
첫번째 파라미터는 시간
두번째 파라미터는 얼마만큼 이동할것 인가?
세번째 파라미터는 점프을 얼마만큼?
네번째 파라미터는 시간내에 몇번을 점프할것인가?
입니다. 

그리고 CCMenuItem 의 액션을 시행하는데
미리 지정한 점프액션과 그에 대한 역액션을 순서대로 무한반복해라 입니다.
진짜 별거 없죠 ㅎㅎ. 

콜백에서 참고할만 것이 있는가 보니 

disabledItem.setIsEnabled(!disabledItem.isEnabled());
disabledItem.stopAllActions(); 

요고 있네요 .
MenuItem 비 활성화와
해당 MenuItem의 액션을 정지 시키기
입니다.



그럼 Layer4로 바로 갈께요 .  아래는 전체 소스 보기 입니다.
 

오호 라 새로운것 하나 나왔습니다. 

바로 CCMenuItemToggle 입니다.  자자 가볼까요 ?
토글 말그대로 입니다. 2가지의 상태변화 입니다. 
A => B , B => A
입니다.  
CCMenuItemToggle item1 = CCMenuItemToggle.item(this,                                       "menuCallback",

                          CCMenuItemFont.item("On"),
                          CCMenuItemFont.item("Off")};
별거 없죠 
첫번째 파라미터 타겟 CCNode
두번째 파라미터는 콜백함수 
세번째와 네번째는 상태변화 될  MenuItem 입니다. 
상태변화도리 MenuItem은 몇개든지 추가 될수 있습니다. 

CCMenuItemToggle item1 = CCMenuItemToggle.item(this,                                       "menuCallback",

                          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>();

            more_items.add(CCMenuItemFont.item("33%"));

            more_items.add(CCMenuItemFont.item("66%"));

            more_items.add(CCMenuItemFont.item("100%"));
item4.getSubItemsRef().addAll(more_items); 

ArrayList에 추가 해서 한번에 할당하기 입니다.간단하죠 .

한가지 추가로 MenuItemToggle이 첫번째 로딩될때 나올 순서를 미리 정할수 도 있는데 그건 아래와 같습니다.  
item4.setSelectedIndex(2);
이로써 기본적인것은 되었구요 . 

하나 재미난것이 있던데 메뉴 정리할때

CCMenu menu = CCMenu.menu(title1, title2, item1, item2, title3, title4, item3, item4, back); // 9 items.

menu.alignItemsInColumns(new int[]{2, 2, 2, 2, 1}); 

첫번째 라인에 순서대로 2개배치하고
2번째 라인에 그다음 2개를 배치하고
3번째 라인에 그다음 2개를 배치하고 
....

마지막은 1개를 배치합니다. 
이런식으로 배치합니다.  

다됐네요
메뉴관련해서는 별다른 내용이 없네요 다만 MenuItem의 선언부분만 잘체크한다면 별다른 어려움없이 정리 될듯합니다.

이로써 한개의 예제를 끝냈는데요 아직 저도 미숙하고 글적는 솜씨도 부족해서
의도가 잘전달 안됐을것도 같네요 .
다음 예제는 이번에 글적으면서 부족했던점을 좀더 보완하여 체계적으로 적어도록
노력하겟습니다. 다음 강좌도 많이 봐주세요  






 

              

                

                   

Posted by 수다쟁이증후군 :
자 이번엔.menuTest.java 의 마지막 시간이 될듯합니다. 

Layer2 클래스에 대해서 알아보죠  

아래는 전체 소스 입니다. 

 
결과 물입니다.  


첫번째는 가로 정렬 
두번째는 about버튼을 눌렀을때 나타나는 화면입니다.

간단히 이야기 하자면 메뉴 2개 만들어서 가로 정렬 해보고 세로정렬 해봤습니다. 
그럼 일단 메뉴2개를 만들어보죠 

public static final int kTagMenu = 1;

public Layer2() {

   super();

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

         CCMenuItemImage item1 = CCMenuItemImage.item("btn-play-normal.png", "btn-play-selected.png", this, "menuCallbackBack");

         CCMenuItemImage item2 = CCMenuItemImage.item("btn-highscores-normal.png", "btn-highscores-selected.png", this, "menuCallbackOpacity");

         CCMenuItemImage item3 = CCMenuItemImage.item("btn-about-normal.png", "btn-about-selected.png", this, "menuCallbackAlign");

  item1.setScaleX(1.5f);

         item2.setScaleY(0.5f);

         item3.setScaleX(0.5f);

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

               menu.setTag(kTagMenu); 

               addChild(menu, 0, 100+i);

               centeredMenu = menu.getPosition();

        } 

     alignedH = true;

     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에 대해서 간단히 살펴 보았습니다.

헷살리는 분이 있으시면 댓글로^^;

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



자그럼 수평정렬 함수를 확인해보겟습니다.

public void alignMenusH() {

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

       CCMenu menu = (CCMenu) getChildByTag(100+i);

       menu.setPosition(centeredMenu);

       if(i==0) {

           // TIP: if no padding, padding = 5

           menu.alignItemsHorizontally();              

           final CGPoint p = menu.getPositionRef();

           menu.setPosition(CGPoint.ccpAdd(p, CGPoint.ccp(0,30)));

       } else {

           // TIP: but padding is configurable

           menu.alignItemsHorizontally(40);

           final CGPoint p = menu.getPositionRef();

           menu.setPosition(CGPoint.ccpSub(p, CGPoint.ccp(0,30)));

       }

   }
}

메뉴를 불러와서 하나는 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 내려 가는 것이니까 화면에서 내려 가겟네요 ^^;


수직정렬도 이와 거의 똑같습니다. 
 public void alignMenusV() {

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

       CCMenu menu = (CCMenu) getChildByTag(100+i);

       menu.setPosition(centeredMenu);

       if(i==0) {

           // TIP: if no padding, padding = 5

           menu.alignItemsVertically();              

           final CGPoint p = menu.getPositionRef();

           menu.setPosition(CGPoint.ccpAdd(p, CGPoint.ccp(100,0)));

       else {

           // TIP: but padding is configurable

           menu.alignItemsVertically(40);

           final CGPoint p = menu.getPositionRef();

           menu.setPosition(CGPoint.ccpSub(p, CGPoint.ccp(100,0)));

       }

   }
}

 이정도야 머 쉽죠이 ㅎ.ㅎ 

자 마지막으로  콜백에서 볼만한게 있는지 확인해볼까요?

public void menuCallbackBack (Object sender) {

     ((CCMultiplexLayer)getParent()).switchTo(0);

}
이거는 이미 한번 했고 레이서 순서 바꾸기 


public void menuCallbackOpacity (Object sender) {

     CCMenuItem item = (CCMenuItem)sender;

     CCMenu menu = (CCMenu)item.getParent();

     int opacity = menu.getOpacity();

     if (opacity == 128)

         menu.setOpacity((byte) 255);

     else

         menu.setOpacity((byte) 128);     
}
opacity 는 불투명도는 나타내죠 그런데 255로 변화 시키니까 아에 안보이고
이벤트도 안먹네요  흠... 이벤트 안먹히고 이건 따로 한번 알아 볼께요 
사라지는것 까지는 이해 했는데 이벤트라 ... 아시는분 댓글좀^^;; 

public void 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);

딸랑 요거 하나네요 .

Posted by 수다쟁이증후군 :
쏘스를 하나 하나 씹어 먹어 봅시다 . 
일단.  먼저 할것은 Menu 관련 입니다. 
경로는 org.cocos2d.tests 패키지에 MenuTest.class 입니다.  
 @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE); 

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

                WindowManager.LayoutParams.FLAG_FULLSCREEN);

 

        mGLSurfaceView = new CCGLSurfaceView(this);

        setContentView(mGLSurfaceView);

    }
 

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 하나 생성 했다 입니다. 물론 전체 화면이니 나발이니 하는것은
하나의 옵션입니다. 이로써 준비는 끝났습니다. 실제 코드에 슬슬 들어 가보죠  

다음 라이프 싸이클에 따라 

@Override

    public void onStart() {

        super.onStart(); 

        // attach the OpenGL view to a window

        CCDirector.sharedDirector().attachInView(mGLSurfaceView); 

        // set landscape mode

        CCDirector.sharedDirector().setLandscape(false); 

        // show FPS

        CCDirector.sharedDirector().setDisplayFPS(true); 

        // frames per second

        CCDirector.sharedDirector().setAnimationInterval(1.0f / 60); 

        CCScene scene = CCScene.node(); 

        CCMultiplexLayer layer = CCMultiplexLayer.node(new Layer1(),

                                    new Layer2(), new Layer3(), new Layer4());

        scene.addChild(layer, 0);

        CCDirector.sharedDirector().runWithScene(scene);

    }

주석이 참 친절하게 잘되어있네요 . 
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()라고 하면 되니까 ㅎ 
이렇게 선언하면됩니다. 


CCMultiplexLayer layer = CCMultiplexLayer.node(new Layer1(),

                            new Layer2(), new Layer3(), newLayer4());

입니다. 레이어 선언이네요 CCLayer를 상속한  CCMultiplexLyer
이름도 거창한 멀티플렉스 전부 아시죠 멀티플렉스영화관 영화관은 영화관인데 기본의 상영관이 1개인 영화관은 한건물에 때려넣은 영화관!

자기 이름도 영화관이면서 안에 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. 그릇 순서에 따라 담기 . 

자 ~~ 기본적인 것 정리는 다됐고  슬슬 또 진행해봅시다.


글중 에 잘못된 부분있다면 이야기 해주세요; ㅎㅎ 

Posted by 수다쟁이증후군 :