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

试试吧~~基本达到了想要的效果。

 

 

 

转载于:https://www.cnblogs.com/hanhongmin/p/3496363.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值