为了用menu来进行对touch事件的阻断,防止其传到下一层,又不能影响上面的CCControlButton等优先级为0的sprite的点击响应,于是就定义了一个MyMenu。
下面为相关代码,下一篇(cocos2d-x里面touch事件传递机制 .)我再详细说下cocos2d-x里面的touch事件响应机制
这里面代码(1)(2)是MyMenu的例子,(7)(8)里面控制touch传递的例子
(1)MyMenu.h
#pragma once // MyMenu #include "cocos2d.h" using namespace cocos2d; class MyMenu : public CCMenu { public: MyMenu(void); ~MyMenu(void); /** creates a CCMenu with it's items */ static MyMenu* create(CCMenuItem* item, ...); // 重写registerWithTouchDispatcher virtual void registerWithTouchDispatcher(); };
(2)MyMenu.cpp
#include "MyMenu.h" MyMenu::MyMenu(void) { } MyMenu::~MyMenu(void) { } MyMenu * MyMenu::create(CCMenuItem* item, ...) { va_list args; va_start(args,item); MyMenu *pRet = new MyMenu(); if (pRet && pRet->initWithItems(item, args)) { pRet->autorelease(); va_end(args); return pRet; } va_end(args); CC_SAFE_DELETE(pRet); return NULL; } // 重写registerWithTouchDispatcher void MyMenu::registerWithTouchDispatcher() { //这里优先级设为1,只要比CCScrollView、tableView、CCControlButton等(这些优先级都为0)低就可以 CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, true); }
(3)BattleBGLayer.h
#pragma once // 战役界面(包含左侧的选项栏layer(BattleZuoLayer)、承载战役场景的layer(BattleShowLayer)等)layer #include "cocos2d.h" #include "cocos-ext.h" using namespace cocos2d; using namespace cocos2d::extension; class BattleBGLayer : public CCLayer { public: BattleBGLayer(void); ~BattleBGLayer(void); public: // init virtual bool init(); CREATE_FUNC(BattleBGLayer); };
(4)BattleBGLayer.cpp
#include "BattleBGLayer.h" #include "BattleShowLayer.h" #include "BattleZuoLayer.h" //****************************************变量begin********************************** // 定义全局变量 int bl_showNumber = 1; // 选择的是哪个战役 //****************************************变量end************************************* BattleBGLayer::BattleBGLayer(void) { } BattleBGLayer::~BattleBGLayer(void) { } // init bool BattleBGLayer::init() { if (!CCLayer::init()) { return false; } // 承载战役场景的layer(BattleShowLayer) BattleShowLayer* battleShowLayer = BattleShowLayer::create(); this->addChild(battleShowLayer,0,1000); // 左侧的选项栏layer(BattleZuoLayer) BattleZuoLayer* battleZuoLayer = BattleZuoLayer::create(); this->addChild(battleZuoLayer,10,1001); return true; }
(5)BattleShowLayer.h
#pragma once // 战役场景界面layer #include "cocos2d.h" #include "cocos-ext.h" #include "BattleBGLayer.h" // 为了引人全局变量 using namespace cocos2d; using namespace cocos2d::extension; //****************************************变量begin********************************** // 声明全局变量 extern int bl_showNumber; // 选择的是哪个战役 //****************************************变量end************************************* class BattleShowLayer : public CCLayer { public: BattleShowLayer(void); ~BattleShowLayer(void); public: // init virtual bool init(); CREATE_FUNC(BattleShowLayer); public: // 兵临华沙战役中各个军队按钮点击回调函数 void jundui1UpInside(CCObject* pSender, CCControlEvent controlEvent); // 马其诺防线战役中各个军队按钮点击回调函数 void jundui2UpInside(CCObject* pSender, CCControlEvent controlEvent); // 敦刻尔克战役中各个军队按钮点击回调函数 void jundui3UpInside(CCObject* pSender, CCControlEvent controlEvent); // 基辅会战战役中各个军队按钮点击回调函数 void jundui4UpInside(CCObject* pSender, CCControlEvent controlEvent); };
(6)BattleShowLayer.cpp
#include "BattleShowLayer.h" BattleShowLayer::BattleShowLayer(void) { } BattleShowLayer::~BattleShowLayer(void) { } // init bool BattleShowLayer::init() { if (!CCLayer::init()) { return false; } // winSize CCSize winSize = CCDirector::sharedDirector()->getWinSize(); // Add the BG CCSprite* theBG = CCSprite::create(CCString::createWithFormat("battle/%d/bg%d.jpg", bl_showNumber, bl_showNumber)->getCString()); theBG->setPosition(ccp(winSize.width/2-44, winSize.height/2)); this->addChild(theBG,0,1000); // 兵临华沙战役 if (bl_showNumber == 1) { // 坐标 int position2_1[12][2] = {{90,598}, {190,550}, {150,434}, {162,318}, {212,214}, {298,304}, {314,426}, {424,538}, {488,468}, {570,432}, {670,500}, {826,462}}; // 各个军队的点击图片 for (int i=1; i<=12; i++) { CCControlButton* jundui1ControlBtn = CCControlButton::create(CCScale9Sprite::create(CCString::createWithFormat("battle/1/%d.png", i)->getCString())); jundui1ControlBtn->setPosition(ccp(position2_1[i-1][0],position2_1[i-1][1])); jundui1ControlBtn->addTargetWithActionForControlEvents(this,cccontrol_selector(BattleShowLayer::jundui1UpInside),CCControlEventTouchUpInside); jundui1ControlBtn->setPreferredSize(CCSizeMake(120,80)); // 点击区域 if (i == 12) { jundui1ControlBtn->setPreferredSize(CCSizeMake(150,100)); } this->addChild(jundui1ControlBtn,0,i); } } // 马其诺防线 else if (bl_showNumber == 2) { // 坐标 int position2_2[11][2] = {{184,660}, {290,584}, {236,458}, {196,300}, {316,324}, {286,250}, {756,190}, {672,344}, {606,448}, {730,490}, {850,570}}; // 各个军队的点击图片 for (int i=1; i<=11; i++) { CCControlButton* jundui2ControlBtn = CCControlButton::create(CCScale9Sprite::create(CCString::createWithFormat("battle/2/%d.png", i)->getCString())); jundui2ControlBtn->setPosition(ccp(position2_2[i-1][0],position2_2[i-1][1])); jundui2ControlBtn->addTargetWithActionForControlEvents(this,cccontrol_selector(BattleShowLayer::jundui2UpInside),CCControlEventTouchUpInside); jundui2ControlBtn->setPreferredSize(CCSizeMake(120,80)); // 点击区域 if (i == 11) { jundui2ControlBtn->setPreferredSize(CCSizeMake(150,100)); } this->addChild(jundui2ControlBtn,0,i); } } // 敦刻尔克 else if (bl_showNumber == 3) { // 坐标 int position2_3[9][2] = {{156,590}, {258,548}, {86,390}, {336,228}, {440,360}, {500,542}, {654,482}, {830,538},{738,258}}; // 各个军队的点击图片 for (int i=1; i<=9; i++) { CCControlButton* jundui3ControlBtn = CCControlButton::create(CCScale9Sprite::create(CCString::createWithFormat("battle/3/%d.png", i)->getCString())); jundui3ControlBtn->setPosition(ccp(position2_3[i-1][0],position2_3[i-1][1])); jundui3ControlBtn->addTargetWithActionForControlEvents(this,cccontrol_selector(BattleShowLayer::jundui3UpInside),CCControlEventTouchUpInside); jundui3ControlBtn->setPreferredSize(CCSizeMake(120,80)); // 点击区域 if (i == 9) { jundui3ControlBtn->setPreferredSize(CCSizeMake(150,100)); } this->addChild(jundui3ControlBtn,0,i); } } // 基辅会战 else if (bl_showNumber == 4) { // 坐标 int position2_4[9][2] = {{82,324}, {182,390}, {246,484}, {372,456}, {460,344}, {580,360}, {630,470}, {806,512}, {866,368}}; // 各个军队的点击图片 for (int i=1; i<=9; i++) { CCControlButton* jundui4ControlBtn = CCControlButton::create(CCScale9Sprite::create(CCString::createWithFormat("battle/4/%d.png", i)->getCString())); jundui4ControlBtn->setPosition(ccp(position2_4[i-1][0],position2_4[i-1][1])); jundui4ControlBtn->addTargetWithActionForControlEvents(this,cccontrol_selector(BattleShowLayer::jundui4UpInside),CCControlEventTouchUpInside); jundui4ControlBtn->setPreferredSize(CCSizeMake(120,80)); // 点击区域 if (i == 9) { jundui4ControlBtn->setPreferredSize(CCSizeMake(150,100)); } this->addChild(jundui4ControlBtn,0,i); } } return true; } // 兵临华沙战役中各个军队按钮点击回调函数 void BattleShowLayer::jundui1UpInside(CCObject* pSender, CCControlEvent controlEvent) { } // 马其诺防线战役中各个军队按钮点击回调函数 void BattleShowLayer::jundui2UpInside(CCObject* pSender, CCControlEvent controlEvent) { } // 敦刻尔克战役中各个军队按钮点击回调函数 void BattleShowLayer::jundui3UpInside(CCObject* pSender, CCControlEvent controlEvent) { } // 基辅会战战役中各个军队按钮点击回调函数 void BattleShowLayer::jundui4UpInside(CCObject* pSender, CCControlEvent controlEvent) { }
(7)BattleZuoLayer.h
#pragma once // 战役界面左侧的选项栏layer #include "cocos2d.h" #include "cocos-ext.h" #include "CityScene.h" // 为了引人全局变量 #include "BattleBGLayer.h" // 为了引人全局变量 using namespace cocos2d; using namespace cocos2d::extension; //****************************************变量begin********************************** // 声明全局变量 extern CityScene* theAScene_global; // theAScene_global用来保存CityScene,让其他地方也能使用CityScene对象 // 声明全局变量 extern int bl_showNumber; // 选择的是哪个战役 //****************************************变量end************************************* class BattleZuoLayer : public CCLayer { public: BattleZuoLayer(void); ~BattleZuoLayer(void); public: // init virtual bool init(); CREATE_FUNC(BattleZuoLayer); public: // myMenu空回调函数 void myNullCallback(CCObject* pSender); // 战役图片点击回调函数 void btn_battleControlBtnUpIn(CCObject* pSender, CCControlEvent controlEvent); // 四个战役按钮图片的点击回调函数 void zhanyiControlBtn1UpInside(CCObject* pSender, CCControlEvent controlEvent); // 选中战役后的按钮图片的点击回调空函数 void zhanyiControlBtn2UpInside(CCObject* pSender, CCControlEvent controlEvent); // 战役介绍的文字内容显示函数 void china2Show(int i); // 各个战役显示函数 void zhanyiShow(int i); };
(8)BattleZuoLayer.cpp
#include "BattleZuoLayer.h" #include "positionResource.h" #include "BattleShowLayer.h" #include "MyMenu.h" // 转码的 #include "UTFTools.h" BattleZuoLayer::BattleZuoLayer(void) { } BattleZuoLayer::~BattleZuoLayer(void) { } // init bool BattleZuoLayer::init() { if (!CCLayer::init()) { return false; } // winSize CCSize winSize = CCDirector::sharedDirector()->getWinSize(); // 底部遮挡图片(用来屏蔽下面事件被触发)(MyMenu) CCMenuItem* myItem = CCMenuItemImage::create("battle/bg_dlg.png","battle/bg_dlg.png",this,menu_selector(BattleZuoLayer::myNullCallback)); MyMenu* myMenu = MyMenu::create(myItem,NULL); myMenu->setPosition(_BL_ZUOBGCONTROLBTN_POS); this->addChild(myMenu,99,99); // 侧边栏 CCSprite* zuoBGPic = CCSprite::create("battle/bg_dlg.png"); zuoBGPic->setPosition(_BL_ZUOBGCONTROLBTN_POS); this->addChild(zuoBGPic,100,100); // "战役"点击的图片 CCControlButton* btn_battleControlBtn = CCControlButton::create(CCScale9Sprite::create("battle/btn_battle_over.png")); btn_battleControlBtn->setPosition(_BL_BTN_BATTLECONTROLBTN_POS); btn_battleControlBtn->addTargetWithActionForControlEvents(this, cccontrol_selector(BattleZuoLayer::btn_battleControlBtnUpIn), CCControlEventTouchUpInside); btn_battleControlBtn->setPreferredSize(CCSizeMake(22,136)); zuoBGPic->addChild(btn_battleControlBtn); // 底图框1(文字介绍底图框) CCScale9Sprite* ditukuang1 = CCScale9Sprite::create("cityBuilding/cityBuildingInfo/kuang1.png"); ditukuang1->setContentSize(CCSizeMake(200,180)); ditukuang1->setPosition(_BL_DITUKUANG1_POS); zuoBGPic->addChild(ditukuang1); // 四个战役按钮图片 int position1[4][2] = {{140,220},{140,170},{140,120},{140,70}}; for (int i=1; i<=4; i++) { CCControlButton* zhanyiControlBtn1 = CCControlButton::create(CCScale9Sprite::create("battle/greenbtn01.png")); zhanyiControlBtn1->setPosition(ccp(position1[i-1][0],position1[i-1][1])); zhanyiControlBtn1->addTargetWithActionForControlEvents(this,cccontrol_selector(BattleZuoLayer::zhanyiControlBtn1UpInside),CCControlEventTouchUpInside); zhanyiControlBtn1->setPreferredSize(CCSizeMake(116,36)); // 点击区域 zhanyiControlBtn1->setZoomOnTouchDown(false); // 点击是否放大 zuoBGPic->addChild(zhanyiControlBtn1,0,200+i); } // 选中战役后的按钮图片(起初默认在第一个) CCControlButton* zhanyiControlBtn2 = CCControlButton::create(CCScale9Sprite::create("battle/greenbtn02.png")); zhanyiControlBtn2->setPosition(ccp(position1[0][0],position1[0][1])); zhanyiControlBtn2->addTargetWithActionForControlEvents(this,cccontrol_selector(BattleZuoLayer::zhanyiControlBtn2UpInside),CCControlEventTouchUpInside); zhanyiControlBtn2->setPreferredSize(CCSizeMake(116,36)); // 点击区域 zhanyiControlBtn2->setZoomOnTouchDown(false); // 点击是否放大 zuoBGPic->addChild(zhanyiControlBtn2,10,210); // 四个按钮图片上面的文字 for (int i=1; i<=4; i++) { std::string arr[] = {"兵临华沙", "马其诺防线", "敦刻尔克", "基辅会战"}; std::string china1_label = arr[i-1]; GBKToUTF8(china1_label, "gbk", "utf-8"); CCLabelTTF* labelTTF1 = CCLabelTTF::create(china1_label.c_str(), "Marker Felt", 14); labelTTF1->setPosition(ccp(position1[i-1][0],position1[i-1][1])); zuoBGPic->addChild(labelTTF1,20); } // 战役介绍的文字内容 BattleZuoLayer::china2Show(1); return true; } // myMenu空回调函数 void BattleZuoLayer::myNullCallback(CCObject* pSender){} // "战役"图片点击回调函数 void BattleZuoLayer::btn_battleControlBtnUpIn(CCObject* pSender, CCControlEvent controlEvent) { // 侧边栏进/出 if (this->getChildByTag(100)->getPositionX() == -250) { this->getChildByTag(100)->runAction(CCMoveBy::create(0.3,ccp(470,0))); this->getChildByTag(99)->runAction(CCMoveBy::create(0.3,ccp(470,0))); } else { this->getChildByTag(100)->runAction(CCMoveBy::create(0.3,ccp(-470,0))); this->getChildByTag(99)->runAction(CCMoveBy::create(0.3,ccp(-470,0))); } } // 四个战役按钮图片的点击回调函数 void BattleZuoLayer::zhanyiControlBtn1UpInside(CCObject* pSender, CCControlEvent controlEvent) { // theTag int theTag = ((CCNode*)pSender)->getTag(); // 选中效果的图片的坐标改变 this->getChildByTag(100)->getChildByTag(210)->setPosition(this->getChildByTag(100)->getChildByTag(theTag)->getPosition()); // 相关战役文字介绍 BattleZuoLayer::china2Show(theTag-200); // 切换到相关战役界面 BattleZuoLayer::zhanyiShow(theTag-200); } // 选中战役后的按钮图片的点击回调空函数 void BattleZuoLayer::zhanyiControlBtn2UpInside(CCObject* pSender, CCControlEvent controlEvent){} // 战役介绍的文字内容显示函数 void BattleZuoLayer::china2Show(int i) { // 移除之前显示的文字 if (this->getChildByTag(100)->getChildByTag(300)) { this->getChildByTag(100)->removeChildByTag(300,true); } // 文字显示 std::string arr[] = {"联合帝国突袭波兰,数天之后便占领但泽走廊,并且以每天60公里的速度向波兰首都华沙推进。在帝国军队狂轰乱炸下,暂时的安全处所已经成为了波兰人民奢华的享受。",\ "为防止联合帝国入侵而建造的钢筋混领土壁垒。1940年5月,帝国部队施展调虎离山计成功的从防御薄弱的地方绕过了马其诺防线。", \ "同样式1940年,因比利时投降,近40万盟军被困敦刻尔克。为保存有生力量,盟军在敦刻尔克上演了一次大规模撤退奇迹。", \ "基辅会战是战争史上规模最大的一次围歼战。对帝国来说是一次空前的杰作,但很多人认为:这场漂亮的围歼战让帝国失去了战争史上最伟大的战争。"}; std::string china2_label = arr[i-1]; GBKToUTF8(china2_label, "gbk", "utf-8"); CCLabelTTF* labelTTF2 = CCLabelTTF::create(china2_label.c_str(), "Marker Felt", 16, CCSizeMake(180,160), kCCTextAlignmentLeft,kCCVerticalTextAlignmentTop); labelTTF2->setPosition(_BL_DITUKUANG1_POS); this->getChildByTag(100)->addChild(labelTTF2,0,300); } // 各个战役界面显示函数 void BattleZuoLayer::zhanyiShow(int i) { // 移除之前显示过的图层 if (theAScene_global->getChildByTag(103)->getChildByTag(1000)) { theAScene_global->getChildByTag(103)->removeChildByTag(1000,true); } // 显示场景界面layer bl_showNumber = i; BattleShowLayer* battleShowLayer = BattleShowLayer::create(); theAScene_global->getChildByTag(103)->addChild(battleShowLayer,0,1000); // 底部遮挡图片重新再加载(cocos2d-x的touch处理机制貌似是后addChild先响应,再看会不会往下传递,所以为了不向下传递必须在要屏蔽的对象后再加载一遍) if (this->getChildByTag(99)) { this->removeChildByTag(99,true); } CCMenuItem* myItem = CCMenuItemImage::create("battle/bg_dlg.png","battle/bg_dlg.png",this,menu_selector(BattleZuoLayer::myNullCallback)); MyMenu* myMenu = MyMenu::create(myItem,NULL); myMenu->setPosition(this->getChildByTag(100)->getPosition()); this->addChild(myMenu,99,99); // 四个战役按钮图片重新再加载 for (int i=1; i<=4; i++) { this->getChildByTag(100)->removeChildByTag(200+i,true); } int position1[4][2] = {{140,220},{140,170},{140,120},{140,70}}; for (int i=1; i<=4; i++) { CCControlButton* zhanyiControlBtn1 = CCControlButton::create(CCScale9Sprite::create("battle/greenbtn01.png")); zhanyiControlBtn1->setPosition(ccp(position1[i-1][0],position1[i-1][1])); zhanyiControlBtn1->addTargetWithActionForControlEvents(this,cccontrol_selector(BattleZuoLayer::zhanyiControlBtn1UpInside),CCControlEventTouchUpInside); zhanyiControlBtn1->setPreferredSize(CCSizeMake(116,36)); // 点击区域 zhanyiControlBtn1->setZoomOnTouchDown(false); // 点击是否放大 this->getChildByTag(100)->addChild(zhanyiControlBtn1,0,200+i); } }
这里面代码(1)(2)是MyMenu的例子,(7)(8)里面控制touch传递的例子