cocos2d-x 3.16实现地图任意缩放

前端之家收集整理的这篇文章主要介绍了cocos2d-x 3.16实现地图任意缩放前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

代码

1.MapZoom.hpp

#ifndef MapZoom_hpp@H_301_6@
#define MapZoom_hpp@H_301_6@

#include <stdio.h>@H_301_6@
#include <cocos2d.h>@H_301_6@

using@H_301_6@ namespace@H_301_6@ std@H_301_6@;
USING_NS_CC;
class@H_301_6@ MapZoom : public@H_301_6@ Layer
{
public@H_301_6@:
    enum@H_301_6@{
        TAG_MAP,};
    MapZoom();
    ~MapZoom();
    static@H_301_6@ Scene *scene();

    bool@H_301_6@ init() override;

    virtual@H_301_6@ void@H_301_6@ onTouchesBegan(const@H_301_6@ vector@H_301_6@<Touch*>@H_301_6@ &touches,Event *event) override;
    virtual@H_301_6@ void@H_301_6@ onTouchesMoved(const@H_301_6@ vector@H_301_6@<Touch*>@H_301_6@ &touches,Event *event) override;
    virtual@H_301_6@ void@H_301_6@ onTouchesEnded(const@H_301_6@ vector@H_301_6@<Touch*>@H_301_6@ &touches,Event *event) override;
    virtual@H_301_6@ void@H_301_6@ onTouchesCanceled(const@H_301_6@ vector@H_301_6@<Touch*>@H_301_6@ &touches,Event *event);

    CREATE_FUNC(MapZoom);
private@H_301_6@:

    float@H_301_6@ m_fMinScale =0.1f@H_301_6@;//最小缩放值,最好不要设置为0@H_301_6@
    float@H_301_6@ m_fMaxScale =4.0f@H_301_6@;//最大缩放值,根据实际情况设定@H_301_6@
    float@H_301_6@ m_fScale =1.0f@H_301_6@;//当前缩放值,这里注意,一定不要设置成0,因为cocos2d-x默认的缩放值就是1.0@H_301_6@
    float@H_301_6@ m_fDistance =0.0f@H_301_6@;//位移@H_301_6@

    cocos2d::Vec2 m_pMiddlePoint;//触摸中点@H_301_6@
    //cocos2d::Vec2 m_pBoderOrigin;//左下角的边界点@H_301_6@
    //cocos2d::Vec2 m_pBoderMax;//右上角的边界点@H_301_6@

    void@H_301_6@ scaleMap(Point pt1,Point pt2);

    vector@H_301_6@<int@H_301_6@>@H_301_6@ m_touchIDVec;//触摸点ID@H_301_6@
    map@H_301_6@<int@H_301_6@,cocos2d::Vec2>@H_301_6@ m_touchPointMap;//触摸点位置@H_301_6@
};
#endif /* MapZoom_hpp */@H_301_6@

2.MapZoom.cpp

//@H_301_6@
// MapZoom.cpp@H_301_6@
// Hello-mobile@H_301_6@
//@H_301_6@
// Created by LiYong on 2018/2/2.@H_301_6@
//@H_301_6@

#include "MapZoom.hpp"@H_301_6@
MapZoom::MapZoom()
{

}
MapZoom::~MapZoom()
{

}
Scene *MapZoom::scene()
{
    MapZoom *pLayer = MapZoom::create();
    Scene *scene = Scene::create();
    scene->addChild(pLayer);
    return@H_301_6@ scene;
}
bool@H_301_6@ MapZoom::init()
{
    if@H_301_6@ (!Layer::init())
    {
        return@H_301_6@ false@H_301_6@;
    }

    Size winSize = Director::getInstance()->getWinSize();
    Sprite *sprite = Sprite::create("white.jpeg"@H_301_6@);
    sprite->setPosition(Vec2(winSize.width/2@H_301_6@,winSize.height/2@H_301_6@));
    sprite->setTag(TAG_MAP);
    addChild(sprite,0@H_301_6@);
    EventListenerTouchAllAtOnce *listener = EventListenerTouchAllAtOnce::create();

    listener->onTouchesBegan = CC_CALLBACK_2(MapZoom::onTouchesBegan,this@H_301_6@);
    listener->onTouchesMoved = CC_CALLBACK_2(MapZoom::onTouchesMoved,this@H_301_6@);
    listener->onTouchesEnded = CC_CALLBACK_2(MapZoom::onTouchesEnded,this@H_301_6@);
    listener->onTouchesCancelled = CC_CALLBACK_2(MapZoom::onTouchesCancelled,this@H_301_6@);
    _eventDispatcher->addEventListenerWithSceneGraPHPriority(listener,sprite);

    return@H_301_6@ true@H_301_6@;
}
void@H_301_6@ MapZoom::onTouchesBegan(const@H_301_6@ vector@H_301_6@<Touch*>@H_301_6@ &touches,Event *event)
{
    Sprite *sprite = dynamic_cast@H_301_6@<Sprite*>(getChildByTag(TAG_MAP));
    if@H_301_6@ (sprite)
    {
        sprite->stopAllActions();
    }
    unsigned@H_301_6@ long@H_301_6@ num = touches.size();
    if@H_301_6@ (num > 1@H_301_6@)
    {
        for@H_301_6@(Touch *elem:touches)
        {
            m_touchIDVec.push_back(elem->getID());
            m_touchPointMap[elem->getID()] = elem->getLocation();
        }
    }
    if@H_301_6@ (m_touchIDVec.size()>=2@H_301_6@)
    {
        auto@H_301_6@ touchPoint = m_touchIDVec.begin();
        auto@H_301_6@ mPoint = m_touchPointMap[(*touchPoint)];
        ++touchPoint;
        auto@H_301_6@ mPoint2 = m_touchPointMap[(*touchPoint)];

        if@H_301_6@ (m_fDistance == 0.0@H_301_6@)
        {
            m_fDistance = mPoint.distance(mPoint);
            m_pMiddlePoint = mPoint.getMidpoint(mPoint2);
        }

    }
}
void@H_301_6@ MapZoom::onTouchesMoved(const@H_301_6@ vector@H_301_6@<Touch*>@H_301_6@ &touches,Event *event)
{
    if@H_301_6@ (touches.size() >= 2@H_301_6@)
    {
        for@H_301_6@(Touch *iter : touches)
        {
            if@H_301_6@ (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@H_301_6@ touchPoint = m_touchIDVec.begin();
        auto@H_301_6@ mPoint = m_touchPointMap[(*touchPoint)];
        ++touchPoint;
        auto@H_301_6@ mPoint2 = m_touchPointMap[(*touchPoint)];

        if@H_301_6@ (m_fDistance == 0@H_301_6@)
        {
            m_fDistance = mPoint.distance(mPoint2);
            m_pMiddlePoint = mPoint.getMidpoint(mPoint2);
            return@H_301_6@;
        }
        scaleMap(mPoint,mPoint2);
    }
    else@H_301_6@ if@H_301_6@ (touches.size() == 1@H_301_6@)
    {
        auto@H_301_6@ iter = touches.cbegin();
        Sprite *sprite = dynamic_cast@H_301_6@<Sprite *>(this@H_301_6@->getChildByTag(TAG_MAP));
        Point endPoint = sprite->getParent()->convertTouchToNodeSpace(*iter);
        if@H_301_6@ (find(m_touchIDVec.begin(),(*iter)->getID()) == m_touchIDVec.end())
        {
            m_touchIDVec.push_back((*iter)->getID());
            m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
            return@H_301_6@;
        }
        if@H_301_6@ (m_touchIDVec.size() == 1@H_301_6@)
        {
            Point pos1 = m_touchPointMap[(*iter)->getID()];
            m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
            Point pos2 = endPoint - pos1 + sprite->getPosition();
            sprite->setPosition(pos2);
            m_fDistance = 0@H_301_6@;
        }
        else@H_301_6@ if@H_301_6@ (m_touchIDVec.size() >= 2@H_301_6@)
        {
            m_touchPointMap[(*iter)->getID()] = (*iter)->getLocation();
            auto@H_301_6@ touchPoint = m_touchIDVec.begin();
            auto@H_301_6@ pt1 = m_touchPointMap[(*touchPoint)];
            ++touchPoint;
            auto@H_301_6@ pt2 = m_touchPointMap[(*touchPoint)];
            scaleMap(pt1,pt2);
        }
    }

}
void@H_301_6@ MapZoom::onTouchesEnded(const@H_301_6@ vector@H_301_6@<Touch*>@H_301_6@ &touches,Event *event)
{
    for@H_301_6@ (Touch *iter : touches)
    {
        int@H_301_6@ touchId = iter->getID();
        if@H_301_6@ (m_touchPointMap.find(touchId) != m_touchPointMap.end())
        {
            m_touchPointMap.erase(touchId);
        }
        auto@H_301_6@ idter = find(m_touchIDVec.begin(),touchId);
        if@H_301_6@ (idter != m_touchIDVec.end())
        {
            m_touchIDVec.erase(idter);
        }
    }
    if@H_301_6@ (m_touchPointMap.empty())
    {
        m_fDistance = 0@H_301_6@;

    }
    else@H_301_6@ if@H_301_6@ (m_touchPointMap.size() >= 2@H_301_6@)
    {
        auto@H_301_6@ touchPoint = m_touchIDVec.begin();
        auto@H_301_6@ pt1 = m_touchPointMap[(*touchPoint)];
        ++touchPoint;
        auto@H_301_6@ pt2 = m_touchPointMap[*touchPoint];
        m_fDistance = pt1.distance(pt2);
    }
}
void@H_301_6@ MapZoom::onTouchesCanceled(const@H_301_6@ vector@H_301_6@<Touch*>@H_301_6@ &touches,Event *event)
{
    m_fDistance = 0@H_301_6@;
    m_touchPointMap.clear();
    m_touchIDVec.clear();
}
void@H_301_6@ MapZoom::scaleMap(Point pt1,Point pt2)
{
    Sprite *sprite = dynamic_cast@H_301_6@<Sprite *>(this@H_301_6@->getChildByTag(TAG_MAP));

    float@H_301_6@ 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@H_301_6@*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@H_301_6@
    m_fScale = min(m_fScale,m_fMaxScale);//缩放比例最大不能超过m_fMaxScale@H_301_6@
    float@H_301_6@ spScale = sprite->getScale();
    float@H_301_6@ newScale = spScale + (m_fScale - spScale)*0.25@H_301_6@;
    if@H_301_6@ (abs@H_301_6@(newScale - sprite->getScale()) > 0.01f@H_301_6@)
    {
        sprite->setScale(newScale);
    }
    sprite->setPosition(newPos);
    sprite->setAnchorPoint(newAnchorPoint);
    m_pMiddlePoint = pt1.getMidpoint(pt2);
    m_fDistance = newdis;
}
1)注意cocos2d-x默认不开启多点触摸
2)最小缩放最好不要设置为0

参考文章
cocos2d-x简单实现地图的缩放

原文链接:https://www.f2er.com/cocos2dx/338227.html

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