先来一张效果图:
1.左侧右侧都有边界 划到头会划不动
2.松手后总会有一个最近的向中心移动,其他的跟随移动
#ifndef __HEROSELECT_SCENE_H__
#define __HEROSELECT_SCENE_H__
#include "cocos2d.h"
class HeroSelect : public cocos2d::LayerColor
{
public:
static cocos2d::Scene* createScene();
CREATE_FUNC(HeroSelect);
private:
virtual bool init();
virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unused_event);
virtual void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unused_event);
virtual void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event);
virtual void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unused_event);
//边界检测 保证左右两侧各有滑动边界
bool isBoundary();
//计算角色集合中 距离中心最近的角色与中心的距离
float calcDistance();
public:
private:
//用该节点作为所有商品的父节点 方便集体调整位置
cocos2d::Node *view = nullptr;
//开始触摸的坐标
cocos2d::Vec2 touchBeginVec2;
//角色集合
cocos2d::Vector herosVector;
//角色集合中 距离中心最近的角色与中心的距离
float distance;
};
#endif // __HEROSELECT_SCENE_H__#include "HeroSelect.h"
USING_NS_CC;
Scene* HeroSelect::createScene()
{
auto scene = Scene::create();
auto layer = HeroSelect::create();
scene->addChild(layer);
return scene;
}
bool HeroSelect::init()
{
//白色背景
if(!LayerColor::initWithColor(Color4B(255, 255, 255, 255)))
{
return false;
}
Size vSize = Director::getInstance()->getVisibleSize();
view = Node::create();
view->setPosition(vSize / 2);
this->addChild(view);
//创建所有角色
for(int i = 1; i != 5; ++i)
{
std::string str = StringUtils::format("big_box%d.png", i);
Sprite * sp = Sprite::create(str);
sp->setPosition(Vec2((i - 1) * sp->getContentSize().width, 0));
view->addChild(sp);
herosVector.pushBack(sp);
}
auto listener = EventListenerTouchOneByOne::create();//创建一个触摸监听(单点触摸)
listener->onTouchBegan = CC_CALLBACK_2(HeroSelect::onTouchBegan, this);//指定触摸的回调函数
listener->onTouchMoved = CC_CALLBACK_2(HeroSelect::onTouchMoved, this);//指定触摸的回调函数
listener->onTouchEnded = CC_CALLBACK_2(HeroSelect::onTouchEnded, this);//指定触摸的回调函数
listener->onTouchCancelled = CC_CALLBACK_2(HeroSelect::onTouchCancelled, this);//指定触摸的回调函数
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
return true;
}
bool HeroSelect::onTouchBegan(Touch *touch, Event *event)
{
touchBeginVec2 = touch->getLocation();
return true;
}
void HeroSelect::onTouchMoved(Touch *touch, Event *unused_event)
{
if(isBoundary())
{
return;
}
int moveX = touch->getLocation().x - touchBeginVec2.x;
auto moveBy = MoveBy::create(0.0f, Vec2(moveX, 0));
view->runAction(moveBy);
touchBeginVec2 = touch->getLocation();
}
void HeroSelect::onTouchEnded(Touch *touch, Event *unused_event)
{
view->stopAllActions();
auto moveBy = MoveBy::create(0.2f, Vec2(calcDistance(), 0));
view->runAction(moveBy);
}
void HeroSelect::onTouchCancelled(Touch *touch, Event *unused_event)
{
onTouchEnded(touch, unused_event);
}
bool HeroSelect::isBoundary()
{
Size vSize = Director::getInstance()->getVisibleSize();
auto begin = herosVector.at(0);
auto end = herosVector.at(herosVector.size() - 1);
//讲在view节点上的相对坐标转换为VisibleSize的坐标(世界坐标)
Vec2 left = begin->convertToWorldSpace(Vec2(begin->getContentSize().width / 2, 0));
Vec2 right = end->convertToWorldSpace(Vec2(end->getContentSize().width / 2, 0));
if(left.x > vSize.width / 2)
{
return true;
}
else if(right.x < vSize.width / 2)
{
return true;
}
return false;
}
float HeroSelect::calcDistance()
{
float result = 1000.0f;
Size vSize = Director::getInstance()->getVisibleSize();
for(auto hero : herosVector)
{
Point p2world = hero->convertToWorldSpace(Point(0, 0)) + Vec2(hero->getContentSize().width / 2, 0);
float dis = vSize.width / 2 - p2world.x;
float temp = fabs(dis);
if(temp < result)
{
result = dis;
}
}
return result;
}