代码改变世界

扩展cocos2d-x中的CCSprite增加点击事件处理

2013-07-23 23:07  科悦  阅读(2299)  评论(1)    收藏  举报

 

#ifndef __CCSPRITEEX_H__
#define __CCSPRITEEX_H__
 
// CCSpriteEx 是对 CCSprite类的扩展,主要是能得到触摸事件的反馈
 
#include <cocos2d.h>
#include <cocos-ext.h>
 
NS_CC_BEGIN
 
class CCSpriteEx 
: public CCSprite
, public CCTargetedTouchDelegate
{
public:
    CCB_STATIC_NEW_AUTORELEASE_OBJECT_WITH_INIT_METHOD(CCSpriteEx, create); // 用于CocosBuilder
    // 设置点击精灵的事件处理器
    void setSelectorWithTarget(CCObject *target, SEL_MenuHandler selector);
 
public:
    CCSpriteEx() : m_pListener(NULL),m_pfnSelector(NULL) {}
 
private:
    void onEnter();
    void onExit();
    // 取得精灵的位置与尺寸
    CCRect rect();
    // 触摸点是否在精灵上
    bool isTouchInside(CCTouch* touch);
 
    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    // optional
    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent);}
    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent);}
 
private:
    // 点击事件处理
    CCObject*       m_pListener;
    SEL_MenuHandler m_pfnSelector;
};
 
class CCSpriteExLoader : public cocos2d::extension::CCSpriteLoader {
public:
    CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCSpriteExLoader, loader);
 
protected:
    CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(CCSpriteEx);
};
 
NS_CC_END
 
#endif // __CCSPRITEEX_H__
 
// cpp begin ----------------------------------------------------------------------
#include "CCSpriteEx.h"
 
NS_CC_BEGIN
 
 
void CCSpriteEx::onEnter()
{
    CCSprite::onEnter();
    // 注册触摸协议,并吃掉触摸事件
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0/*priority=??*/, true);
}
 
void CCSpriteEx::onExit()
{
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
    CCSprite::onExit();
}
 
cocos2d::CCRect CCSpriteEx::rect()
{
    return CCRectMake(getPositionX() - getContentSize().width * getAnchorPoint().x,
        getPositionY() - getContentSize().height * getAnchorPoint().y,
        getContentSize().width, getContentSize().height); // 为了能够自定义自己的位置大小采用了低效的函数而不是直接用成员变量
}
 
bool CCSpriteEx::isTouchInside( CCTouch* touch )
{
    CCPoint touchLocation = touch->getLocation(); // 返回GL坐标
    CCPoint localPos = convertToNodeSpace(touchLocation);
    CCRect rc = rect();
    rc.origin = CCPointZero;
    bool isTouched = rc.containsPoint(localPos);
     
    return isTouched;
}
 
bool CCSpriteEx::ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent )
{
    bool isTouched = isTouchInside(pTouch);
    return isTouched;
}
 
void CCSpriteEx::ccTouchEnded( CCTouch *pTouch, CCEvent *pEvent )
{
    bool isTouched = isTouchInside(pTouch) && isVisible();
    if (isTouched)
    {       
        if (m_pListener && m_pfnSelector)
        {
            (m_pListener->*m_pfnSelector)(this);
        }
    }
}
 
void CCSpriteEx::setSelectorWithTarget( CCObject *target, SEL_MenuHandler selector )
{
    m_pListener = target;
    m_pfnSelector = selector;
}
 
NS_CC_END