首页 > 代码库 > 9. Cocos2d-x 游戏编程 之 多点触碰

9. Cocos2d-x 游戏编程 之 多点触碰

上一篇内容讲了 单点触碰,然后这篇接着讲 多点触碰。多点触碰就是说,多个手指同时在屏幕上操作,然后触发监听器,回调方法实现功能而已。


1、先了解这个代码如何在手机上调试。因为这个是关乎到多个手指触碰才能触发的监听器,所以说,在模拟器上实现不了手指的触碰。必须在真机上跑才行。

其实很简单,只要在项目中的 ios 这个文件夹中的 AppController.mm 文件里边的 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { } 方法内 补上一句 [eaglView setMultipleTouchEnabled:YES]; 就行了,详细请看图:



2、然后,我们就要上代码了,很简单的,只不过是在单点触碰的基础上把 onTouchBegan 等这些个单词变成复数 onTouchesBegan 等词而已,上过英语课的都懂。

代码(Firth.h):

#include "cocos2d.h"

USING_NS_CC;

class FirthTest : public cocos2d::Layer
{
/* TouchAllAtOnce */
private:
    double _distance;   //两个触摸点之间的距离
    double _deltax;     //x 轴的改变值
    double _deltay;     //y 轴的改变值
    Sprite *_bgSprite;  //精灵
    double _mscale;     //缩放比例
public:
    static cocos2d::Scene* createScene();
    
    virtual bool init();
    
    /* TouchAllAtOnce */
    void onTouchesBegan(const std::vector<Touch *> &touches, cocos2d::Event *event);
    void onTouchesMoved(const std::vector<Touch *> &touches, cocos2d::Event *event);
    void onTouchesEnded(const std::vector<Touch *> &touches, cocos2d::Event *event);
    void onTouchesCancelled(const std::vector<Touch *> &touches, cocos2d::Event *event);
    
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    void scale9();
    
    CREATE_FUNC(FirthTest);
};
#endif /* defined(__HelloWorld__Fireth__) */

(Firth.cpp)

USING_NS_CC;

Scene* FirthTest::createScene()
{
    auto scene = Scene::create();
    auto layer = FirthTest::create();
    scene->addChild(layer);
    return scene;
}

bool FirthTest::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    /**
     *  获得可见OpenGL视图大小
     */
    Size size = Director::getInstance()->getVisibleSize();
    
    /**
     *  获得可见OpenGL视图起始点(0,0)
     */
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
    /**
     *  创建菜单项
     */
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(FirthTest::menuCloseCallback, this));
    
    closeItem->setPosition(Vec2(origin.x + size.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));
    
    /**
     *  创建菜单
     */
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);
    
    /**
     *  创建标题
     */
    auto title = Label::createWithSystemFont("多点触碰", "", 50);
    title->setPosition(size.width / 2 , size.height * 0.9);
    this->addChild(title);
    
    /**
     *  创建一个精灵
     */
    _bgSprite = Sprite::create("HelloWorld.png");
    _bgSprite->setPosition(Vec2(size.width / 2 + origin.x , size.height / 2 + origin.y));
    this->addChild(_bgSprite , 0);
    
    _mscale = 1.0;
    
    /**
     *  创建多点触碰监听器
     */
    auto listener = EventListenerTouchAllAtOnce::create();
    
    listener->onTouchesBegan = CC_CALLBACK_2(FirthTest::onTouchesBegan, this);
    listener->onTouchesMoved = CC_CALLBACK_2(FirthTest::onTouchesMoved, this);
    listener->onTouchesEnded = CC_CALLBACK_2(FirthTest::onTouchesMoved, this);
    listener->onTouchesCancelled = CC_CALLBACK_2(FirthTest::onTouchesMoved, this);
    
    /**
     *  注册监听事件
     */
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
    
    return true;
}
void FirthTest::onTouchesBegan(const std::vector<Touch *> &touches, cocos2d::Event *event)
{
    if (touches.size() >= 2) {
        
        //获取第一个点
        auto touch1 = touches.at(0);
        
        Vec2 myPoint1 = touch1->getLocation();
        
        //获取第二个点
        auto touch2 = touches.at(1);
        
        Vec2 myPoint2 = touch2->getLocation();
        
        /**
         *  勾股定理,算出两点距离
         */
        _distance = sqrt((myPoint2.x - myPoint1.x) * (myPoint2.x - myPoint1.x) +
                         (myPoint2.x - myPoint1.x) * (myPoint2.y - myPoint1.y));
        
    }
}

void FirthTest::onTouchesMoved(const std::vector<Touch *> &touches, cocos2d::Event *event)
{
    if (touches.size() >= 2) {
        //获取第一个点
        auto touch1 = touches.at(0);
        
        Vec2 myPoint1 = touch1->getLocation();
        
        //获取第二个点
        auto touch2 = touches.at(1);
        
        Vec2 myPoint2 = touch2->getLocation();
        
        /**
         *  勾股定理,算出两点距离
         */
        double mdistance = sqrt((myPoint2.x - myPoint1.x) * (myPoint2.x - myPoint1.x) +
                         (myPoint2.x - myPoint1.x) * (myPoint2.y - myPoint1.y));
        <span class="s1" style="font-family: Arial, Helvetica, sans-serif;">// </span><span class="s2" style="font-family: Arial, Helvetica, sans-serif;">新的距离</span><span class="s1" style="font-family: Arial, Helvetica, sans-serif;">/</span><span class="s2" style="font-family: Arial, Helvetica, sans-serif;">老的距离</span><span class="s1" style="font-family: Arial, Helvetica, sans-serif;">*</span><span class="s2" style="font-family: Arial, Helvetica, sans-serif;">原来的缩放比例,即为新的缩放比例</span>
        _mscale = mdistance / _distance * _mscale;
        
        _distance = mdistance;
        //设置新的比例
        _bgSprite->setScale(_mscale);
    }
}
void FirthTest::onTouchesEnded(const std::vector<Touch *> &touches, cocos2d::Event *event)
{}
void FirthTest::onTouchesCancelled(const std::vector<Touch *> &touches, cocos2d::Event *event)
{}

void FirthTest::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
    MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    return;
#endif
    
    Director::getInstance()->end();
    
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}


其实代码没有难度,就看注释吧,挺详细的了。


第九章,结束!

本篇内容属原创,转载请注明出处,禁止用于商业用途。谢谢!

9. Cocos2d-x 游戏编程 之 多点触碰