头文件
class MyMenu : public CCMenu { public: virtual void registerWithTouchDispatcher() { //这里优先级设为1,只要比CCScrollView低就可以 CCDirector* pDirector = CCDirector::sharedDirector(); pDirector->getTouchDispatcher()->addTargetedDelegate(this, 1, true); } static MyMenu* create(); static MyMenu* create(CCMenuItem* item, ...); bool isTouchBegan(CCTouch *pTouch, CCEvent *pEvent); void touchMoved(CCTouch *pTouch, CCEvent *pEvent); void touchEnded(CCTouch *pTouch, CCEvent *pEvent); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchCancelled(CCTouch *touch, CCEvent* event); virtual void onExit(); //super methods virtual void addChild(CCNode * child); virtual void addChild(CCNode * child, int zOrder); virtual void addChild(CCNode * child, int zOrder, int tag); virtual void removeChild(CCNode* child, bool cleanup); virtual void setOpacityModifyRGB(bool bValue) {CC_UNUSED_PARAM(bValue);} virtual bool isOpacityModifyRGB(void) { return false;} virtual bool isEnabled() { return m_bEnabled; } virtual void setEnabled(bool value) { m_bEnabled = value; }; MyMenu() : m_pSelectedItem(NULL){} virtual ~MyMenu(){} static MyMenu* createWithItems(CCMenuItem *item, va_list args); static MyMenu* createWithArray(CCArray* pArrayOfItems); bool initWithArray(CCArray* pArrayOfItems); private: //CCRect visibleRect_; CCPoint startPosition; bool m_bEnabled; bool moved_; CCPoint startPoint; protected: CCMenuItem *m_pSelectedItem; };
cpp文件
#define CC_UNUSED_PARAM(unusedparam) (void)unusedparam bool MyMenu::isTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { CC_UNUSED_PARAM(pEvent); if (m_eState != kCCMenuStateWaiting || ! m_bVisible || !m_bEnabled) { return false; } for (CCNode *c = this->m_pParent; c != NULL; c = c->getParent()) { if (c->isVisible() == false) { return false; } } m_pSelectedItem = this->itemForTouch(pTouch); if (m_pSelectedItem) { m_eState = kCCMenuStateTrackingTouch; m_pSelectedItem->selected(); return true; } return false; } void MyMenu::touchMoved(CCTouch *pTouch, CCEvent *pEvent) { CC_UNUSED_PARAM(pEvent); CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchMoved] -- invalid state"); CCMenuItem *currentItem = this->itemForTouch(pTouch); if (currentItem != m_pSelectedItem) { if (m_pSelectedItem) { m_pSelectedItem->unselected(); } m_pSelectedItem = currentItem; if (m_pSelectedItem) { m_pSelectedItem->selected(); } } } void MyMenu::touchEnded(CCTouch *pTouch, CCEvent *pEvent) { CC_UNUSED_PARAM(pTouch); CC_UNUSED_PARAM(pEvent); CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchEnded] -- invalid state"); if (m_pSelectedItem) { m_pSelectedItem->unselected(); m_pSelectedItem->activate(); } m_eState = kCCMenuStateWaiting; } bool MyMenu::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent){ startPoint = pTouch->getLocation(); /* if(!CCRectMake(0,80,800,320).containsPoint(pTouch->getLocation())) return false;*/ moved_=false; return isTouchBegan(pTouch,pEvent); } void MyMenu::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent){ if (abs(int(pTouch->getLocation().x-startPoint.x)) > 15||abs(int(pTouch->getLocation().y-startPoint.y))>15) { moved_ = true; } touchMoved(pTouch,pEvent); } void MyMenu::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent){ if(!moved_) touchEnded(pTouch,pEvent); else { m_eState = kCCMenuStateWaiting; m_pSelectedItem = this->itemForTouch(pTouch); if(m_pSelectedItem){ m_pSelectedItem->unselected(); } } } MyMenu* MyMenu::create() { return MyMenu::create(NULL, NULL); } MyMenu* MyMenu::create( CCMenuItem* item, ... ) { va_list args; va_start(args,item); MyMenu *pRet = MyMenu::createWithItems(item, args); va_end(args); return pRet; } MyMenu* MyMenu::createWithItems( CCMenuItem *item, va_list args ) { CCArray* pArray = NULL; if( item ) { pArray = CCArray::create(item, NULL); CCMenuItem *i = va_arg(args, CCMenuItem*); while(i) { pArray->addObject(i); i = va_arg(args, CCMenuItem*); } } return MyMenu::createWithArray(pArray); } MyMenu* MyMenu::createWithArray( CCArray* pArrayOfItems ) { MyMenu *pRet = new MyMenu(); if (pRet && pRet->initWithArray(pArrayOfItems)) { pRet->autorelease(); } else { CC_SAFE_DELETE(pRet); } return pRet; } bool MyMenu::initWithArray(CCArray* pArrayOfItems) { if (CCLayer::init()) { setTouchPriority(kCCMenuHandlerPriority); setTouchMode(kCCTouchesOneByOne); setTouchEnabled(true); m_bEnabled = true; moved_ = false; // menu in the center of the screen CCSize s = CCDirector::sharedDirector()->getWinSize(); this->ignoreAnchorPointForPosition(true); setAnchorPoint(ccp(0.5f, 0.5f)); this->setContentSize(s); setPosition(ccp(s.width/2, s.height/2)); if (pArrayOfItems != NULL) { int z=0; CCObject* pObj = NULL; CCARRAY_FOREACH(pArrayOfItems, pObj) { CCMenuItem* item = (CCMenuItem*)pObj; this->addChild(item, z); z++; } } // [self alignItemsVertically]; m_pSelectedItem = NULL; m_eState = kCCMenuStateWaiting; // enable cascade color and opacity on menus setCascadeColorEnabled(true); setCascadeOpacityEnabled(true); return true; } return false; } void MyMenu::ccTouchCancelled( CCTouch *touch, CCEvent* event ) { CCMenu::ccTouchCancelled(touch,event); } void MyMenu::onExit() { CCMenu::onExit(); } void MyMenu::addChild( CCNode * child ) { CCMenu::addChild(child); } void MyMenu::addChild( CCNode * child, int zOrder ) { CCMenu::addChild(child,zOrder); } void MyMenu::addChild( CCNode * child, int zOrder, int tag ) { CCMenu::addChild(child,zOrder,tag); } void MyMenu::removeChild( CCNode* child, bool cleanup ) { CCMenu::removeChild(child,cleanup); }