前端之家收集整理的这篇文章主要介绍了
cocos2d-x 3.16实现地图任意缩放,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
1.MapZoom.hpp
- #ifndef MapZoom_hpp
- #define MapZoom_hpp
-
- #include <stdio.h>
- #include <cocos2d.h>
-
- using namespace std;
- USING_NS_CC;
- class MapZoom : public Layer
- {
- public:
- enum{
- TAG_MAP,};
- MapZoom();
- ~MapZoom();
- static Scene *scene();
-
- bool init() override;
-
- virtual void onTouchesBegan(const vector<Touch*> &touches,Event *event) override;
- virtual void onTouchesMoved(const vector<Touch*> &touches,Event *event) override;
- virtual void onTouchesEnded(const vector<Touch*> &touches,Event *event) override;
- virtual void onTouchesCanceled(const vector<Touch*> &touches,Event *event);
-
- CREATE_FUNC(MapZoom);
- private:
-
- float m_fMinScale =0.1f;
- float m_fMaxScale =4.0f;
- float m_fScale =1.0f;
- float m_fDistance =0.0f;
-
- cocos2d::Vec2 m_pMiddlePoint;
-
-
-
- void scaleMap(Point pt1,Point pt2);
-
- vector<int> m_touchIDVec;
- map<int,cocos2d::Vec2> m_touchPointMap;
- };
- #endif /* MapZoom_hpp */
2.MapZoom.cpp
-
- #include "MapZoom.hpp"
- MapZoom::MapZoom()
- {
-
- }
- MapZoom::~MapZoom()
- {
-
- }
- Scene *MapZoom::scene()
- {
- MapZoom *pLayer = MapZoom::create();
- Scene *scene = Scene::create();
- scene->addChild(pLayer);
- return scene;
- }
- bool MapZoom::init()
- {
- if (!Layer::init())
- {
- return false;
- }
-
- Size winSize = Director::getInstance()->getWinSize();
- Sprite *sprite = Sprite::create("white.jpeg");
- sprite->setPosition(Vec2(winSize.width/2,winSize.height/2));
- sprite->setTag(TAG_MAP);
- addChild(sprite,0);
- EventListenerTouchAllAtOnce *listener = EventListenerTouchAllAtOnce::create();
-
- listener->onTouchesBegan = CC_CALLBACK_2(MapZoom::onTouchesBegan,this);
- listener->onTouchesMoved = CC_CALLBACK_2(MapZoom::onTouchesMoved,this);
- listener->onTouchesEnded = CC_CALLBACK_2(MapZoom::onTouchesEnded,this);
- listener->onTouchesCancelled = CC_CALLBACK_2(MapZoom::onTouchesCancelled,this);
- _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener,sprite);
-
- return true;
- }
- void MapZoom::onTouchesBegan(const vector<Touch*> &touches,Event *event)
- {
- Sprite *sprite = dynamic_cast<Sprite*>(getChildByTag(TAG_MAP));
- if (sprite)
- {
- sprite->stopAllActions();
- }
- unsigned long num = touches.size();
- if (num > 1)
- {
- for(Touch *elem:touches)
- {
- m_touchIDVec.push_back(elem->getID());
- m_touchPointMap[elem->getID()] = elem->getLocation();
- }
- }
- if (m_touchIDVec.size()>=2)
- {
- auto touchPoint = m_touchIDVec.begin();
- auto mPoint = m_touchPointMap[(*touchPoint)];
- ++touchPoint;
- auto mPoint2 = m_touchPointMap[(*touchPoint)];
-
- if (m_fDistance == 0.0)
- {
- m_fDistance = mPoint.distance(mPoint);
- m_pMiddlePoint = mPoint.getMidpoint(mPoint2);
- }
-
- }
- }
- void MapZoom::onTouchesMoved(const vector<Touch*> &touches,Event *event)
- {
- if (touches.size() >= 2)
- {
- for(Touch *iter : touches)
- {
- if (find(m_touchIDVec.begin(),m_touchIDVec.end(),iter->getID()) == m_touchIDVec.end())
- {
- m_touchIDVec.push_back(iter->getID());
- }
-
- m_touchPointMap[iter->getID()] = iter->getLocation();
- }
- auto touchPoint = m_touchIDVec.begin();
- auto mPoint = m_touchPointMap[(*touchPoint)];
- ++touchPoint;
- auto mPoint2 = m_touchPointMap[(*touchPoint)];
-
- if (m_fDistance == 0)
- {
- m_fDistance = mPoint.distance(mPoint2);
- m_pMiddlePoint = mPoint.getMidpoint(mPoint2);
- return;
- }
- scaleMap(mPoint,mPoint2);
- }
- else if (touches.size() == 1)
- {
- auto iter = touches.cbegin();
- Sprite *sprite = dynamic_cast<Sprite *>(this->getChildByTag(TAG_MAP));
- Point endPoint = sprite->getParent()->convertTouchToNodeSpace(*iter);
- if (find(m_touchIDVec.begin(),(*iter)->getID()) == m_touchIDVec.end())
- {
- m_touchIDVec.push_back((*iter)->getID());
- m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
- return;
- }
- if (m_touchIDVec.size() == 1)
- {
- Point pos1 = m_touchPointMap[(*iter)->getID()];
- m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
- Point pos2 = endPoint - pos1 + sprite->getPosition();
- sprite->setPosition(pos2);
- m_fDistance = 0;
- }
- else if (m_touchIDVec.size() >= 2)
- {
- m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
- auto touchPoint = m_touchIDVec.begin();
- auto pt1 = m_touchPointMap[(*touchPoint)];
- ++touchPoint;
- auto pt2 = m_touchPointMap[(*touchPoint)];
- scaleMap(pt1,pt2);
- }
- }
-
- }
- void MapZoom::onTouchesEnded(const vector<Touch*> &touches,Event *event)
- {
- for (Touch *iter : touches)
- {
- int touchId = iter->getID();
- if (m_touchPointMap.find(touchId) != m_touchPointMap.end())
- {
- m_touchPointMap.erase(touchId);
- }
- auto idter = find(m_touchIDVec.begin(),touchId);
- if (idter != m_touchIDVec.end())
- {
- m_touchIDVec.erase(idter);
- }
- }
- if (m_touchPointMap.empty())
- {
- m_fDistance = 0;
-
- }
- else if (m_touchPointMap.size() >= 2)
- {
- auto touchPoint = m_touchIDVec.begin();
- auto pt1 = m_touchPointMap[(*touchPoint)];
- ++touchPoint;
- auto pt2 = m_touchPointMap[*touchPoint];
- m_fDistance = pt1.distance(pt2);
- }
- }
- void MapZoom::onTouchesCanceled(const vector<Touch*> &touches,Event *event)
- {
- m_fDistance = 0;
- m_touchPointMap.clear();
- m_touchIDVec.clear();
- }
- void MapZoom::scaleMap(Point pt1,Point pt2)
- {
- Sprite *sprite = dynamic_cast<Sprite *>(this->getChildByTag(TAG_MAP));
-
- float newdis = pt1.distance(pt2);
- m_fScale = newdis*m_fScale/m_fDistance;
-
- Point midPt = pt1.getMidpoint(pt2);
- Point curlMidNodePt = sprite->getParent()->convertToNodeSpace(midPt);
- Point oldMidNodePt = sprite->getParent()->convertToNodeSpace(m_pMiddlePoint);
- Point newPos = 2*curlMidNodePt - oldMidNodePt;
-
- midPt = sprite->convertToNodeSpace(midPt);
- Point newAnchorPoint = Vec2(midPt.x/sprite->getContentSize().width,midPt.y/sprite->getContentSize().height);
-
- m_fScale = max(m_fScale,m_fMinScale);
- m_fScale = min(m_fScale,m_fMaxScale);
- float spScale = sprite->getScale();
- float newScale = spScale + (m_fScale - spScale)*0.25;
- if (abs(newScale - sprite->getScale()) > 0.01f)
- {
- sprite->setScale(newScale);
- }
- sprite->setPosition(newPos);
- sprite->setAnchorPoint(newAnchorPoint);
- m_pMiddlePoint = pt1.getMidpoint(pt2);
- m_fDistance = newdis;
- }
- 1)注意cocos2d-x默认不开启多点触摸
- 2)最小缩放最好不要设置为0
参考文章:
cocos2d-x简单实现地图的缩放