您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx 触摸测试三 优先级及阻止传递

2013-12-29 15:08 323 查看
前两篇随笔,搞定了单个图片的拖拽和缩放

那么,当屏幕上有两个甚至多个同样的图片会发生什么呢?我们试试

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


试试吧~~基本达到了想要的效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: