Coco2d-x 3.X 点击滚动、移动滚动

1、CustomScrollLayer.h

#pragma once
#include "cocos2d.h"
USING_NS_CC;
class CustomScrollLayer:public Layer
{
public:
	CustomScrollLayer();
	~CustomScrollLayer();
private:
	Vec2				_pox[3];
	int					_leftItemIndex;
	int					_midItemIndex;
	int					_rightItemIndex;
	float				_space;
	bool				_isScrollActionOver;
	bool				_hasMoveScrolled;
public:
	std::vector<Node*> m_items;
	static CustomScrollLayer* create(Vec2 midItemPox, float space, std::vector<Node*> allItems);
	bool init(Vec2 midItemPox, float space, std::vector<Node*> allItems);
	void onEnter()override;
	void onExit()override;
	bool touchBegan(Touch *pTouch, Event *pEvent);
	void touchMoved(Touch *pTouch, Event *pEvent);
	void touchEnded(Touch *pTouch, Event *pEvent);
private:
	void initPosX(Vec2 midItemPox,std::vector<Node*> allItems);
	void startMoveActions(bool isGoLeft = true);
	void disapperAction(bool isLeftDisAppear);
	void scaleDownAction(bool isGoLeft);
	void scaleUpAction(bool isGoLeft);
	void showAction(bool isShowRightItem);
	void resetItemIndex(bool isGoLeft);
	bool hitTest(Touch* pTouch, int index);
};

2、CustomScrollLayer.cpp


#include "CustomScrollLayer.h"
//#include "AppUtils.h"



#define		SCALE_SPACE					0.3f
#define		SCROLL_ACTION_DURATION		0.3f
#define		MOVE_SCROLL_SPACE			50

CustomScrollLayer::CustomScrollLayer()
{
	_leftItemIndex = 0;
	_midItemIndex = 0;
	_rightItemIndex = 0;
	_space = 0; 
	_isScrollActionOver = true;
	_hasMoveScrolled = false;
}


CustomScrollLayer::~CustomScrollLayer()
{
}

CustomScrollLayer* CustomScrollLayer::create(Vec2 midItemPox, float space, std::vector<Node*> allItems)
{
	CustomScrollLayer* pRet = new CustomScrollLayer();
	if (pRet&&pRet->init(midItemPox, space,allItems))
	{
		pRet->autorelease();
	}
	else
	{
		delete pRet;
		pRet = NULL;
	}
	return pRet;
}

bool CustomScrollLayer::init(Vec2 midItemPox, float space, std::vector<Node*> allItems)
{
	if (!Layer::init()) return false;
	_space = space;
	initPosX(midItemPox,allItems);
	return true;
}

void CustomScrollLayer::onEnter()
{
	Layer::onEnter();
	auto touchEvent = EventListenerTouchOneByOne::create();
	touchEvent->onTouchBegan = CC_CALLBACK_2(CustomScrollLayer::touchBegan, this);
	touchEvent->onTouchMoved = CC_CALLBACK_2(CustomScrollLayer::touchMoved, this);
	touchEvent->onTouchEnded = CC_CALLBACK_2(CustomScrollLayer::touchEnded, this);
	touchEvent->setSwallowTouches(true);
	_eventDispatcher->addEventListenerWithFixedPriority(touchEvent, 10);
}

void CustomScrollLayer::onExit()
{
	_eventDispatcher->removeEventListenersForTarget(this);
	Layer::onExit();
}

bool CustomScrollLayer::touchBegan(Touch *pTouch, Event *pEvent)
{
	return true;
}

void CustomScrollLayer::touchMoved(Touch *pTouch, Event *pEvent)
{
	Point begin = pTouch->getStartLocation();
	Point cur = pTouch->getLocation();
	cur.subtract(begin);
	if ((cur.x>MOVE_SCROLL_SPACE|cur.x<-MOVE_SCROLL_SPACE)&&!_hasMoveScrolled&&_isScrollActionOver)
	{
		_hasMoveScrolled = true;
		startMoveActions(cur.x<0);
	}
}

void CustomScrollLayer::touchEnded(Touch *pTouch, Event *pEvent)
{
	if (hitTest(pTouch,_leftItemIndex))
	{
		startMoveActions(false);
	}
	else if(hitTest(pTouch, _rightItemIndex))
	{
		startMoveActions(true);
	}
	else if (hitTest(pTouch, _midItemIndex))
	{
		MessageBox("Execute Menu Pressed Event!","执行按钮点击方法");
		//AppUtils::toastMessage(this, "Execute Menu Pressed Event!", 640);
	}
_hasMoveScrolled = false;	
}

void CustomScrollLayer::initPosX(Vec2 midItemPox,std::vector<Node*> allItems)
{
	_pox[0] = Vec2(midItemPox.x - _space, midItemPox.y);
	_pox[1] = Vec2(midItemPox.x, midItemPox.y);
	_pox[2] = Vec2(midItemPox.x + _space, midItemPox.y);
	_midItemIndex = 1;
	_rightItemIndex = _midItemIndex + 1;

	for (size_t i = 0; i < allItems.size(); i++)
	{
		Node* item = allItems.at(i);
		item->setColor(Color3B::GRAY);
		if (i < 3)
		{
			item->setPosition(_pox[i]);
			if (i==1)
			{
				item->setScale(1+ SCALE_SPACE);
				item->setColor(Color3B::WHITE);
			}
		}
		else
		{
			item->setVisible(false);
			item->setScale(1 - SCALE_SPACE);
		}
		addChild(item);
		m_items.push_back(item);
	}
}

