简单手势识别

前端之家收集整理的这篇文章主要介绍了简单手势识别前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

模拟iOS原生手势,简单实现点击(双击)、长按、滑动、拖动等功能

代码如下:

//
// CGesture.h
// ActionLabel
//
// Created by xujw on 16/3/15.

/* 手势识别 仿iphone 简单长按 点击(双击等) 滑动 拖动等。 * 使用方法: * auto gesture = CGesture::createTapGesture(target,callback,taps); * this->addChild(gestrue) */

#ifndef CGesture_h
#define CGesture_h

#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;

typedef enum gestureDirection
{
    kDirectUp = 0,kDirectDown = 1,kDirectLeft = 2,kDirectRight = 3
}GestureDirection;

typedef std::function<void(Touch*)> GestureCallback;
typedef std::function<void(Touch*,GestureDirection)> SwipeGestureCallback;

#define SHAKE_LENGTH 100

class CGesture:public Layer
{
private:
    bool _isCanTouch;
    int _tapNum;
public:
    CGesture();
    ~CGesture();
    bool init();
    CREATE_FUNC(CGesture);
public:
    //点击
    static CGesture* createTapGesture(Node*target,GestureCallback callback,int tapsrequired=1);
    //长按
    static CGesture* createLongPressGesture(Node*target,float delay = 1.0f);
    //滑动
    static CGesture* createSwipeGesture(Node*target,SwipeGestureCallback callback);
    //拖动
    static CGesture* createPanGestrue(Node*target,GestureCallback callback);
};
#endif /* CGesture_h */

//
// CGesture.cpp
// ActionLabel
//
// Created by xujw on 16/3/15.
//
//

#include "CGesture.h"
#include <time.h>

CGesture::CGesture()
:_isCanTouch(false),_tapNum(0)
{}
CGesture::~CGesture()
{}

bool CGesture::init()
{
    if (!Layer::init())
    {
        return false;
    }

    return true;
}

CGesture* CGesture::createTapGesture(Node*target,int tapsrequired)
{
    CCASSERT(callback && target,"callback or target is null");

    auto parent = target->getParent();

    auto gesture = CGesture::create();

    auto lis = EventListenerTouchOneByOne::create();
    lis->onTouchBegan = [=](Touch *touch,Event *event)
    {
        auto Box = target->getBoundingBox();
        auto pos = touch->getLocation();
        if (parent) {
            pos = parent->convertToNodeSpace(pos);
        }
        if (Box.containsPoint(pos))
        {
            gesture->_tapNum ++;
        }

        return true;
    };
    lis->onTouchMoved = [=](Touch *touch,Event *event)
    {
        auto startPos = touch->getStartLocation();
        auto curPos = touch->getLocation();
        auto subPos = curPos - startPos;
        if (fabs(subPos.x)>=10 || fabs(subPos.y)>=10)
        {
            gesture->_tapNum = 0;
            gesture->unschedule("GestureTapNumReset");
        }        
    };
    lis->onTouchEnded = [=](Touch *touch,Event *event)
    {
        if (gesture->_tapNum >= tapsrequired)
        {
            auto Box = target->getBoundingBox();
            auto pos = touch->getLocation();
            auto parent = target->getParent();
            if (parent) {
                pos = parent->convertToNodeSpace(pos);
            }
            if (Box.containsPoint(pos))
            {
                gesture->_tapNum = 0;
                gesture->unschedule("GestureTapNumReset");
                callback(touch);
            }
        }
        gesture->scheduleOnce([=](float dt)
        {
            gesture->_tapNum = 0;
        },0.5,"GestureTapNumReset");
    };

    gesture->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(lis,target);

    return gesture;
}

