cocos2d-x 多点触控实现缩放及相关问题的解决方法

首先,来看下代码:

声明文件:

#ifndef __loading__MoreTouches__
#define __loading__MoreTouches__

#include 
#include "cocos2d.h"
USING_NS_CC;
class MoreTouches :public CCLayer
{
public:
    bool init();
    //virtual void registerWithTouchDispather(void);    //由于是继承自CCLayer,这个方法就不用重写了,但下面几个方法还是要重写滴
    virtual void ccTouchesCancellnd(CCSet *pTouches,CCEvent *pEvent);
    virtual void ccTouchesBegan(CCSet *pTouches,CCEvent *pEvent);//注意这个方法和单点触控方法的返回类型不同
    virtual void ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent);
    virtual void ccTouchesMoved(CCSet *pTouches,CCEvent *pEvent);
    static CCScene *scene();
    virtual void onEnter();
    virtual void onExit();
    CREATE_FUNC(MoreTouches);
    
public:
    double distance;    //两个触摸点之间的距离
    double deltax;    //目标x轴的改变值
    double deltay;    //目标y轴的改变值
    CCSprite *bg;     //目标精灵
    double mscale;   //初始地图缩放比例
    
};

#endif /* defined(__loading__MoreTouches__) */

定义文件:

#include "MoreTouches.h"

bool MoreTouches::init()
{
    if(!CCLayer::init())
    {
        return false;
    }
    bg=CCSprite::create("fullbg.png");   //初始化目标图片
    this->addChild(bg);

    mscale=1.0;     //初始化图片的缩放比例
    return true;
}

//void MoreTouches::registerWithTouchDispather()
//{
//    CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);
//}

void MoreTouches::ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
    if(pTouches->count()>=2)  //如果触摸点不少于两个
    {
        CCSetIterator iter=pTouches->begin();
        CCPoint mPoint1=((CCTouch *)(*iter))->getLocationInView();
        mPoint1 = CCDirector::sharedDirector()->convertToGL(mPoint1);
        iter++;
        CCPoint mPoint2=((CCTouch *)(*iter))->getLocationInView();
        mPoint2 = CCDirector::sharedDirector()->convertToGL(mPoint2);
        
        distance=sqrt((mPoint2.x-mPoint1.x)*(mPoint2.x-mPoint1.x)+(mPoint2.y-mPoint1.y)*(mPoint2.y-mPoint1.y));//计算两个触摸点距离
        deltax = (mPoint1.x + mPoint2.x)/2 - bg->getPositionX();     //得到两个触摸点中点和精灵锚点的差值
        deltay = (mPoint1.y + mPoint2.y)/2 - bg->getPositionY();
        CCLog("ccTouchesBegan  ...");
    
    }
}
void MoreTouches::ccTouchesMoved(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
    if(pTouches->count()>=2)  //如果移动时触摸点的个数不少于两个
    {
        CCSetIterator iter = pTouches->begin();
        CCPoint mPoint1 = ((CCTouch*)(*iter))->getLocationInView();
        mPoint1 = CCDirector::sharedDirector()->convertToGL(mPoint1);
        iter++;
        CCPoint mPoint2 = ((CCTouch*)(*iter))->getLocationInView();
        mPoint2 = CCDirector::sharedDirector()->convertToGL(mPoint2);        //获得新触摸点两点之间的距离
        double mdistance = sqrt((mPoint1.x-mPoint2.x)*(mPoint1.x-mPoint2.x)+(mPoint1.y-mPoint2.y)*(mPoint1.y-mPoint2.y));
        mscale = mdistance/distance * mscale;                      //   新的距离 / 老的距离  * 原来的缩放比例,即为新的缩放比例
        distance = mdistance;
        bg->setScale(mscale);
        
        double x = (mPoint2.x+mPoint1.x)/2 - deltax;      //计算两触点中点与精灵锚点的差值
        double y = (mPoint2.y+mPoint1.y)/2 - deltay;
        bg->setPosition(ccp(x,y));                        //保持两触点中点与精灵锚点的差值不变
        deltax = (mPoint1.x+ mPoint2.x)/2 - bg->getPositionX();       //计算新的偏移量
        deltay = (mPoint2.y + mPoint1.y)/2 - bg->getPositionY();
        CCLog("ccTouchMoved  ....");
    }
    if(pTouches->count()==1)                          //如果触摸点为一个
    {
        CCSetIterator iter =  pTouches->begin();
        CCPoint mPoint=((CCTouch*)(*iter))->getLocationInView();
        mPoint=CCDirector::sharedDirector()->convertToGL(mPoint);    //坐标转换
        bg->setPosition(mPoint);                    //直接移动精灵
    }
}
void MoreTouches::ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
    
}
void MoreTouches::ccTouchesCancellnd(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent)
{
    
}
CCScene *MoreTouches::scene()
{
    CCScene *scene=CCScene::create();
    MoreTouches *layer=MoreTouches::create();
    scene->addChild(layer);
    return scene;
}
void MoreTouches::onEnter()
{
    CCLayer::onEnter();
    setTouchEnabled(true);CCLog("onenter");
}
void MoreTouches::onExit()
{
    CCLayer::onExit();
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);     //移除触摸代理
}

        首先要实现缩放这个逻辑,在ccTouchesBegan中检测,如果触摸点的个数大于两个,那么取前两个点,使用两点距离公式计算两点距离,在ccTouchesMoved中检测,如果触摸点的个数大于两个,那么继续计算这两个点的距离,然后通过距离,计算得到缩放比例,调用setScale设置缩放比例即可。

        另外,除了缩放处理外,还需要处理位置问题,在ccTouchesBegan中计算两个触点的中点位置和精灵锚点的差,在ccTouchesMoved中,随着缩放,保持两触点中点和精灵锚点的差不变即可,ccTouchesEnded和ccTouchesCancelled中不需要修改。

        接下来,就重点说下在实现时遇到的问题吧,主要就一个,就是当在ios模拟器中操作时,我按着option键,可以出现两个点,但程序中始终只能得到一个点,即count=1,

移动时也根本不能实现缩放。后来,终于谷歌出结果了,原来需要修改ios目录下的 AppController.mm文件

static AppDelegate s_sharedApplication;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    // Add the view controller's view to the window and display.
    window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
    EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]
                                     pixelFormat: kEAGLColorFormatRGBA8
                                     depthFormat: GL_DEPTH_COMPONENT16
                              preserveBackbuffer: NO
                                      sharegroup: nil
                                   multiSampling: NO
                                 numberOfSamples:0 ];

    // Use RootViewController manage EAGLView
    viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
    viewController.wantsFullScreenLayout = YES;
    viewController.view = __glView;

    // Set RootViewController to window
    if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
    {
        // warning: addSubView doesn't work on iOS6
        [window addSubview: viewController.view];
    }
    else
    {
        // use this method on ios6
        [window setRootViewController:viewController];
    }
    [window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarHidden: YES];
    cocos2d::CCApplication::sharedApplication()->run();
    [__glView setMultipleTouchEnabled:YES];    //主要就是这句了
    return YES;
}
简单来说,就是: AppController.mm 里要启用多点触摸才可以,在- (BOOL)application:(UIApplication *)application添加[__glView setMultipleTouchEnabled:YES];
这样,当我们按着option键和鼠标时,移动鼠标,就可以实现缩放了,当只用鼠标时,可以实现图片的移动,问题解决。

你可能感兴趣的:(Cocos2d-x学习笔记)