游戏很多地方都需要用到按钮,比如开始,退出等。cocos2d-x引擎封装有CCMenu这样一个类,可以很轻松的实现按钮的效果。其中包括了
CCMenuItemSprite 精灵按钮,
CCMenuItemImage 图片按钮,
CCMenuItemLabel label按钮
。。。。
具体的用法推荐自己去看看,很好用。(
CCMenu的用法)
不过CCMenu的优先级太高(-128),在很多的地方比如弹出层会阻止事件传递,并且按钮效果单一,有特殊需求的时候会显得鸡肋,那么,我们就可以封装一个自己的按钮精灵类。
封装按钮类,最主要的还是回调函数的处理,我们可以参照引擎提供的CCMenuItemSprite的构造方法来传递回调。先看它的构造方法:
CCMenuItemSprite * item = CCMenuItemSprite::create(normal, selected, this, menu_selector(Test::callback));
normal,selected 都是图片路径,前者为默认状态的图片,后者为选中状态图片
this为事件执行者,menu_select后面带上回调函数,callback为点击执行的函数,注意其参数为CCObject
那么我们的按钮构造函数也可以这样写。。。
先建立一个类,MyButton继承CCSprite(也可以直接继承CCNode)。我们这个按钮要有点击事件,那么肯定要继承
CCTouchDelegate。先看头文件代码:
#ifndef __MYBUTTON_SPRITE_H__
#define __MYBUTTON_SPRITE_H__
#include <cocos2d.h>
USING_NS_CC;
class MyButtonSprite : public CCSprite, public CCTargetedTouchDelegate
{
public:
virtual void onEnter();
virtual void onExit();
virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual bool init();
static MyButtonSprite* create(const char*, CCObject*, SEL_MenuHandler, SEL_MenuHandler);
//初始化按钮回调事件
virtual bool initTag(CCObject* ,SEL_MenuHandler ,SEL_MenuHandler);
public:
CCObject* m_pListerTag;
SEL_MenuHandler m_pSelectorDown; //点击按钮
SEL_MenuHandler m_pSelectorUp; //点击结束
bool m_bTouch;
//移动的偏移量
float m_fPetMove;
};
#endif
#include "MyButton.h"
MyButtonSprite* MyButtonSprite::create(const char* img)
{
MyButtonSprite* button = new MyButtonSprite();
if (button && button->init() && button->initWithFile(img))
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>button->autorelease();
<span style="white-space:pre"> </span>return button;
}
CC_SAFE_DELETE(button);
return NULL;
}
MyButtonSprite* MyButtonSprite::create(const char* img, CCObject* target, SEL_MenuHandler selectorDown, SEL_MenuHandler selectorUp)
{
MyButtonSprite* button = new MyButtonSprite();
if (button && button->init() && button->initTag(target,selectorDown,selectorUp)&& button->initWithFile(img) )
{
<span style="white-space:pre"> </span>button->autorelease();
<span style="white-space:pre"> </span>return button;
<span style="white-space:pre"> </span>}
CC_SAFE_DELETE(button);
return NULL;
}
bool MyButtonSprite::init()
{
if (!CCSprite::init())
{
return false;
}
m_fPetMove = 0;
m_bTouch = false;
return true ;
}
bool MyButtonSprite::initTag(CCObject* ob ,SEL_MenuHandler selectorDown,SEL_MenuHandler selectorUp)
{
m_pListerTag = ob;
m_pSelectorDown = selectorDown;
m_pSelectorUp = selectorUp;
return true;
}
void MyButtonSprite::onEnter()
{
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,1, true);
CCSprite::onEnter();
}
void MyButtonSprite::onExit()
{
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
CCSprite::onExit();
}
bool MyButtonSprite::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
CCPoint touchPos = touch->getLocation();
CCPoint realPos = this->getParent()->convertToNodeSpace(touchPos);
if (this->boundingBox().containsPoint(realPos))
{
ccColor3B color = this->getColor();
this -> setColor(ccc3(color.r/2,color.g/2,color.b/2));
m_bTouch = false;
if (m_pListerTag && m_pSelectorDown)
{
(m_pListerTag->*m_pSelectorDown)(this);
}
return true;
}
return false;
}
void MyButtonSprite::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
CCPoint touchPos = pTouch->getLocation();
CCPoint presPos = pTouch->getPreviousLocation();
if (this->boundingBox().containsPoint(presPos))
{
m_bTouch = false;
}else
{
m_bTouch = true;
return;
}
}
void MyButtonSprite::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
ccColor3B color = this->getColor();
this -> setColor(ccc3(color.r*2,color.g*2,color.b*2));
if (m_bTouch)
{
return;
}
if (m_pListerTag && m_pSelectorUp)
{
(m_pListerTag->*m_pSelectorUp)(this);
}
}