cocos2d-x 3.16实现地图任意缩放

前端之家收集整理的这篇文章主要介绍了cocos2d-x 3.16实现地图任意缩放前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

代码

1.MapZoom.hpp

  1. #ifndef MapZoom_hpp
  2. #define MapZoom_hpp
  3.  
  4. #include <stdio.h>
  5. #include <cocos2d.h>
  6.  
  7. using namespace std;
  8. USING_NS_CC;
  9. class MapZoom : public Layer
  10. {
  11. public:
  12. enum{
  13. TAG_MAP,};
  14. MapZoom();
  15. ~MapZoom();
  16. static Scene *scene();
  17.  
  18. bool init() override;
  19.  
  20. virtual void onTouchesBegan(const vector<Touch*> &touches,Event *event) override;
  21. virtual void onTouchesMoved(const vector<Touch*> &touches,Event *event) override;
  22. virtual void onTouchesEnded(const vector<Touch*> &touches,Event *event) override;
  23. virtual void onTouchesCanceled(const vector<Touch*> &touches,Event *event);
  24.  
  25. CREATE_FUNC(MapZoom);
  26. private:
  27.  
  28. float m_fMinScale =0.1f;//最小缩放值,最好不要设置为0
  29. float m_fMaxScale =4.0f;//最大缩放值,根据实际情况设定
  30. float m_fScale =1.0f;//当前缩放值,这里注意,一定不要设置成0,因为cocos2d-x默认的缩放值就是1.0
  31. float m_fDistance =0.0f;//位移
  32.  
  33. cocos2d::Vec2 m_pMiddlePoint;//触摸中点
  34. //cocos2d::Vec2 m_pBoderOrigin;//左下角的边界点
  35. //cocos2d::Vec2 m_pBoderMax;//右上角的边界点
  36.  
  37. void scaleMap(Point pt1,Point pt2);
  38.  
  39. vector<int> m_touchIDVec;//触摸点ID
  40. map<int,cocos2d::Vec2> m_touchPointMap;//触摸点位置
  41. };
  42. #endif /* MapZoom_hpp */

