티스토리 뷰

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

}


소스가 쉬우니 직접 읽어보면 이해가 쉽게 될 것이다. 유용하게 사용하길!



MyMenuItem.cpp


MyMenuItem.h


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday