cocos2dx学习之自定义你的CCSprite(二)监测长按和双击

  上一篇我们介绍了如何给你自定义的CCSprite添加Touch监听,但是你会发现无论你点击屏幕的哪里,我们的精灵都会收到Touch事件,为什么会这样呢,主要是CCTouchDispatcher只是实现触摸事件分发,所以每一个添加到CCTouchDispatcher上的CCTouchDelegate,都是一层,屏幕大小,这也是为什么有时候我们点击到层的外面也能接受到Touch监听的原因。不管怎么说,这是我们不想看到的。其实这里cocos2dx的源代码中已经给出了解决办法,那就是CCMenu,看看它的源代码你会发现它是做了判断Touch区域的操作。我们这里也这么做。代码如下

  

bool TestSprite::isInSprite(CCTouch *theTouch){

    //    返回当前触摸位置在OpenGL坐标 

    CCPoint touchPoint=theTouch->getLocation();

    //    将世界坐标转换为当前父View的本地坐标系

    CCPoint reallyPoint=this->getParent()->convertToNodeSpace(touchPoint);

    //    获取当前基于父view的坐标系

    CCRect rect=this->boundingBox();

    //    CCnode->convertToNodeSpace 或者  convertToWorldSpace 是基于当前Node  与当前Node相关

    if(rect.containsPoint(reallyPoint)){

        

        return true;

    }

    

    returnfalse;

}

这样子我们就能知道我们点击是不是我们的精灵了。下面我们来判断双击。代码如下

  //    获取当前时间 精确到毫秒数

    static inline long millisecondNow()

    {

        struct cc_timeval now;

        CCTime::gettimeofdayCocos2d(&now, NULL);

        return (now.tv_sec * 1000 + now.tv_usec / 1000);

    }

    // 判断是不是 双击

    static inline bool isDoubleTouch(){

        static long lastTouchTime=0;

        long thisTouchTime=millisecondNow();

        if(abs(thisTouchTime-lastTouchTime)<250){

            lastTouchTime=0;

            return true;

        }

        else{

            lastTouchTime=millisecondNow();

            return false;

        }

    }

就是简单的做一下两次点击的时间间隔,如果小于250毫米,就算做双击。单机我们给解决了,那么现在就是长按了,长安其实也是很简单就是,如果你touch的时间长于两秒,那么我们算做它长按。或不多说,上代码

void TestSprite::checkLongPress(){

    this->unschedule(schedule_selector(TestSprite::checkLongPress));

    if (isInTouch&&!isInMove) {

        CCLog("LONGLONG");

        this->setScale(2);

        this->setOpacity(200);

        afterLongPress=true;

    }

}

bool TestSprite::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent){

    if (this->isInSprite(pTouch)) {

  isInTouch=true;

        if (isDoubleTouch()) {

            this->doubleClickSprite();

            this->touchBeginTime=millisecondNow();

        }else{

            this->singleClickSprite();

            this->touchBeginTime=millisecondNow();

            this->schedule(schedule_selector(TestSprite::checkLongPress), 2);

        }

        

        

        return true;

    }

 

    returnfalse;

}

 void TestSprite::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {

     CCPoint deltaPoint=pTouch->getDelta();

     CCLog("x=%f,y=%f",deltaPoint.x,deltaPoint.y);

     if(fabs(deltaPoint.x)>1||fabs(deltaPoint.y)>1){

         isInMove=true;

       }

 

}

 void TestSprite::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {

     isInTouch=false;

     isInMove=false;

     afterLongPress=false;

//     恢复 精灵

     this->setScale(1);

     this->setPosition(orignalPoint);

     this->setOpacity(255);

     

}

 void TestSprite::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent){

     isInTouch=false;

     isInMove=false;

     afterLongPress=false;

//     恢复 精灵

     this->setScale(1);

     this->setPosition(orignalPoint);

     this->setOpacity(255);

}

当然我们这里也是做了一个简单的判断,如果touch了一直没有move超过两秒我们才算做长按的。 

posted @ 2013-01-19 16:32  丁昌兴  阅读(5353)  评论(0编辑  收藏  举报