CGesture* CGesture::createLongPressGesture(Node*target,float delay)
{
    CCASSERT(callback && target,Event *event)
    {
        auto Box = target->getBoundingBox();
        auto pos = touch->getLocation();
        if (parent) {
            pos = parent->convertToNodeSpace(pos);
        }
        if (Box.containsPoint(pos))
        {
            gesture->scheduleOnce([=](float){
                gesture->_isCanTouch = true;
            },delay,"GestureChangeTouchState");
            return true;
        }
        else
        {
            return false;
        }
    };
    lis->onTouchMoved = [=](Touch *touch,Event *event)
    {
        //长按时滑动算取消
        auto startPos = touch->getStartLocation();
        auto curPos = touch->getLocation();
        auto subPos = curPos - startPos;
        if (fabs(subPos.x)>=10 || fabs(subPos.y)>=10)
        {
            gesture->unschedule("GestureChangeTouchState");
            gesture->_isCanTouch = false;
        }
    };
    lis->onTouchEnded = [=](Touch *touch,Event *event)
    {
        auto Box = target->getBoundingBox();
        auto pos = touch->getLocation();
        if (parent) {
            pos = parent->convertToNodeSpace(pos);
        }

        if (gesture->_isCanTouch)
        {
            if (Box.containsPoint(pos))
            {
                callback(touch);
            }
        }
        else
        {
            gesture->unschedule("GestureChangeTouchState");
        }
        gesture->_isCanTouch = false;
    };

    gesture->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(lis,target);

    return gesture;
}

CGesture* CGesture::createSwipeGesture(Node*target,SwipeGestureCallback callback)
{
    CCASSERT(callback && target,"callback or target is null");

    auto parent = target->getParent();
    auto gesture = CGesture::create();

    auto lis = EventListenerTouchOneByOne::create();
    lis->onTouchBegan = [=](Touch *touch,Event *event)
    {
        auto pos = touch->getLocation();
        auto Box = target->getBoundingBox();
        if (parent) {
            pos = parent->convertToNodeSpace(pos);
        }
        if (Box.containsPoint(pos))
        {
            gesture->_isCanTouch = true;
        }
        else{
            gesture->_isCanTouch = false;
        }
        return gesture->_isCanTouch;
    };
    lis->onTouchMoved = [=](Touch *touch,Event *event){};
    lis->onTouchEnded = [=](Touch *touch,Event *event)
    {
        auto pos = touch->getLocation();
        auto Box = target->getBoundingBox();
        if (parent) {
            pos = parent->convertToNodeSpace(pos);
        }
        //起始点都在target范围内才响应
        if (!gesture->_isCanTouch || !Box.containsPoint(pos))
        {
            gesture->_isCanTouch = false;
            return ;
        }

        auto startPos = touch->getStartLocation();
        auto curPos = touch->getLocation();
        auto subPos = curPos - startPos;

        if (fabs(subPos.x) > fabs(subPos.y))
        {
            //左右移动
            if (subPos.x > SHAKE_LENGTH)
            {
                //向右移动
                callback(touch,kDirectRight);
            }
            else if (subPos.x < -SHAKE_LENGTH)
            {
                //向左移动
                callback(touch,kDirectLeft);
            }
        }
        else
        {
            if (subPos.y > SHAKE_LENGTH)
            {
                //向上移动
                callback(touch,kDirectUp);
            }
            else if (subPos.y < -SHAKE_LENGTH)
            {
                //向下移动
                callback(touch,kDirectDown);
            }
        }
    };
    gesture->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(lis,gesture);
    return gesture;
}

CGesture* CGesture::createPanGestrue(Node*target,GestureCallback callback)
{
    CCASSERT(callback && target,Event *event)
    {
        auto Box = target->getBoundingBox();
        auto pos = touch->getLocation();
        if (parent) {
            pos = parent->convertToNodeSpace(pos);
        }
        if (Box.containsPoint(pos))
        {
            gesture->_isCanTouch = true;
        }
        return true;
    };
    lis->onTouchMoved = [=](Touch *touch,Event *event)
    {
        if (gesture->_isCanTouch)
        {
            callback(touch);
        }
    };
    lis->onTouchEnded = [=](Touch *touch,Event *event)
    {
        gesture->_isCanTouch = false;
    };
    gesture->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(lis,target);
    return gesture;
}

代码下载Git

猜你在找的Cocos2d-x相关文章