2.MapZoom.cpp

  1. //
  2. // MapZoom.cpp
  3. // Hello-mobile
  4. //
  5. // Created by LiYong on 2018/2/2.
  6. //
  7.  
  8. #include "MapZoom.hpp"
  9. MapZoom::MapZoom()
  10. {
  11.  
  12. }
  13. MapZoom::~MapZoom()
  14. {
  15.  
  16. }
  17. Scene *MapZoom::scene()
  18. {
  19. MapZoom *pLayer = MapZoom::create();
  20. Scene *scene = Scene::create();
  21. scene->addChild(pLayer);
  22. return scene;
  23. }
  24. bool MapZoom::init()
  25. {
  26. if (!Layer::init())
  27. {
  28. return false;
  29. }
  30.  
  31. Size winSize = Director::getInstance()->getWinSize();
  32. Sprite *sprite = Sprite::create("white.jpeg");
  33. sprite->setPosition(Vec2(winSize.width/2,winSize.height/2));
  34. sprite->setTag(TAG_MAP);
  35. addChild(sprite,0);
  36. EventListenerTouchAllAtOnce *listener = EventListenerTouchAllAtOnce::create();
  37.  
  38. listener->onTouchesBegan = CC_CALLBACK_2(MapZoom::onTouchesBegan,this);
  39. listener->onTouchesMoved = CC_CALLBACK_2(MapZoom::onTouchesMoved,this);
  40. listener->onTouchesEnded = CC_CALLBACK_2(MapZoom::onTouchesEnded,this);
  41. listener->onTouchesCancelled = CC_CALLBACK_2(MapZoom::onTouchesCancelled,this);
  42. _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener,sprite);
  43.  
  44. return true;
  45. }
  46. void MapZoom::onTouchesBegan(const vector<Touch*> &touches,Event *event)
  47. {
  48. Sprite *sprite = dynamic_cast<Sprite*>(getChildByTag(TAG_MAP));
  49. if (sprite)
  50. {
  51. sprite->stopAllActions();
  52. }
  53. unsigned long num = touches.size();
  54. if (num > 1)
  55. {
  56. for(Touch *elem:touches)
  57. {
  58. m_touchIDVec.push_back(elem->getID());
  59. m_touchPointMap[elem->getID()] = elem->getLocation();
  60. }
  61. }
  62. if (m_touchIDVec.size()>=2)
  63. {
  64. auto touchPoint = m_touchIDVec.begin();
  65. auto mPoint = m_touchPointMap[(*touchPoint)];
  66. ++touchPoint;
  67. auto mPoint2 = m_touchPointMap[(*touchPoint)];
  68.  
  69. if (m_fDistance == 0.0)
  70. {
  71. m_fDistance = mPoint.distance(mPoint);
  72. m_pMiddlePoint = mPoint.getMidpoint(mPoint2);
  73. }
  74.  
  75. }
  76. }
  77. void MapZoom::onTouchesMoved(const vector<Touch*> &touches,Event *event)
  78. {
  79. if (touches.size() >= 2)
  80. {
  81. for(Touch *iter : touches)
  82. {
  83. if (find(m_touchIDVec.begin(),m_touchIDVec.end(),iter->getID()) == m_touchIDVec.end())
  84. {
  85. m_touchIDVec.push_back(iter->getID());
  86. }
  87.  
  88. m_touchPointMap[iter->getID()] = iter->getLocation();
  89. }
  90. auto touchPoint = m_touchIDVec.begin();
  91. auto mPoint = m_touchPointMap[(*touchPoint)];
  92. ++touchPoint;
  93. auto mPoint2 = m_touchPointMap[(*touchPoint)];
  94.  
  95. if (m_fDistance == 0)
  96. {
  97. m_fDistance = mPoint.distance(mPoint2);
  98. m_pMiddlePoint = mPoint.getMidpoint(mPoint2);
  99. return;
  100. }
  101. scaleMap(mPoint,mPoint2);
  102. }
  103. else if (touches.size() == 1)
  104. {
  105. auto iter = touches.cbegin();
  106. Sprite *sprite = dynamic_cast<Sprite *>(this->getChildByTag(TAG_MAP));
  107. Point endPoint = sprite->getParent()->convertTouchToNodeSpace(*iter);
  108. if (find(m_touchIDVec.begin(),(*iter)->getID()) == m_touchIDVec.end())
  109. {
  110. m_touchIDVec.push_back((*iter)->getID());
  111. m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
  112. return;
  113. }
  114. if (m_touchIDVec.size() == 1)
  115. {
  116. Point pos1 = m_touchPointMap[(*iter)->getID()];
  117. m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
  118. Point pos2 = endPoint - pos1 + sprite->getPosition();
  119. sprite->setPosition(pos2);
  120. m_fDistance = 0;
  121. }
  122. else if (m_touchIDVec.size() >= 2)
  123. {
  124. m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
  125. auto touchPoint = m_touchIDVec.begin();
  126. auto pt1 = m_touchPointMap[(*touchPoint)];
  127. ++touchPoint;
  128. auto pt2 = m_touchPointMap[(*touchPoint)];
  129. scaleMap(pt1,pt2);
  130. }
  131. }
  132.  
  133. }
  134. void MapZoom::onTouchesEnded(const vector<Touch*> &touches,Event *event)
  135. {
  136. for (Touch *iter : touches)
  137. {
  138. int touchId = iter->getID();
  139. if (m_touchPointMap.find(touchId) != m_touchPointMap.end())
  140. {
  141. m_touchPointMap.erase(touchId);
  142. }
  143. auto idter = find(m_touchIDVec.begin(),touchId);
  144. if (idter != m_touchIDVec.end())
  145. {
  146. m_touchIDVec.erase(idter);
  147. }
  148. }
  149. if (m_touchPointMap.empty())
  150. {
  151. m_fDistance = 0;
  152.  
  153. }
  154. else if (m_touchPointMap.size() >= 2)
  155. {
  156. auto touchPoint = m_touchIDVec.begin();
  157. auto pt1 = m_touchPointMap[(*touchPoint)];
  158. ++touchPoint;
  159. auto pt2 = m_touchPointMap[*touchPoint];
  160. m_fDistance = pt1.distance(pt2);
  161. }
  162. }
  163. void MapZoom::onTouchesCanceled(const vector<Touch*> &touches,Event *event)
  164. {
  165. m_fDistance = 0;
  166. m_touchPointMap.clear();
  167. m_touchIDVec.clear();
  168. }
  169. void MapZoom::scaleMap(Point pt1,Point pt2)
  170. {
  171. Sprite *sprite = dynamic_cast<Sprite *>(this->getChildByTag(TAG_MAP));
  172.  
  173. float newdis = pt1.distance(pt2);
  174. m_fScale = newdis*m_fScale/m_fDistance;
  175.  
  176. Point midPt = pt1.getMidpoint(pt2);
  177. Point curlMidNodePt = sprite->getParent()->convertToNodeSpace(midPt);
  178. Point oldMidNodePt = sprite->getParent()->convertToNodeSpace(m_pMiddlePoint);
  179. Point newPos = 2*curlMidNodePt - oldMidNodePt;
  180.  
  181. midPt = sprite->convertToNodeSpace(midPt);
  182. Point newAnchorPoint = Vec2(midPt.x/sprite->getContentSize().width,midPt.y/sprite->getContentSize().height);
  183.  
  184. m_fScale = max(m_fScale,m_fMinScale);//缩放比例最小不能小于m_fMinScale
  185. m_fScale = min(m_fScale,m_fMaxScale);//缩放比例最大不能超过m_fMaxScale
  186. float spScale = sprite->getScale();
  187. float newScale = spScale + (m_fScale - spScale)*0.25;
  188. if (abs(newScale - sprite->getScale()) > 0.01f)
  189. {
  190. sprite->setScale(newScale);
  191. }
  192. sprite->setPosition(newPos);
  193. sprite->setAnchorPoint(newAnchorPoint);
  194. m_pMiddlePoint = pt1.getMidpoint(pt2);
  195. m_fDistance = newdis;
  196. }
  1. 1)注意cocos2d-x默认不开启多点触摸
  2. 2)最小缩放最好不要设置为0

参考文章
cocos2d-x简单实现地图的缩放

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