티스토리 뷰

메뉴를 출력하는 방법에는 폰트, 이미지, 레이블 방식이 있습니다. 그리고 버튼의 종류는 일반 버튼과 토글 버튼이 있으며 메뉴의 위치에 대해서 간단히 설명 드리겠습니다.




아래는 대략적인 설명입니다.


- 폰트 : 폰트로 메뉴를 생성하는 방식으로 기본적으로 토글시 글씨가 커지는 효과가 있습니다.

- 레이블 : 레이블을 이용한 메뉴 생성 방식으로 폰트와 거의똑같다고 볼수 있지만 크기 색상 등을 수정할 수 있습니다.

- 이미지 : 이미지를 이용한 메뉴 버튼을 만드는 형식입니다.

- Splite: 이미지를 앞에서 배운 Splite 로 로드후 이미지로 만드는 방식입니다.

- 토글 : 토글이란 글씨를 클릭 했을 때(클릭 상태) 변화가 일어나는 것을 말합니다. 간단히 말하면 스위치(?) 와 같다고 생각하시면 됩니다.

-메뉴 위치에 대한 기본적인 상식


1. 폰트 메뉴


 우선 폰트를 이용한 메뉴 입니다. header 에는 메뉴를 눌럿을때 발생할 함수인 menuCallback 을  추가해 주도록 합니다.

file : HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();

    void menuCallback(cocos2d::Ref* pSender);
    
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

그리고 이제 HelloWorldScene.cpp 에는 메뉴 를 생성하는 함수 및 메뉴를 눌럿을때 발생할 함수를 만들어 주시면 됩니다.

폰트를 이용한 메뉴에서는 MenuItemFont::create 를 이용하며 함수 내부에는 메뉴에 사용될 글씨를 그냥 넣어 주시면됩니다.


