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

 

 

posted @ 2013-12-29 00:15  韩宏敏  阅读(626)  评论(0编辑  收藏  举报