zoukankan      html  css  js  c++  java
  • 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经验都没有,各位见笑了 文章中如有错误或者不全面或者有更好的解决办法,请指出,不胜感激
  • 相关阅读:
    微信分享 apicloud方式 中遇到的坎
    css之颜色篇
    css总结
    记一些茅塞顿开的事情
    apicloud
    安装MySQL
    智能家居
    java
    数据库设计好不好,分配很重要。
    WP8.1的shell:SystemTray去哪了?
  • 原文地址:https://www.cnblogs.com/hanhongmin/p/3496363.html
Copyright © 2011-2022 走看看