#include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    
    auto item_1 = MenuItemFont::create("Play" , CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto item_2 = MenuItemFont::create("Score" , CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto item_3 = MenuItemFont::create("exit" , CC_CALLBACK_1(HelloWorld::menuCallback, this));
    
    auto menu = Menu::create(item_1, item_2, item_3, NULL);
    menu->alignItemsVertically();
    this->addChild(menu);

    return true;
}


void HelloWorld::menuCallback(cocos2d::Ref* pSender)
{
    CCLOG("menuCallback");
}

아래는 폰트를 이용한 메뉴의 출력화면



아래는 메뉴를 클릭했을때 발생한 CCLOG("menuCallback") 입니다.





2. 레이블 버튼 메뉴


 레이블을 이용한 버튼 메뉴는 위의 폰트와 비슷하지만 다른점은 폰트의 설정을 레이블의 형태로 불러오기 때문에 조정이 가능하다는 것입니다. 방법은 간단합니다 앞에서 배운 Label 을 만든 후 MenuItemLabel 로 메뉴 아이템을 생성 후 사용하는 방식입니다.


bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    
    auto btnLable_1 = Label::createWithSystemFont("NewGame", "Airal", 50);
    auto btnLable_2 = Label::createWithSystemFont("Load", "Airal", 30);
    auto btnLable_3 = Label::createWithSystemFont("About", "Airal", 20);
    auto btnLable_4 = Label::createWithSystemFont("Exit", "Airal", 10);
    
    auto mItem_1 = MenuItemLabel::create(btnLable_1, CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto mItem_2 = MenuItemLabel::create(btnLable_2, CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto mItem_3 = MenuItemLabel::create(btnLable_3, CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto mItem_4 = MenuItemLabel::create(btnLable_4, CC_CALLBACK_1(HelloWorld::menuCallback, this));
    
    
    auto menu = Menu::create(mItem_1,mItem_2,mItem_3,mItem_4,NULL);
    
    menu->alignItemsVertically();
    this->addChild(menu);

    return true;
}


아래는 결과 입니다. 레이블의 폰트 사이즈를 조절 후 출력한 화면입니다.



3. 이미지 버튼 메뉴


이미지를 이용하여 만드는 버튼입니다. 이미지 버튼의 장점은 마음대로 예쁘게 꾸밀수 있다는것 입니다.

일단 이번 예제에서 사용하는 이미지는 아래의 2개 입니다.


StartGame.zip






일단 프로젝트에 이미지를 입혀 주셨다는 가정하에 ( IOS는 폴더에 넣더라도 레퍼런스에 카피해주셔야 합니다. )


bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    
    auto item_1 = MenuItemImage::create("start_on.png" , "start_off.png", "start_off.png", CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto item_2 = MenuItemImage::create("start_on.png" , "start_off.png", "start_off.png", CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto item_3 = MenuItemImage::create("start_on.png" , "start_off.png", "start_off.png", CC_CALLBACK_1(HelloWorld::menuCallback, this));
    
    
    auto menu = Menu::create(item_1, item_2, item_3, NULL);
    
    item_1->setEnabled(false);
    
    menu->alignItemsVertically();
    this->addChild(menu);

    return true;
}


void HelloWorld::menuCallback(cocos2d::Ref* pSender)
{
    CCLOG("이미지 버튼 콜!");
}

코드의 경우 기본적으로 MenuItemImage 에 각각 상태의 이미지를 3개 지정해주고  함수를 지정하는 방식입니다. 이미지는 각각 순서대로 Nornal(평소) , Selected(클릭시), Disabled(사용불가) 입니다. 또한 item_1 의 사용을 false 로 만들어 주었기 때문에 아래의 결과에서 1번 버튼의 결과가 false 인것을 알수 있습니다.


아래의 스삿에서 1번 버튼은 Disabled 된 상태 입니다.





아래의 스샷에서는 3번 버튼을 누를 상태에서 찍었습니다. 말그대로 3번 버튼이 selected 된 상태임을 뜻합니다.




4. Sprite 를 이용한 메뉴


 앞에서 배웠던 Sprite 를 이용해 이미지를 불러온 후 메뉴 아이템으로 이용하는 방법입니다. Label 이 폰트의 속성을 변경 할수 있다면 Sprite 는 이미지의 속성을 변경우 사용할수 있다는 점에서 Label 과 비슷하다고 보시면 됩니다.


bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    
    auto btnStart_on_1 = Sprite::create("start_on.png");
    auto btnStart_off_1 = Sprite::create("start_off.png");

    
    auto btnStart_on_2 = Sprite::create("start_on.png");
    auto btnStart_off_2 = Sprite::create("start_off.png");
    btnStart_off_2->setScale(0.6);


    auto btnStart_on_3 = Sprite::create("start_on.png");
    auto btnStart_off_3 = Sprite::create("start_off.png");
    btnStart_on_3->setScale(0.4);
    
    auto mItem_1 = MenuItemSprite::create(btnStart_on_1,btnStart_off_1, CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto mItem_2 = MenuItemSprite::create(btnStart_on_2,btnStart_off_2, CC_CALLBACK_1(HelloWorld::menuCallback, this));
    auto mItem_3 = MenuItemSprite::create(btnStart_on_3,btnStart_off_3, CC_CALLBACK_1(HelloWorld::menuCallback, this));
    
    
    auto menu = Menu::create(mItem_1, mItem_2, mItem_3, NULL);
    
    
    
    menu->alignItemsVertically();
    this->addChild(menu);

    return true;
}

위의 코드에서 btnStart_off_2 의 크기를 60%로 btnStart_on_3 을 40%로 줄였습니다. 그리고 아래는 결과 입니다.

2번 버튼의 경우 off 로 만들기 위해 누른 상태에서 스샷을 찍어 보았습니다.




5. 토글


토글 메뉴를 만드는 방법입니다. 토글은 위에서도 설명했다시피 터치 할때마다 속성이 변하는 것을 말합니다. ( 2개를 지정 후 교차로 나오게함 ) => 간단히 말하면 아래와 같은 스위치 라고 이해하시면 됩니다.


귀차니즘이 발동된 관계로 위의 코드를 수정만 하였습니다.

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    
    auto btnStart_on_1 = Sprite::create("start_on.png");
    auto btnStart_off_1 = Sprite::create("start_off.png");

    
    auto btnStart_on_2 = Sprite::create("start_on.png");
    auto btnStart_off_2 = Sprite::create("start_off.png");
    btnStart_on_2->setScale(0.5);
    btnStart_off_2->setScale(0.5);

    auto mItem_1 = MenuItemSprite::create(btnStart_on_1,btnStart_off_1);
    auto mItem_2 = MenuItemSprite::create(btnStart_on_2,btnStart_off_2);
    
    auto tItem_1 = MenuItemToggle::createWithCallback(CC_CALLBACK_1(HelloWorld::menuCallback, this) , mItem_1, mItem_2, NULL);
    auto mItem_3 = MenuItemImage::create("start_on.png", "start_off.png", CC_CALLBACK_1(HelloWorld::menuCallback, this));
    
    auto menu = Menu::create(tItem_1, mItem_3, NULL);
    
    menu->alignItemsVertically();
    this->addChild(menu);

    return true;
}

그리고 아래는 결과 입니다.


처음에는 같은 버튼이 나오지만



아래는 제가 터치를 하고 있는 것이 아닌 한번씩 터치한 상태입니다. 2번 버튼의 경우 일반 버튼과 같이 selected 상태에서 normal 로 돌아 갔지만 1번 버튼의 경우 버튼이 변한것을 확인하실수 있으실 것 입니다.



5. 메뉴의 위치 에 대한 기본적인 상식


1. 메뉴는 위치 지정을 하지 않을 경우 화면의 중앙에 기본적으로 위치하게 된다.


MenuItem : 메뉴 안에 들어가는 아이템 의 기본위치

 AnchorPoint

 (0.5, 0.5)

 Position

 (0,0)


Menu : 화면에 출력되는 MenuItem 의 집합

 AnchorPoint

 (0,0)

 Position

 (윈도우 사이즈 가로 /2, 윈도우 사이즈 높이 /2) 


대충 설명을 드리자면

MenuItem 의 경우 기본적으로 중앙 정렬 그리고 좌하단을 기준으로 배치됩니다.

그리고

Menu 의 경우 좌하단을 기준으로 화면의 중앙에 위치하게 됩니다.


주의를 드리자면 UI 를 만드실때 절대값으로 UI의 위치를 판단하실때는 화면의 크기를 고려하셔서 위치를 만들어 주셔야 합니다.


2. alignItems 를 이용한 가로, 세로 정렬


그리고 위의 예제들에서도 사용한 가로 정렬, 세로 정렬 함수가 있습니다.

 alignItemsVertically()

 세로 정렬

 alignItemsHorizontally()

 가로 정렬 


그리고 위의 가로 정렬과 세로 정렬은 WithPadding 이라는 함수로 간격을 조절해 주실 수 있습니다.


 alignItemsVerticallyWithPadding()

  세로 정렬의 간격 조절

 alignItemsHorizontallyWithPadding()

  가로 정렬의 간격 조절


사용 예제를 대충 보자면 아래와 같습니다.


menu->alignItemsHorizontally()
menu->alignItemsHorizontallyWithPadding(10); // float


즐거운 게임 개발 되시기 바랍니다.


공유하기 링크
댓글