简单手势识别

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

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

代码如下:

  1. //
  2. // CGesture.h
  3. // ActionLabel
  4. //
  5. // Created by xujw on 16/3/15.
  6.  
  7. /* 手势识别 仿iphone 简单长按 点击(双击等) 滑动 拖动等。 * 使用方法: * auto gesture = CGesture::createTapGesture(target,callback,taps); * this->addChild(gestrue) */
  8.  
  9. #ifndef CGesture_h
  10. #define CGesture_h
  11.  
  12. #include <stdio.h>
  13. #include "cocos2d.h"
  14. USING_NS_CC;
  15.  
  16. typedef enum gestureDirection
  17. {
  18. kDirectUp = @H_404_30@0,kDirectDown = @H_404_30@1,kDirectLeft = @H_404_30@2,kDirectRight = @H_404_30@3
  19. }GestureDirection;
  20.  
  21. typedef std::function<void(Touch*)> GestureCallback;
  22. typedef std::function<void(Touch*,GestureDirection)> SwipeGestureCallback;
  23.  
  24. #define SHAKE_LENGTH 100
  25.  
  26. class CGesture:public Layer
  27. {
  28. private:
  29. bool _isCanTouch;
  30. int _tapNum;
  31. public:
  32. CGesture();
  33. ~CGesture();
  34. bool init();
  35. CREATE_FUNC(CGesture);
  36. public:
  37. //点击
  38. static CGesture* createTapGesture(Node*target,GestureCallback callback,int tapsrequired=@H_404_30@1);
  39. //长按
  40. static CGesture* createLongPressGesture(Node*target,float delay = @H_404_30@1.0f);
  41. //滑动
  42. static CGesture* createSwipeGesture(Node*target,SwipeGestureCallback callback);
  43. //拖动
  44. static CGesture* createPanGestrue(Node*target,GestureCallback callback);
  45. };
  46. #endif /* CGesture_h */
  47.  
  48. //
  49. // CGesture.cpp
  50. // ActionLabel
  51. //
  52. // Created by xujw on 16/3/15.
  53. //
  54. //
  55.  
  56. #include "CGesture.h"
  57. #include <time.h>
  58.  
  59. CGesture::CGesture()
  60. :_isCanTouch(false),_tapNum(@H_404_30@0)
  61. {}
  62. CGesture::~CGesture()
  63. {}
  64.  
  65. bool CGesture::init()
  66. {
  67. if (!Layer::init())
  68. {
  69. return false;
  70. }
  71.  
  72. return true;
  73. }
  74.  
  75. CGesture* CGesture::createTapGesture(Node*target,int tapsrequired)
  76. {
  77. CCASSERT(callback && target,"callback or target is null");
  78.  
  79. auto parent = target->getParent();
  80.  
  81. auto gesture = CGesture::create();
  82.  
  83. auto lis = EventListenerTouchOneByOne::create();
  84. lis->onTouchBegan = [=](Touch *touch,Event *event)
  85. {
  86. auto Box = target->getBoundingBox();
  87. auto pos = touch->getLocation();
  88. if (parent) {
  89. pos = parent->convertToNodeSpace(pos);
  90. }
  91. if (Box.containsPoint(pos))
  92. {
  93. gesture->_tapNum ++;
  94. }
  95.  
  96. return true;
  97. };
  98. lis->onTouchMoved = [=](Touch *touch,Event *event)
  99. {
  100. auto startPos = touch->getStartLocation();
  101. auto curPos = touch->getLocation();
  102. auto subPos = curPos - startPos;
  103. if (fabs(subPos.x)>=@H_404_30@10 || fabs(subPos.y)>=@H_404_30@10)
  104. {
  105. gesture->_tapNum = @H_404_30@0;
  106. gesture->unschedule("GestureTapNumReset");
  107. }
  108. };
  109. lis->onTouchEnded = [=](Touch *touch,Event *event)
  110. {
  111. if (gesture->_tapNum >= tapsrequired)
  112. {
  113. auto Box = target->getBoundingBox();
  114. auto pos = touch->getLocation();
  115. auto parent = target->getParent();
  116. if (parent) {
  117. pos = parent->convertToNodeSpace(pos);
  118. }
  119. if (Box.containsPoint(pos))
  120. {
  121. gesture->_tapNum = @H_404_30@0;
  122. gesture->unschedule("GestureTapNumReset");
  123. callback(touch);
  124. }
  125. }
  126. gesture->scheduleOnce([=](float dt)
  127. {
  128. gesture->_tapNum = @H_404_30@0;
  129. },@H_404_30@0.5,"GestureTapNumReset");
  130. };
  131.  
  132. gesture->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(lis,target);
  133.  
  134. return gesture;
  135. }
  136.  
  137. CGesture* CGesture::createLongPressGesture(Node*target,float delay)
  138. {
  139. CCASSERT(callback && target,Event *event)
  140. {
  141. auto Box = target->getBoundingBox();
  142. auto pos = touch->getLocation();
  143. if (parent) {
  144. pos = parent->convertToNodeSpace(pos);
  145. }
  146. if (Box.containsPoint(pos))
  147. {
  148. gesture->scheduleOnce([=](float){
  149. gesture->_isCanTouch = true;
  150. },delay,"GestureChangeTouchState");
  151. return true;
  152. }
  153. else
  154. {
  155. return false;
  156. }
  157. };
  158. lis->onTouchMoved = [=](Touch *touch,Event *event)
  159. {
  160. //长按时滑动算取消
  161. auto startPos = touch->getStartLocation();
  162. auto curPos = touch->getLocation();
  163. auto subPos = curPos - startPos;
  164. if (fabs(subPos.x)>=@H_404_30@10 || fabs(subPos.y)>=@H_404_30@10)
  165. {
  166. gesture->unschedule("GestureChangeTouchState");
  167. gesture->_isCanTouch = false;
  168. }
  169. };
  170. lis->onTouchEnded = [=](Touch *touch,Event *event)
  171. {
  172. auto Box = target->getBoundingBox();
  173. auto pos = touch->getLocation();
  174. if (parent) {
  175. pos = parent->convertToNodeSpace(pos);
  176. }
  177.  
  178. if (gesture->_isCanTouch)
  179. {
  180. if (Box.containsPoint(pos))
  181. {
  182. callback(touch);
  183. }
  184. }
  185. else
  186. {
  187. gesture->unschedule("GestureChangeTouchState");
  188. }
  189. gesture->_isCanTouch = false;
  190. };
  191.  
  192. gesture->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(lis,target);
  193.  
  194. return gesture;
  195. }
  196.  
  197. CGesture* CGesture::createSwipeGesture(Node*target,SwipeGestureCallback callback)
  198. {
  199. CCASSERT(callback && target,"callback or target is null");
  200.  
  201. auto parent = target->getParent();
  202. auto gesture = CGesture::create();
  203.  
  204. auto lis = EventListenerTouchOneByOne::create();
  205. lis->onTouchBegan = [=](Touch *touch,Event *event)
  206. {
  207. auto pos = touch->getLocation();
  208. auto Box = target->getBoundingBox();
  209. if (parent) {
  210. pos = parent->convertToNodeSpace(pos);
  211. }
  212. if (Box.containsPoint(pos))
  213. {
  214. gesture->_isCanTouch = true;
  215. }
  216. else{
  217. gesture->_isCanTouch = false;
  218. }
  219. return gesture->_isCanTouch;
  220. };
  221. lis->onTouchMoved = [=](Touch *touch,Event *event){};
  222. lis->onTouchEnded = [=](Touch *touch,Event *event)
  223. {
  224. auto pos = touch->getLocation();
  225. auto Box = target->getBoundingBox();
  226. if (parent) {
  227. pos = parent->convertToNodeSpace(pos);
  228. }
  229. //起始点都在target范围内才响应
  230. if (!gesture->_isCanTouch || !Box.containsPoint(pos))
  231. {
  232. gesture->_isCanTouch = false;
  233. return ;
  234. }
  235.  
  236. auto startPos = touch->getStartLocation();
  237. auto curPos = touch->getLocation();
  238. auto subPos = curPos - startPos;
  239.  
  240. if (fabs(subPos.x) > fabs(subPos.y))
  241. {
  242. //左右移动
  243. if (subPos.x > SHAKE_LENGTH)
  244. {
  245. //向右移动
  246. callback(touch,kDirectRight);
  247. }
  248. else if (subPos.x < -SHAKE_LENGTH)
  249. {
  250. //向左移动
  251. callback(touch,kDirectLeft);
  252. }
  253. }
  254. else
  255. {
  256. if (subPos.y > SHAKE_LENGTH)
  257. {
  258. //向上移动
  259. callback(touch,kDirectUp);
  260. }
  261. else if (subPos.y < -SHAKE_LENGTH)
  262. {
  263. //向下移动
  264. callback(touch,kDirectDown);
  265. }
  266. }
  267. };
  268. gesture->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(lis,gesture);
  269. return gesture;
  270. }
  271.  
  272. CGesture* CGesture::createPanGestrue(Node*target,GestureCallback callback)
  273. {
  274. CCASSERT(callback && target,Event *event)
  275. {
  276. auto Box = target->getBoundingBox();
  277. auto pos = touch->getLocation();
  278. if (parent) {
  279. pos = parent->convertToNodeSpace(pos);
  280. }
  281. if (Box.containsPoint(pos))
  282. {
  283. gesture->_isCanTouch = true;
  284. }
  285. return true;
  286. };
  287. lis->onTouchMoved = [=](Touch *touch,Event *event)
  288. {
  289. if (gesture->_isCanTouch)
  290. {
  291. callback(touch);
  292. }
  293. };
  294. lis->onTouchEnded = [=](Touch *touch,Event *event)
  295. {
  296. gesture->_isCanTouch = false;
  297. };
  298. gesture->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(lis,target);
  299. return gesture;
  300. }

代码下载Git

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