티스토리 뷰
Cocos2d-x의 CCMenuItemImage를 생성할 때는 보통 normal image와 selected image를 넣어서 만들게 된다. 그러면 이 이미지 버튼이 down된 상태에 selected image를 보여주는 것이다. 문제는 이런 방식을 사용할 경우 selected image를 만들지 않을 경우 버튼이 클릭된 느낌을 내기 어렵다는 것이다. 그래서 이미지 한 장으로 이미지 버튼을 만들 때 흔히 사용하는 방법으로 버튼을 확대시키거나 축소시키는 액션을 취해준다. Cocos2d-x의 터치 시스템이 괴랄해서 따로 버튼을 만드는 것은 상당히 귀찮은 일인 것은 다들 동의할 것이다. 그래서 고민을 해봤는데, 그냥 CCMenuItemImage 클래스를 살짝 수정하면 해결이 될 것 같아서 한 번 해봤다. 해보니까 별로 어렵지 않아서 공유해본다.
CCMenuItemImage는 사실 CCMenuItemSprite를 상속받은 클래스이다. 그래서 CCMenuItemImage 클래스에는 클릭 관련 메소드가 없지만 CCMenuItemSprite에서는 찾을 수 있다. 바로 CCMenuItemSprite::selected와 CCMenuItemSprite::unselected 메소드이다. 이 클래스의 상속구조를 거슬러 올라가보면 CCMenuItem 클래스의 selected, unselected 메소드에서 클릭 관련 변수 값을 수정해주는 것을 알 수 있다.
void CCMenuItemSprite::selected()
{
CCMenuItem::selected();
if (m_pNormalImage)
{
if (m_pDisabledImage)
{
m_pDisabledImage->setVisible(false);
}
if (m_pSelectedImage)
{
m_pNormalImage->setVisible(false);
m_pSelectedImage->setVisible(true);
}
else
{
m_pNormalImage->setVisible(true);
this->runAction(CCScaleTo::create(0.1, 0.9));
}
}
}
여기서 살펴볼 점은 this->runAction 부분이다. 이게 내가 추가한 소스인데, selected 함수 내부에서 selected image가 없을 경우 수행되는 if statement에서 scale이 0.9가 되도록 하는 액션을 해주고 있음을 알 수 있다. 마찬가지로 unselected 메소드에서는 scale이 1이 되도록 하는 액션을 구동하면 이제 버튼이 클릭된 상태가 아닐 때 원 상태로 돌아오게 된다.
처음에는 이렇게 cocos2d-x 자체 소스를 수정했는데 생각해보니까 CCMenuItemImage를 상속받은 커스텀 클래스를 만들어도 괜찮을 것 같았다. 그래서 만들었다! 별건 없고 노드를 생성할 때 clicked action과 unclicked action을 넘겨주도록 했다.
#include "MyMenuItem.h"
MyMenuItemImage::~MyMenuItemImage()
{
_clickedAction->release();
_unclickedAction->release();
}
MyMenuItemImage * MyMenuItemImage::create(const char *normalImage,
CCAction *clickedAction,
CCAction *unclickedAction,
CCObject *target,
SEL_MenuHandler selector)
{
MyMenuItemImage *pRet = new MyMenuItemImage;
if( pRet && pRet->initWithNormalImage( normalImage, NULL, NULL, target, selector ) )
{
pRet->registerClickedAction(clickedAction);
pRet->registerUnClickedAction(unclickedAction);
pRet->autorelease();
return pRet;
}
return NULL;
}
void MyMenuItemImage::registerClickedAction(CCAction *clickedAction)
{
clickedAction->retain();
this->_clickedAction = clickedAction;
}
void MyMenuItemImage::registerUnClickedAction(CCAction *unclickedAction)
{
unclickedAction->retain();
this->_unclickedAction = unclickedAction;
}
void MyMenuItemImage::selected()
{
CCMenuItemImage::selected();
this->runAction( _clickedAction );
}
void MyMenuItemImage::unselected() {
CCMenuItemImage::unselected();
this->runAction( _unclickedAction );
}
소스가 쉬우니 직접 읽어보면 이해가 쉽게 될 것이다. 유용하게 사용하길!
'프로그래밍 > 게임 개발' 카테고리의 다른 글
[cocos2dx] Run-Time Check Failure #0 어쩌구 저쩌구 해결하기 (0) | 2014.01.16 |
---|---|
[cocos2dx] Lua binding - 커스텀 클래스를 만들어서 binding 하기 (0) | 2013.12.19 |
[cocos2dx] 2.2 버전의 lua binding으로 만든 간단한 게임 프로젝트 공유 (0) | 2013.12.03 |
[cocos2dx] XML과 JSON중 어떤 것을 선택해야 하는가? (2) | 2013.11.25 |
[cocos2dx] JSON을 활용한 스프라이트 애니메이션 클래스 제작 (0) | 2013.11.21 |
- Total
- Today
- Yesterday