zoukankan      html  css  js  c++  java
  • cocos2d-x 多点触控实现缩放及相关问题的解决方法

    首先,来看下代码:

    声明文件:

    #ifndef __loading__MoreTouches__
    #define __loading__MoreTouches__
    
    #include <iostream>
    #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键和鼠标时,移动鼠标,就可以实现缩放了,当只用鼠标时,可以实现图片的移动,问题解决。

  • 相关阅读:
    Orchard Oracle 支持
    讽刺的是,我在linux下使用最多的命令,竟然是windows的
    学习bash
    提高分布式环境中程序启动性能的一个方法
    MQTT X v1.4.1 正式发布
    社区力量|因为 EMQ,他上了微博热搜
    不止是现在,更关注未来:EMQ 携手高校加强物联网人才培养
    EMQ 助力西安增材制造国家研究院打造增材智能车间平台
    Kuiper 1.0.1 正式发布
    MQTT X v1.4.0 正式发布
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3292211.html
Copyright © 2011-2022 走看看