您的位置:首页 > 移动开发 > Cocos引擎

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

2013-12-29 00:15 330 查看
紧接上一篇,现在我们去掉单点触摸的注册,仅使用多点触摸来实现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

//
//  MySprite.cpp
//  TouchesTest
//
//  Created by HanHongmin on 13-12-28.
//
//

#include "MySprite.h"

MySprite* MySprite::create(const char* pszFileName){
MySprite *pobSprite = new MySprite();
if (pobSprite && pobSprite->initWithFile(pszFileName))
{
pobSprite->autorelease();
return pobSprite;
}
CC_SAFE_DELETE(pobSprite);
return NULL;
}

void MySprite::onEnter(){
CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);//多点触控
//CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);//单点触控
CCSprite::onEnter();
}
void MySprite::onExit(){
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
CCSprite::onExit();
}

// optional
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);
float scale = this->getScale()*(endDistance/startDistance);
if(scale<0.5f){
scale = 0.5f;
}else if(scale>3.0f){
scale = 3.0f;
}
this->setScale(scale);
}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);
}
}
void MySprite::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){
//CCLog("****ccTouchesEnded*");
}
void MySprite::ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent){
//CCLog("****ccTouchesCancelled*");
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: