前面已经写过一篇了,在这里就不具体解释细节了,大体原理都是一样的,双指缩放还是根据双指间占原距离的比例进行缩放。下面直接上代码了:
.h
#ifndef __MAPLAYER_H #define __MAPLAYER_H #include "cocos2d.h" using namespace cocos2d; class MapLayer:public Layer { public: Vec2 mpOrigin; virtual bool init(); CREATE_FUNC(MapLayer); private: }; #endif // !__MAPLAYER_H
下面是 .cpp注释写的很详细不明白的话可以细看
auto dis = Director::getInstance()->getEventDispatcher(); auto listen = EventListenerTouchAllAtOnce::create(); listen->onTouchesMoved = [=](const std::vector<Touch*>& touches,Event *event){ if(touches.size() > 1) // 多点进行缩放 { // 得到当前两触摸点 auto point1 = touches[0]->getLocation(); auto point2 = touches[1]->getLocation(); // 计算两点之间得距离 auto currDistance = point1.distance(point2); // 计算两触摸点上一时刻之间得距离 auto prevDistance = touches[0]->getPrevIoUsLocation().distance(touches[1]->getPrevIoUsLocation()); // 两触摸点与原点的差向量,pointVec1和pointVec2是相对于maplayer的位置 auto pointVec1 = point1 - mpOrigin; auto pointVec2 = point2 - mpOrigin; // 两触摸点的相对中点 auto relMidx = (pointVec1.x + pointVec2.x) / 2 ; auto relMidy = (pointVec1.y + pointVec2.y) / 2 ; // 计算maplayer的锚点 auto anchorX = relMidx / maplayer->getBoundingBox().size.width; auto anchorY = relMidy / maplayer->getBoundingBox().size.height; // 相对屏幕的中点 auto absMidx = (point2.x + point1.x) / 2 ; auto absMidy = (point2.y + point1.y) / 2 ; // 缩放时,为了避免出现空白的区域,需要做以下的边界处理。 // 当bgSprite快要进入到屏幕时,修改maplayer的位置(既absMidx和absMidy)。 if( mpOrigin.x > 0) { absMidx -= mpOrigin.x; } if( mpOrigin.x < -maplayer->getBoundingBox().size.width + winSize.width ) { absMidx += -maplayer->getBoundingBox().size.width + winSize.width - mpOrigin.x; } if( mpOrigin.y > 0 ) { absMidy -= mpOrigin.y; } if( mpOrigin.y < -maplayer->getBoundingBox().size.height + winSize.height ) { absMidy += -maplayer->getBoundingBox().size.height + winSize.height - mpOrigin.y; } // 重设bgSprite锚点和位置 maplayer->setAnchorPoint(Vec2(anchorX,anchorY)); maplayer->setPosition(Vec2(absMidx,absMidy)); // 根据两触摸点前后的距离计算缩放倍率 auto scalex = maplayer->getScaleX() * (currDistance / prevDistance); auto scaley = scalex * RATIO; // 控制缩放倍率在1~4倍之间,最小倍率不能太小,不让背景将不能填充满整个屏幕。 scalex = MIN(1.8,MAX(preScalex,scalex)); scaley = MIN(1.8,MAX(preScaley,scaley)); maplayer->setScale(scalex,scaley); // 更新原点位置 mpOrigin = Vec2(absMidx,absMidy) - Vec2(maplayer->getBoundingBox().size.width * anchorX,maplayer->getBoundingBox().size.height * anchorY) ; } else if(touches.size() == 1) // 单点进行移动 { // 单点时,touches中只有一个Touch对象,所以通过touches[0]就可以得到触摸对象 auto touch = touches[0]; // 计算滑动过程中的滑动增量 auto diff = touch->getDelta(); // 得到当前maplayer的位置 auto currentPos = maplayer->getPosition(); // 得到滑动后maplayer应该所在的位置 auto pos = currentPos + diff; // 得到此刻maplayer的尺寸 auto maplayerCurrSize = maplayer->getBoundingBox().size; //边界控制,约束pos的位置 pos.x = MIN(pos.x,maplayerCurrSize.width * maplayer->getAnchorPoint().x); pos.x = MAX(pos.x,-maplayerCurrSize.width + winSize.width + maplayerCurrSize.width * maplayer->getAnchorPoint().x); pos.y = MIN(pos.y,maplayerCurrSize.height * maplayer->getAnchorPoint().y); pos.y = MAX(pos.y,-maplayerCurrSize.height + winSize.height + maplayerCurrSize.height * maplayer->getAnchorPoint().y); // 重设bgSprite位置 maplayer->setPosition(pos); // 更新原点位置 if( pos.x >= maplayerCurrSize.width * maplayer->getAnchorPoint().x || pos.x <= -maplayerCurrSize.width + winSize.width + maplayerCurrSize.width * maplayer->getAnchorPoint().x) { diff.x = 0; } if( pos.y >= maplayerCurrSize.height * maplayer->getAnchorPoint().y || pos.y <= -maplayerCurrSize.height + winSize.height + maplayerCurrSize.height * maplayer->getAnchorPoint().y) { diff.y = 0; } mpOrigin += diff; } }; dis->addEventListenerWithSceneGraPHPriority(listen,maplayer);
这样就能解决缩放与拖动了。