总体思路是
先对当前屏幕截屏,然后利用clippingnode 对截屏进行显示,同时对截屏进行放大达到放大镜的效果
实现细节如下:
1 利用renderTexture对屏幕进行截图
2 创建一个放大镜类,该类包含一个clippingnode,clippingnode的显示区域为放大镜的镜头区域。将屏幕截图作为child添加到clippingnode里面。通过镜头区域的移动来控制内容的显示
3 为放大镜类添加一个放大镜的手柄,移动手柄来控制clippingnode显示区域的移动。
4 注意放大镜的中心点在屏幕中的位置(百分比),通过该位置来决定屏幕截图的注册点。可以先将屏幕截图的注册点修改后,再将截图正中显示,再缩放。注册点改变后,显示坐标不变的方法是:
之前坐标是 (x1,y1) 之前注册点是 anchpoint1,新设置的注册点是 anchpoint2
那么之后坐标为
x2 = x1 +(anchpoint2.x - anchpoint1.x) * width
y2 = y1 +(anchpoint2.y - anchpoint1.y) * height
实现代码如下:
#ifndef __STTouchableSprite__
#define __STTouchableSprite__
#include "cocos2d.h"
#include "STMacro.h"
NS_ST_BEGIN
class STTouchableSprite : public cocos2d::Sprite
{
cocos2d::EventListenerTouchOneByOne *m_pListener;
public:
static STTouchableSprite * create();
static STTouchableSprite* create(const std::string& filename);
static STTouchableSprite* createWithSpriteFrame(cocos2d::SpriteFrame *spriteFrame);
static STTouchableSprite* createWithSpriteFrameName(const std::string& spriteFrameName);
void setTouchEnable(std::function<bool(cocos2d::Touch*, cocos2d::Event*)> began,
std::function<void(cocos2d::Touch*, cocos2d::Event*)> moved = nullptr,
std::function<void(cocos2d::Touch*, cocos2d::Event*)> ended = nullptr,
std::function<void(cocos2d::Touch*, cocos2d::Event*)> cancelled = nullptr);
void setTouchDisable();
protected:
STTouchableSprite();
virtual ~STTouchableSprite();
};
NS_ST_END
#endif
#include "STTouchableSprite.h"
USING_NS_CC;
USING_NS_ST;
using namespace std;
STTouchableSprite * STTouchableSprite::create()
{
auto sprite = new (std::nothrow) STTouchableSprite();
if ( sprite && sprite->init() )
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}
STTouchableSprite *STTouchableSprite::create(const std::string& filename)
{
STTouchableSprite *sprite = new (std::nothrow) STTouchableSprite();
if (sprite && sprite->initWithFile(filename))
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}
STTouchableSprite *STTouchableSprite::createWithSpriteFrame(cocos2d::SpriteFrame *spriteFrame)
{
STTouchableSprite *sprite = new (std::nothrow) STTouchableSprite();
if (sprite && spriteFrame && sprite->initWithSpriteFrame(spriteFrame))
{
sprite->autorelease();
return sprite;
}
CC_SAFE_DELETE(sprite);
return nullptr;
}
STTouchableSprite *STTouchableSprite::createWithSpriteFrameName(const std::string& spriteFrameName)
{
SpriteFrame *frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(spriteFrameName);
return createWithSpriteFrame(frame);
}
STTouchableSprite::STTouchableSprite()
: m_pListener(nullptr)
{
}
STTouchableSprite::~STTouchableSprite()
{
}
void STTouchableSprite::setTouchEnable(function<bool(Touch*, Event*)> began,
function<void(Touch*, Event*)> moved,
function<void(Touch*, Event*)> ended,
function<void(Touch*, Event*)> cancelled)
{
m_pListener = EventListenerTouchOneByOne::create();
m_pListener->setSwallowTouches(true);
m_pListener->onTouchBegan = began;
m_pListener->onTouchMoved = moved;
m_pListener->onTouchEnded = ended;
m_pListener->onTouchCancelled = cancelled;
_eventDispatcher->addEventListenerWithSceneGraphPriority(m_pListener, this);
}
void STTouchableSprite::setTouchDisable()
{
if (m_pListener)
_eventDispatcher->removeEventListener(m_pListener);
}