cocos2dx 触摸测试二 多点包含单点

紧接上一篇,现在我们去掉单点触摸的注册,仅使用多点触摸来实现Sprite的拖拽和缩放

删除单点触摸对应的方法声明和定义,onEnter中取消单点触摸事件的注册

修改ccTouchesBegan方法,我们把在图片范围内的触摸视为有效触摸。当有一个指头在图片内,另一个在图片外,我们就将其视为单点触摸。

void MySprite::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){

    CCLog("ccTouchesBegan 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){//多于2点,只取前两点为有效点

        

        CCTouch *touch1 = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(0))->getCString());

        CCTouch *touch2 = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(1))->getCString());

        

        CCPoint pt = touch1->getLocation();

        CCPoint pt2 = touch2->getLocation();

        if(pt.x==pt2.x&&pt.y==pt2.y){

            CCLog("两点一样");

            return;

        }

        _beganDistance = ccpDistance(pt,pt2);

        CCLog("****ccTouchesBegan,distance:%f",_beganDistance);

    }

}

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 pt = touch1->getLocation();

        CCPoint pt2 = touch2->getLocation();

        

        float moveDistance = ccpDistance(pt,pt2);

        CCLog("_beganDistance:%f,moveDistance:%f",_beganDistance,moveDistance);

        if(_beganDistance!=0){

            CCLog("curScale:%f,change:%f",this->getScale(),moveDistance/_beganDistance);

            this->setScale(this->getScale()*(moveDistance/_beganDistance));

            _beganDistance = moveDistance;

        }else{

            CCLog("开始距离为0");

        }

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

    }

}

开模拟器试一下单点,拖动没啥问题

在真机上试一下缩放,和上一篇的效果基本无异,注意触点得在图片内。

 

下面我们尝试改善一下缩放效果,上一篇的有点问题,就是程序初始化的时候_beganDistance是零,而这时二指不同时触摸的话,调用了两次ccTouchesBegan,都是一个点的参数,_beganDistance还是零。而后面的情况,_beganDistance会保留上一次缩放的值,导致如果第二次二指间距离和上一次差距过大的话,图片会被骤然缩放。

我们是否可以按照单点的方式来做呢?压根就不要在ccTouchesBegan中设置这个值了。试试吧

ccTouchesBegan方法中程序直接注释掉,修改ccTouchesMoved方法,如下:

void MySprite::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){

    CCLog("ccTouchesBegan touches point count:%i",pTouches->count());

}

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

        this->setScale(this->getScale()*(endDistance/startDistance));

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

    }

}

OK,去真机上试一下。                    

:目      尚未发现其他问题。

再限制一下缩放比例。如最小0.5,最大3。

最终代码如下:

MySprite.h

 1 //

 2 //  MySprite.h

 3 //  TouchesTest

 4 //

 5 //  Created by HanHongmin on 13-12-28.

 6 //

 7 //

 8 

 9 #ifndef __TouchesTest__MySprite__

10 #define __TouchesTest__MySprite__

11 

12 #include "cocos2d.h"

13 using namespace cocos2d;

14 

15 class MySprite:public CCSprite,public CCTouchDelegate{

16 public:

17     static MySprite* create(const char *pszFileName);

18     

19     virtual void onEnter();

20     virtual void onExit();

21     

22     // optional

23     virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);

24     virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);

25     virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);

26     virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);

27 protected:

28     //float _beganDistance;

29 };

30 

31 #endif /* defined(__TouchesTest__MySprite__) */
View Code

MySprite.cpp

 1 //

 2 //  MySprite.cpp

 3 //  TouchesTest

 4 //

 5 //  Created by HanHongmin on 13-12-28.

 6 //

 7 //

 8 

 9 #include "MySprite.h"

10 

11 MySprite* MySprite::create(const char* pszFileName){

12     MySprite *pobSprite = new MySprite();

13     if (pobSprite && pobSprite->initWithFile(pszFileName))

14     {

15         pobSprite->autorelease();

16         return pobSprite;

17     }

18     CC_SAFE_DELETE(pobSprite);

19     return NULL;

20 }

21 

22 void MySprite::onEnter(){

23     CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);//多点触控

24     //CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);//单点触控

25     CCSprite::onEnter();

26 }

27 void MySprite::onExit(){

28     CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);

29     CCSprite::onExit();

30 }

31 

32 

33 // optional

34 void MySprite::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){

35     //CCLog("ccTouchesBegan touches point count:%i",pTouches->count());

36 }

37 void MySprite::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){

38     CCLog("ccTouchesMoved touches point count:%i",pTouches->count());

39     CCDictionary* touchesDic = CCDictionary::create();

40     CCSetIterator iter = pTouches->begin();

41     CCRect rect = this->boundingBox();

42     for (; iter != pTouches->end(); iter++){

43         CCTouch* pTouch = (CCTouch*)(*iter);

44         if(rect.containsPoint(pTouch->getLocation())){

45             touchesDic->setObject(pTouch, CCString::createWithFormat("%d",pTouch->getID())->getCString());

46         }

47     }

48     CCArray* keys = touchesDic->allKeys();

49     //两个手指

50     if (touchesDic->count() == 2){

51         //CCLog("****ccTouchesMoved*");

52         CCArray* keys = touchesDic->allKeys();

53         CCTouch *touch1 = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(0))->getCString());

54         CCTouch *touch2 = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(1))->getCString());

55         

56         CCPoint p1End = touch1->getLocation();

57         CCPoint p2End = touch2->getLocation();

58         CCPoint p1Start = touch1->getPreviousLocation();

59         CCPoint p2Start = touch2->getPreviousLocation();

60         

61         float startDistance = ccpDistance(p1Start,p2Start);

62         float endDistance = ccpDistance(p1End,p2End);

63         

64         //CCLog("startDistance:%f,endDistance:%f",startDistance,endDistance);

65         float scale = this->getScale()*(endDistance/startDistance);

66         if(scale<0.5f){

67             scale = 0.5f;

68         }else if(scale>3.0f){

69             scale = 3.0f;

70         }

71         this->setScale(scale);

72     }else if(touchesDic->count() ==1){//单点

73         CCTouch *pTouch = (CCTouch*)touchesDic->objectForKey(((CCString*)keys->objectAtIndex(0))->getCString());

74         CCPoint start = pTouch->getPreviousLocation();

75         CCPoint end = pTouch->getLocation();

76         //计算位移,直接使用point充当position的话,会有偏差,比如点住图片的一角进行拖动,setPosition的时候是依据AnchorPoint进行设置的

77         CCPoint sub = ccpSub(end, start);

78         CCPoint newPosition = ccpAdd(this->getPosition(),sub);

79         this->setPosition(newPosition);

80     }

81 }

82 void MySprite::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){

83     //CCLog("****ccTouchesEnded*");

84 }

85 void MySprite::ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent){

86     //CCLog("****ccTouchesCancelled*");

87 }
View Code

 

 

你可能感兴趣的:(cocos2dx)