cocos2d-x下自己实现的一个button类,名字叫: TTButton
代码如下:
#include <iostream> #include "cocos2d.h" #include "cocos-ext.h" USING_NS_CC; USING_NS_CC_EXT; #include "ClientDefine.h" static const GLchar* pszGrayModeFragSource = "#ifdef GL_ES \n \ precision mediump float; \n \ #endif \n \ uniform sampler2D u_texture; \n \ varying vec2 v_texCoord; \n \ varying vec4 v_fragmentColor; \n \ void main(void) \n \ { \n \ // Convert to greyscale using NTSC weightings \n \ vec4 col = texture2D(u_texture, v_texCoord); \n \ float grey = dot(col.rgb, vec3(0.299, 0.587, 0.114)); \n \ gl_FragColor = vec4(grey, grey, grey, col.a); \n \ }"; void setSpriteGray(CCNode *pNode, bool isGray); typedef enum _BTN_STATE { BTN_STATE_UNSET = -1, BTN_STATE_NORMAL = 0, BTN_STATE_PRESS = 1, BTN_STATE_DISABLE = 2, } BTN_STATE; class TTButton :public CCLayer { public: TTButton(); ~TTButton(); bool initWithImages(std::string strNormal, std::string strSel , std::string strDisable ); bool initWithImage(std::string strNormal); bool initWithImages(std::string strNormal, std::string strSel , std::string strDisable , CCSize rectSize); bool initWithImage(std::string strNormal, CCSize rectSize); //更新某种状态下的图像 void upDateImageForState(BTN_STATE btnState , CCTexture2D *texture); static TTButton * createWithImage(std::string strNormal); static TTButton * createWithImages(std::string strNormal, std::string strSel , std::string strDisable ); static TTButton * createWithImage(std::string strNormal, CCSize rectSize); static TTButton * createWithImages(std::string strNormal, std::string strSel , std::string strDisable , CCSize rectSize); //设置 颜色 void setColorForState(BTN_STATE btnState, ccColor3B color); //更新状态UI void upDateStatusUI(); //设置选中状态 void setSelected(); //设置非选中状态 void setUnSelected(); //设置是否是disable状态 void setIsDisable(bool bDisabel); //获得当前状态 BTN_STATE getCurState(); //添加 处理handle void addTouchupInsideHandle(CCNode * target , SEL_CallFuncO selector); //判断是否是点击在有效区域 bool isTouchInvalidated(CCTouch* touch); virtual void onEnter(); virtual void onExit(); virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event); virtual void ccTouchEnded(CCTouch* touch, CCEvent* event); virtual void ccTouchCancelled(CCTouch *touch, CCEvent* event); virtual void ccTouchMoved(CCTouch* touch, CCEvent* event); public: BTN_STATE m_btnState; CCSprite * m_normalSprite; CCSprite * m_pressedSprite; CCSprite * m_disableSprite; CCScale9Sprite * m_normalScaleSprite; CCScale9Sprite * m_pressedScaleSprite; CCScale9Sprite * m_disableScaleSprite; CC_SYNTHESIZE(bool, m_bSelected, IsSelected); CC_SYNTHESIZE(bool, m_bDisabled, IsDisabled); CC_SYNTHESIZE(SEL_CallFuncO, m_touchupInsideSelector, TouchupSelector); CC_SYNTHESIZE(CCNode *, m_target, Target); CC_SYNTHESIZE_RETAIN(CCObject *, m_saveObj, SaveObj); };
#include "TTButton.h" void setSpriteGray(CCNode *pNode, bool isGray) { if(isGray) { CCGLProgram *pProgram = CCShaderCache::sharedShaderCache()->programForKey("GrayEffect"); if(!pProgram) { pProgram = new CCGLProgram(); pProgram->autorelease(); pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, pszGrayModeFragSource); pProgram->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position); pProgram->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color); pProgram->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords); pProgram->link(); CHECK_GL_ERROR_DEBUG(); pProgram->updateUniforms(); CHECK_GL_ERROR_DEBUG(); CCShaderCache::sharedShaderCache()->addProgram(pProgram, "GrayEffect"); } pNode->setShaderProgram(pProgram); CHECK_GL_ERROR_DEBUG(); } else { //CCSprite pNode->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor)); } } TTButton::TTButton() { //让调用 registerWithTouchDispatcher 函数 m_bTouchEnabled = true; m_bSelected = false; m_bDisabled = false; m_btnState = BTN_STATE_UNSET; m_normalSprite = NULL; m_pressedSprite = NULL; m_disableSprite = NULL; m_normalScaleSprite = NULL; m_pressedScaleSprite = NULL; m_disableScaleSprite = NULL; m_saveObj = NULL; m_touchupInsideSelector = NULL; } TTButton::~TTButton() { } bool TTButton:: initWithImages(std::string strNormal, std::string strSel , std::string strDisable , CCSize rectSize) { if (strNormal.empty() ) { return false; } //normal CCSpriteFrame * normalFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strNormal.c_str()); if (normalFrame ) { m_normalScaleSprite = CCScale9Sprite::createWithSpriteFrame(normalFrame); } if (m_normalScaleSprite == NULL) { m_normalScaleSprite = CCScale9Sprite::create(strNormal.c_str()); } if (m_normalScaleSprite == NULL) { return false; } else { m_normalScaleSprite->setContentSize(rectSize); m_normalScaleSprite->setAnchorPoint(CCPointZero); m_normalScaleSprite->setPosition(CCPointZero); this->addChild(m_normalScaleSprite); //set contentSize this->setContentSize(rectSize ); } //sel if ( strSel.empty() ) { CCSpriteFrame * normalFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strNormal.c_str()); if (normalFrame ) { m_pressedScaleSprite = CCScale9Sprite::createWithSpriteFrame(normalFrame); } if (m_pressedScaleSprite == NULL) { m_pressedScaleSprite = CCScale9Sprite::create(strNormal.c_str()); } } else { CCSpriteFrame * selFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strSel.c_str()); if (selFrame ) { m_pressedScaleSprite = CCScale9Sprite::createWithSpriteFrame(selFrame); } if (m_pressedScaleSprite == NULL) { m_pressedScaleSprite = CCScale9Sprite::create(strSel.c_str()); } } if (m_pressedScaleSprite ) { m_pressedScaleSprite->setContentSize(rectSize); m_pressedScaleSprite->setAnchorPoint(CCPointZero); m_pressedScaleSprite->setPosition(CCPointZero); this->addChild(m_pressedScaleSprite); } //disabel if (strDisable.empty() ) { CCSpriteFrame * normalFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strNormal.c_str()); if (normalFrame ) { m_disableScaleSprite = CCScale9Sprite::createWithSpriteFrame(normalFrame); } if (m_disableScaleSprite == NULL) { m_disableScaleSprite = CCScale9Sprite::create(strNormal.c_str()); } //如果是用 normal处理的,那么灰化 if (m_disableScaleSprite) { setSpriteGray(m_disableScaleSprite, true); } } else { CCSpriteFrame * disableFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strDisable.c_str()); if (disableFrame ) { m_disableScaleSprite = CCScale9Sprite::createWithSpriteFrame(disableFrame); } if (m_disableScaleSprite == NULL) { m_disableScaleSprite = CCScale9Sprite::create(strDisable.c_str()); } } if (m_disableScaleSprite) { m_disableScaleSprite->setContentSize(rectSize); m_disableScaleSprite->setAnchorPoint(CCPointZero); m_disableScaleSprite->setPosition(CCPointZero); this->addChild(m_disableScaleSprite); } //显示正常状态 this->setUnSelected(); return true; } bool TTButton::initWithImage(std::string strNormal, CCSize rectSize) { return this->initWithImages(strNormal,"","", rectSize); } bool TTButton::initWithImage(std::string strNormal) { return this->initWithImages(strNormal, "", ""); } bool TTButton::initWithImages(std::string strNormal, std::string strSel , std::string strDisable ) { if (strNormal.empty() ) { return false; } //normal CCSpriteFrame * normalFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strNormal.c_str()); if (normalFrame ) { m_normalSprite = CCSprite::createWithSpriteFrame(normalFrame); } if (m_normalSprite == NULL) { m_normalSprite = CCSprite::create(strNormal.c_str()); } if (m_normalSprite == NULL) { return false; } else { m_normalSprite->setAnchorPoint(CCPointZero); m_normalSprite->setPosition(CCPointZero); this->addChild(m_normalSprite); //set contentSize this->setContentSize(m_normalSprite->getContentSize() ); } //sel if ( strSel.empty() ) { CCSpriteFrame * normalFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strNormal.c_str()); if (normalFrame ) { m_pressedSprite = CCSprite::createWithSpriteFrame(normalFrame); } if (m_pressedSprite == NULL) { m_pressedSprite = CCSprite::create(strNormal.c_str()); } } else { CCSpriteFrame * selFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strSel.c_str()); if (selFrame ) { m_pressedSprite = CCSprite::createWithSpriteFrame(selFrame); } if (m_pressedSprite == NULL) { m_pressedSprite = CCSprite::create(strSel.c_str()); } } if (m_pressedSprite ) { m_pressedSprite->setAnchorPoint(CCPointZero); m_pressedSprite->setPosition(CCPointZero); this->addChild(m_pressedSprite); } //disabel if (strDisable.empty() ) { CCSpriteFrame * normalFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strNormal.c_str()); if (normalFrame ) { m_disableSprite = CCSprite::createWithSpriteFrame(normalFrame); } if (m_disableSprite == NULL) { m_disableSprite = CCSprite::create(strNormal.c_str()); } //如果是用 normal处理的,那么灰化 if (m_disableSprite) { setSpriteGray(m_disableSprite, true); } } else { CCSpriteFrame * disableFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(strDisable.c_str()); if (disableFrame ) { m_disableSprite = CCSprite::createWithSpriteFrame(disableFrame); } if (m_disableSprite == NULL) { m_disableSprite = CCSprite::create(strDisable.c_str()); } } if (m_disableSprite) { m_disableSprite->setAnchorPoint(CCPointZero); m_disableSprite->setPosition(CCPointZero); this->addChild(m_disableSprite); } //显示正常状态 this->setUnSelected(); return true; } //更新某种状态下的图像 void TTButton::upDateImageForState(BTN_STATE btnState , CCTexture2D *texture) { if(texture == NULL) { return ; } if (btnState == BTN_STATE_NORMAL ) { if (m_normalSprite ) { m_normalSprite->setTexture(texture); } } if (btnState == BTN_STATE_PRESS) { if (m_pressedSprite ) { m_pressedSprite->setTexture(texture); } } if (btnState == BTN_STATE_DISABLE) { if (m_disableSprite) { m_disableSprite->setTexture(texture); } } } TTButton * TTButton::createWithImage(std::string strNormal) { TTButton * pRet = new TTButton(); if (pRet && pRet->initWithImage(strNormal) ) { pRet->autorelease(); } else { delete pRet; pRet = NULL; } return pRet; } TTButton * TTButton::createWithImages(std::string strNormal, std::string strSel , std::string strDisable ) { TTButton * pRet = new TTButton(); if (pRet && pRet->initWithImages(strNormal,strSel,strDisable) ) { pRet->autorelease(); } else { delete pRet; pRet = NULL; } return pRet; } TTButton * TTButton:: createWithImage(std::string strNormal, CCSize rectSize) { TTButton * pRet = new TTButton(); if (pRet && pRet->initWithImage(strNormal, rectSize)) { pRet->autorelease(); } else { CC_SAFE_DELETE(pRet); } return pRet; } TTButton * TTButton::createWithImages(std::string strNormal, std::string strSel , std::string strDisable , CCSize rectSize) { TTButton * pRet = new TTButton; if (pRet && pRet->initWithImages(strNormal, strSel, strDisable, rectSize)) { pRet->autorelease(); } else { CC_SAFE_DELETE(pRet); } return pRet; } //设置 颜色 void TTButton::setColorForState(BTN_STATE btnState, ccColor3B color) { switch (btnState) { case BTN_STATE_NORMAL: { if (m_normalSprite) { m_normalSprite->setColor(color); } if (m_normalScaleSprite) { m_normalScaleSprite->setColor(color); } } break; case BTN_STATE_PRESS: { if (m_pressedSprite) { m_pressedSprite->setColor(color); } if (m_pressedScaleSprite) { m_pressedScaleSprite->setColor(color); } } break; case BTN_STATE_DISABLE: { if (m_disableSprite) { m_disableSprite->setColor(color); } if (m_disableScaleSprite) { m_disableScaleSprite->setColor(color); } } break; default: break; } } //更新状态UI void TTButton::upDateStatusUI() { switch (m_btnState) { case BTN_STATE_PRESS: { if (m_normalSprite ) { m_normalSprite->setVisible(false); } if (m_normalScaleSprite) { m_normalScaleSprite->setVisible(false); } if (m_disableSprite ) { m_disableSprite->setVisible(false); } if (m_disableScaleSprite) { m_disableScaleSprite->setVisible(false); } if (m_pressedSprite ) { m_pressedSprite->setVisible(true); } if (m_pressedScaleSprite) { m_pressedScaleSprite->setVisible(true); } } break; case BTN_STATE_NORMAL: { if (m_normalSprite ) { m_normalSprite->setVisible(true); } if (m_normalScaleSprite) { m_normalScaleSprite->setVisible(true); } if (m_disableSprite ) { m_disableSprite->setVisible(false); } if (m_disableScaleSprite) { m_disableScaleSprite->setVisible(false); } if (m_pressedSprite ) { m_pressedSprite->setVisible(false); } if (m_pressedScaleSprite) { m_pressedScaleSprite->setVisible(false); } } break; case BTN_STATE_DISABLE: { if (m_normalSprite ) { m_normalSprite->setVisible(false); } if (m_normalScaleSprite) { m_normalScaleSprite->setVisible(false); } if (m_disableSprite ) { m_disableSprite->setVisible(true); } if (m_disableScaleSprite) { m_disableScaleSprite->setVisible(true); } if (m_pressedSprite ) { m_pressedSprite->setVisible(false); } if(m_disableScaleSprite) { m_disableScaleSprite->setVisible(false); } } break; default: break; } } //设置选中状态 void TTButton::setSelected() { m_bSelected = true; m_btnState = BTN_STATE_PRESS; upDateStatusUI(); } //设置非选中状态 void TTButton::setUnSelected() { m_bSelected = false; m_btnState = BTN_STATE_NORMAL; upDateStatusUI(); } //设置是否是disable状态 void TTButton::setIsDisable(bool bDisabel) { m_bDisabled = bDisabel; if (bDisabel ) { m_btnState = BTN_STATE_DISABLE; } else { m_btnState = BTN_STATE_NORMAL; } upDateStatusUI(); } //获得当前状态 BTN_STATE TTButton::getCurState() { return m_btnState; } //添加 处理handle void TTButton::addTouchupInsideHandle(CCNode * target , SEL_CallFuncO selector) { m_target = target; m_touchupInsideSelector = selector; } //判断是否是点击在有效区域 bool TTButton::isTouchInvalidated(CCTouch* touch) { CCPoint touchLocation = touch->getLocation(); CCPoint localLocation = this->convertToNodeSpace(touchLocation); CCRect rc = CCRectMake( 0, 0, this->getContentSize().width, this->getContentSize().height ); if (rc.containsPoint(localLocation)) { return true; } else { return false; } } void TTButton::onEnter() { CCLayer::onEnter(); CCDirector* pDirector = CCDirector::sharedDirector(); pDirector->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority -1, true); } void TTButton::onExit() { CCLayer::onExit(); CCDirector* pDirector = CCDirector::sharedDirector(); pDirector->getTouchDispatcher()->removeDelegate(this); } bool TTButton::ccTouchBegan(CCTouch* touch, CCEvent* event) { //如果是disabled的状态,那么就返回false if (m_btnState == BTN_STATE_DISABLE) { return false; } //如果自己不可见,那么返回false if (isVisible() == false) { return false; } //如果有parent不可见,那么返回false CCNode * parent = NULL; for (parent = this->getParent() ; parent !=NULL ; parent = parent->getParent() ) { if (parent->isVisible() == false ) { return false; } } //然后判断是否是在自己的范围内 if ( isTouchInvalidated(touch) ) { if (m_bSelected) { m_btnState = BTN_STATE_NORMAL; } else { m_btnState = BTN_STATE_PRESS; } upDateStatusUI(); return true; } return false; } void TTButton::ccTouchMoved(CCTouch* touch, CCEvent* event) { //如果是有效范围内,那么设置selected状态 if ( isTouchInvalidated(touch) ) { if (m_bSelected) { m_btnState = BTN_STATE_NORMAL; } else { m_btnState = BTN_STATE_PRESS; } upDateStatusUI(); } else { if (m_bSelected) { m_btnState = BTN_STATE_PRESS; } else { m_btnState = BTN_STATE_NORMAL; } upDateStatusUI(); } } void TTButton::ccTouchEnded(CCTouch* touch, CCEvent* event) { //然后判断是否是在自己的范围内 if ( isTouchInvalidated(touch) ) { //如果是有处理函数,调用处理函数。 CCLOG("touch event handle \n"); if (m_bSelected) { setUnSelected(); } else { setSelected(); } if ( m_target && m_touchupInsideSelector ) { (m_target->*m_touchupInsideSelector)(this); } } } void TTButton::ccTouchCancelled(CCTouch *touch, CCEvent* event) { if (m_btnState != BTN_STATE_DISABLE ) { this->setUnSelected(); } }
其中使用的方法如下:
这个控件的锚点是(0,0),需要注意下:
TTButton * buttonTest = TTButton::createWithImage("avatar.png"); buttonTest->setScale(39.0f/buttonTest->getContentSize().width); buttonTest->setPosition(ccp( m_originPoint.x + i * (buttonTest->getContentSize().width + 22/2 ) + 30/2 , this->getContentSize().height * 0.5f - buttonTest->getContentSize().height * 0.5f )); buttonTest->addTouchupInsideHandle(this, callfuncO_selector(TTPlayerWall::onClickPlayerImage)); this->addChild(buttonTest);