cocos2dx 触摸测试三 优先级及阻止传递
前两篇随笔,搞定了单个图片的拖拽和缩放
那么,当屏幕上有两个甚至多个同样的图片会发生什么呢?我们试试
修改HelloWorld的init方法,再放上一个图片
bool HelloWorld::init() { if ( !CCLayer::init() ) { return false; } MySprite* pSprite = MySprite::create("HelloWorld.png"); pSprite->setPosition(VisibleRect::center()); this->addChild(pSprite, 0); MySprite* pSprite2 = MySprite::create("Icon-114.png"); pSprite2->setPosition(VisibleRect::center()); pSprite2->setScale(2.0f);//图片资源太小,我的手指比较大点不到... this->addChild(pSprite2, 1); return true; }
开模拟器试一下单点拖动就可以了,发现两个图片都跟着动。
如果我们想要,上面的图片拖动,后面的不动呢?
google搜一搜,查查资料,都说处理完之后吃掉touches点就可以了
我们试一下
修改ccTouchesMoved方法
void MySprite::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){ CCLog("ccTouchesMoved touches point count:%i",pTouches->count()); CCDictionary* touchesDic = CCDictionary::create(); CCSetIterator iter = pTouches->begin(); CCRect rect = this->boundingBox(); for (; iter != pTouches->end(); iter++){ CCTouch* pTouch = (CCTouch*)(*iter); if(rect.containsPoint(pTouch->getLocation())){ touchesDic->setObject(pTouch, CCString::createWithFormat("%d",pTouch->getID())->getCString()); } } CCArray* keys = touchesDic->allKeys(); //两个手指 if (touchesDic->count() == 2){ //CCLog("****ccTouchesMoved*"); CCArray* keys = touchesDic->allKeys(); CCTouch *touch1 = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(0))->getCString()); CCTouch *touch2 = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(1))->getCString()); CCPoint p1End = touch1->getLocation(); CCPoint p2End = touch2->getLocation(); CCPoint p1Start = touch1->getPreviousLocation(); CCPoint p2Start = touch2->getPreviousLocation(); float startDistance = ccpDistance(p1Start,p2Start); float endDistance = ccpDistance(p1End,p2End); //CCLog("startDistance:%f,endDistance:%f",startDistance,endDistance); float scale = this->getScale()*(endDistance/startDistance); if(scale<0.5f){ scale = 0.5f; }else if(scale>3.0f){ scale = 3.0f; } this->setScale(scale); pTouches->removeObject(touch1); pTouches->removeObject(touch2); }else if(touchesDic->count() ==1){//单点 CCTouch *pTouch = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(0))->getCString()); CCPoint start = pTouch->getPreviousLocation(); CCPoint end = pTouch->getLocation(); //计算位移,直接使用point充当position的话,会有偏差,比如点住图片的一角进行拖动,setPosition的时候是依据AnchorPoint进行设置的 CCPoint sub = ccpSub(end, start); CCPoint newPosition = ccpAdd(this->getPosition(),sub); this->setPosition(newPosition); pTouches->removeObject(pTouch); } }
试一下,发现OK。
按着这个道理,如果我们把大于等于2点的都统一处理,即
if (touchesDic->count() >= 2)
我们只remove了2个点,其余点是否还会往下传递?这个我没试。我尝试了removeAllObjects,然后就报错啦~~
好了暂时先不深究了,至少现在达到我想要的效果了。
记得触摸事件分发有个优先级来着,可以搜一下。balabalabala....
我们把两张图的代码换一下位置
bool HelloWorld::init() { if ( !CCLayer::init() ) { return false; } MySprite* pSprite2 = MySprite::create("Icon-114.png"); pSprite2->setPosition(VisibleRect::center()); pSprite2->setScale(2.0f); this->addChild(pSprite2, 1); MySprite* pSprite = MySprite::create("HelloWorld.png"); pSprite->setPosition(VisibleRect::center()); this->addChild(pSprite, 0); return true; }
再试,发现后面的大图被拖动,这不是我们想要的。原因是,后面的大图优先处理了触摸事件。
那么我们在图片创建的时候,给他一个优先级,然后onEnter的时候把它设置进去。
修改MySprite.h
class MySprite:public CCSprite,public CCTouchDelegate{ public: static MySprite* create(const char *pszFileName,int nPriority); virtual void onEnter(); virtual void onExit(); // optional virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent); virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent); void setPriority(int nPriority); int getPriority(); protected: int _nPriority; };
MySprite.cpp的create方法
MySprite* MySprite::create(const char* pszFileName,int nPriority){ MySprite *pobSprite = new MySprite(); if (pobSprite && pobSprite->initWithFile(pszFileName)) { pobSprite->setPriority(nPriority); pobSprite->autorelease(); return pobSprite; } CC_SAFE_DELETE(pobSprite); return NULL; }
MySprite.cpp的onEnter方法
void MySprite::onEnter(){ CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, _nPriority);//多点触控 CCSprite::onEnter(); }
修改HelloWord的init方法,试试
MySprite* pSprite2 = MySprite::create("Icon-114.png",2);//优先级数值越小越优先响应 pSprite2->setPosition(VisibleRect::center()); pSprite2->setScale(2.0f); this->addChild(pSprite2, 1); MySprite* pSprite = MySprite::create("HelloWorld.png",3); pSprite->setPosition(VisibleRect::center()); this->addChild(pSprite, 0);
试试吧~~基本达到了想要的效果。
我是cocos2dx初学者,Java5年,一点C++,OC经验都没有,各位见笑了
文章中如有错误或者不全面或者有更好的解决办法,请指出,不胜感激