重新写了地图双指缩放和单指拖动,适合所有机型屏幕配置

前端之家收集整理的这篇文章主要介绍了重新写了地图双指缩放和单指拖动,适合所有机型屏幕配置前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前面已经写过一篇了,在这里就不具体解释细节了,大体原理都是一样的,双指缩放还是根据双指间占原距离的比例进行缩放。下面直接上代码了:

.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);

这样就能解决缩放与拖动了。

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