MenuItemFont는 스프라이트처럼 하나하나를 레이어에 추가시키는게 아니라, 만들어둔 아이템들을 'Menu'라는 클래스에 추가하여 생성한 뒤, 해당 메뉴를 레이어에 추가하는 것임.
즉, '스프라이트-레이어' 의 관계가 메뉴에서 '메뉴아이템-메뉴' 의 관계와 유사함.
auto item_01 = MenuItemFont::create("Play"); //play 아이템 생성
auto item_02 = MenuItemFont::create("Quit"); //quit 아이템 생성
auto menu = Menu::create(item_01, item_02, NULL); //두개의 아이템을 추가한 메뉴 생성
//NULL은 더이상 추가할 아이템이 없다는 것을 알려주는 역할
menu->alignItemsVertically(); //아이템들을 수직으로 자동 정렬
//menu->alignItemsVerticallyWithPadding(20);
//이렇게 패딩을 통해 아이템들 사이에 빈 공간을 채워서 여유를 줄 수 있다.
//이렇게 정렬을 안해주면, 두 아이템이 기본값으로 추가됐기때문에 겹치게 나옴
this->addChild(menu); //아이템이 아닌 메뉴를 레이어에 추가
+ 메뉴/메뉴 아이템의 기본 위치값(좌표/앵커포인트)
+ 메뉴/메뉴 아이템의 기본 위치값(좌표/앵커포인트)
메뉴 아이템의 기본 AnchorPoint는 (0.5, 0.5), 기본 위치는 (0, 0)
메뉴의 기본 AnchorPoint는 (0, 0), 기본 위치는 화면의 정중앙
메뉴 아이템 클릭시 동작하게 만드는 함수 추가
void playCallback(Ref* sender);
void quitCallback(Ref* sender);
+ Ref* sender란?
+Ref* sender란 ?
Ref(Reference)는 Node / Vector 등의 부모가 되는, cocos의 최상위 클래스
Menu의 부모 클래스는 Node, 이 Node의 부모클래스가 바로 Ref이다.
즉, 해당 노드의 포인터를 넘기는 것이라 보면 된다.
위의 아무 동작 안하는 메뉴들 중, play를 수정해서 클릭시 동작하게끔 함수를 바꾼다.
auto item_01 = MenuItemFont::create("Play", CC_CALLBACK_1(HelloWorld::playCallback, this));
//this는 타겟. 여기서는 playCallback이 있는 HelloWorld가 된다.
//이렇게 바꿔줌을 통해, play를 클릭하면 playCallback함수가 호출된다.
//playCallback함수의 호출과 동시에 item_01자기 자신이 함수의 파라미터로 넘어간다.
//아이템에 해당된 함수는 클릭(터치)을 눌렀다가 뗄 시에 호출된다.
+ CC_CALLBACK_1이란?( CC_CALLBACK_n )
+ CC_CALLBACK_1이란?( CC_CALLBACK_n )
이 행동을 통해 실행되는 함수의 파라미터 n개를 알아서 처리해주는 기능
여기서는 CC_CALLBACK_1을 통해서 클릭을 받은 본인(item)이 호출 함수의 파라미터로 넘어가게 됨.
MenuItemFont는 말 그대로 font만 직접 입력하여 사용하는 것이기 때문에 다양한 활용도가 없다.
그래서 대신에 MenuItemLabel을 사용하면, 라벨을 이용하여 메뉴를 구성할 수 있다.
//라벨 아이템 생성
auto label_01 = Label::createWithBMFont("west_england-64.fnt", "PLAY");
auto item_01 = MenuItemLabel::create(label_01, CC_CALLBACK_1(HelloWorld::playCallback, this));
//메뉴에 추가하는 건 동일함
+메뉴별 callback을 menuCallback하나로 묶은 코드
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
auto label_01 = Label::createWithBMFont("west_england-64.fnt", "PLAY");
auto item_01 = MenuItemLabel::create(label_01, CC_CALLBACK_1(HelloWorld::menuCallback, this));
item_01->setTag(1);
auto label_02 = Label::createWithBMFont("west_england-64.fnt", "HELP");
auto item_02 = MenuItemLabel::create(label_02, CC_CALLBACK_1(HelloWorld::menuCallback, this));
item_02->setTag(2);
auto label_03 = Label::createWithBMFont("west_england-64.fnt", "OPTION");
auto item_03 = MenuItemLabel::create(label_03, CC_CALLBACK_1(HelloWorld::menuCallback, this));
item_03->setTag(3);
auto label_04 = Label::createWithBMFont("west_england-64.fnt", "QUIT");
auto item_04 = MenuItemLabel::create(label_04, CC_CALLBACK_1(HelloWorld::menuCallback, this));
item_04->setTag(4);
auto menu = Menu::create(item_01, item_02, item_03, item_04, NULL); //두개의 아이템을 추가한 메뉴 생성
menu->alignItemsVerticallyWithPadding(20);
this->addChild(menu);
return true;
}
void HelloWorld::menuCallback(Ref* sender)
{
auto item = (MenuItemLabel*)sender;
switch (item->getTag())
{
case 1:
CCLOG("PLAY");
break;
case 2:
CCLOG("HELP");
break;
case 3:
CCLOG("OPTION");
break;
case 4:
CCLOG("QUIT");
break;
default:
CCLOG("INVALID!");
break;
}
}