上代码:
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;//最小缩放值,最好不要设置为0
float m_fMaxScale =4.0f;//最大缩放值,根据实际情况设定
float m_fScale =1.0f;//当前缩放值,这里注意,一定不要设置成0,因为cocos2d-x默认的缩放值就是1.0
float m_fdistance =0.0f;//位移
cocos2d::Vec2 m_pMiddlePoint;//触摸中点
//cocos2d::Vec2 m_pBoderOrigin;//左下角的边界点
//cocos2d::Vec2 m_pBoderMax;//右上角的边界点
void scaleMap(Point pt1,Point pt2);
vector<int> m_touchIDVec;//触摸点ID
map<int,cocos2d::Vec2> m_touchPointMap;//触摸点位置
};
#endif /* MapZoom_hpp */
2.MapZoom.cpp
//
// MapZoom.cpp
// Hello-mobile
//
// Created by LiYong on 2018/2/2.
//
#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_fMinScale
m_fScale = min(m_fScale,m_fMaxScale);//缩放比例最大不能超过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
原文地址:https://www.jb51.cc/cocos2dx/338227.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。