void CustomScrollLayer::startMoveActions(bool isGoLeft/* = true*/)
{
	_isScrollActionOver = false;
	// 缩小消失
	disapperAction(isGoLeft);
	// 缩小移动变灰
	scaleDownAction(isGoLeft);
	// itemRight
	scaleUpAction(isGoLeft);
	resetItemIndex(isGoLeft);
	if (m_items.size()>3)
	{
		showAction(isGoLeft);
	}
}

void CustomScrollLayer::disapperAction(bool isLeftDisAppear)
{
	Node* target = NULL;
	if (isLeftDisAppear)
	{
		target = m_items.at(_leftItemIndex);
	}
	else
	{
		target = m_items.at(_rightItemIndex);
	}
	target->setZOrder(100);
	ScaleTo* pScaleTo = ScaleTo::create(m_items.size() <= 3?SCROLL_ACTION_DURATION/2: SCROLL_ACTION_DURATION, 1 - SCALE_SPACE);
	CallFunc* pCallFunc = CallFunc::create([=]() {
		target->setVisible(false);
		if (m_items.size() <=3)
		{
			showAction(isLeftDisAppear);
		}
	});
	Sequence* pSequence = Sequence::create(pScaleTo, pCallFunc, NULL);
	target->runAction(pSequence);
}

void CustomScrollLayer::scaleDownAction(bool isGoLeft)
{
	Node* target = m_items.at(_midItemIndex);
	target->setZOrder(200);
	target->setColor(Color3B::GRAY);
	ScaleTo* pScaleTo = ScaleTo::create(SCROLL_ACTION_DURATION, 1);
	MoveTo* pMoveTo = MoveTo::create(SCROLL_ACTION_DURATION, isGoLeft?_pox[0]:_pox[2]);
	Spawn* pSpawn = Spawn::create(pScaleTo, pMoveTo, NULL);
	target->runAction(pSpawn);
}

void CustomScrollLayer::scaleUpAction(bool isGoLeft)
{
	Node* target = NULL;
	if (isGoLeft)
	{
		target = m_items.at(_rightItemIndex);
	}
	else
	{
		target = m_items.at(_leftItemIndex);
	}
	target->setZOrder(300);
	MoveTo* pMoveTo = MoveTo::create(SCROLL_ACTION_DURATION, _pox[1]);
	ScaleTo* pScaleTo = ScaleTo::create(SCROLL_ACTION_DURATION, 1 + SCALE_SPACE);
	Spawn* pSpawn = Spawn::create(pMoveTo, pScaleTo, NULL);
	CallFunc* pCallFunc = CallFunc::create([=]() {
		target->setColor(Color3B::WHITE);
	});
	Sequence* pSequence = Sequence::create(pSpawn, pCallFunc, NULL);
	target->runAction(pSequence);
}

void CustomScrollLayer::showAction(bool isShowRightItem)
{
	Node* target = NULL;
	if (isShowRightItem)
	{
		target = m_items.at(_rightItemIndex);
	}
	else
	{
		target = m_items.at(_leftItemIndex);
	}
	target->setZOrder(50);
	target->setVisible(true);
	if (!isShowRightItem)
	{
		target->setPosition(_pox[0]);
	}
	else
	{
		target->setPosition(_pox[2]);
	}
	ScaleTo* pScaleTo = ScaleTo::create(m_items.size() <= 3 ? SCROLL_ACTION_DURATION / 2: SCROLL_ACTION_DURATION, 1);
	CallFunc* pCallFunc = CallFunc::create([=]() {
		_isScrollActionOver = true;
	});
	Sequence* pSequence = Sequence::create(pScaleTo,pCallFunc,NULL);
	target->runAction(pSequence);
}

void CustomScrollLayer::resetItemIndex(bool isGoLeft)
{
	if (isGoLeft)
	{
		_leftItemIndex = _midItemIndex;
		_midItemIndex = _rightItemIndex;
		_rightItemIndex = _midItemIndex + 1;
		if (_rightItemIndex >= m_items.size())
		{
			_rightItemIndex = 0;
		}
	}
	else
	{
		_rightItemIndex = _midItemIndex;
		_midItemIndex = _leftItemIndex;
		_leftItemIndex = _midItemIndex - 1;
		if (_leftItemIndex < 0)
		{
			_leftItemIndex = m_items.size()-1;
		}
	}
}

bool CustomScrollLayer::hitTest(Touch* pTouch,int index)
{
	Point pre = pTouch->getStartLocation();
	Point cur = pTouch->getLocation();
	Rect rect = m_items.at(index)->getBoundingBox();
	if (rect.containsPoint(pre) && rect.containsPoint(cur) && _isScrollActionOver)
	{
		return true;
	}
	return false;
}

3、使用

void MainRoomLayer::testForScrollLayer()
{
	std::vector<Node*> itemNames;
	itemNames.push_back(Sprite::create("test/room1.png"));
	itemNames.push_back(Sprite::create("test/room2.png"));
	itemNames.push_back(Sprite::create("test/room3.png"));
	itemNames.push_back(Sprite::create("test/room3.png"));
	
	auto size = Director::getInstance()->getVisibleSize();
	CustomScrollLayer* pScrollLayer = CustomScrollLayer::create(Vec2(size.width/2,size.height/2), 400,itemNames);
	pScrollLayer->setPositionY((size.height - pScrollLayer->getContentSize().height)/2);
	addChild(pScrollLayer);
}


4、效果图



1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值