现在的位置: 首页 > 综合 > 正文

cocos2d-x自己实现的一个button类

2013年08月06日 ⁄ 综合 ⁄ 共 14502字 ⁄ 字号 评论关闭

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


抱歉!评论已关闭.