关闭

cocos2dx 3.2下利用裁剪节点实现跑马灯滚动效果

3716人阅读 评论(4) 收藏 举报
分类:

以前利用过ScrollView设置跑马灯效果。现在利用cocos2dx内置的ClippingNode也可以实现。

首先原理是什么呢?

将节点A用ClippingNode对象C的setStencil(A)方法设置,然后设置其透明度,

那么ClippingNode对象C再通过addChild添加B,则B将会仅显示A遮罩的部分。

然后移动B,则形成滚动。

当然了,如果你嫌我啰嗦或者描述不清的话,可以直达官网查看→相应文档←。


好了,步兵无真相。骑兵送上。

希望童鞋们发现知识的不足或者好的建议或者意见能够提醒小弟一下,毕竟菜鸟一枚。

头文件。

/****************************************************************************
 Copyright (c) 2014-10-11 Real.xm
 Create by q229827701
 http://blog.csdn.net/q229827701
 ****************************************************************************/
#pragma once
#include "cocos2d.h"
class ScrollText:public cocos2d::Node
{
	public:
		CREATE_FUNC(ScrollText);

		/**
		@pragma  pMask 需要用于遮罩的精灵
		@pragma  pMoveChild 需要移动的Node
		@pragma  otherChid 其他需要显示的Node
		*/
		static ScrollText* create(cocos2d::Sprite* &pMask,cocos2d::Node* &pMoveChild,cocos2d::Node* &otherChild,...);
		/**
		@pragma  isScroll 设置是否需要自动滚动
		@pragma  byWidth 设置是否需要根据长度来滚动
		PS:如果按照长度来设置,则长度小于遮罩长度的将不予滚动
		*/
		void setAutoScroll(bool isScroll,bool byWidth=false);
CC_CONSTRUCTOR_ACCESS:
		ScrollText();
		virtual ~ScrollText();
		virtual bool init();
		virtual bool initWithDatas(cocos2d::Sprite* &pMask,cocos2d::Node* &pMoveChild);
		bool initClipper(cocos2d::Sprite* &pMask,cocos2d::Node* &pMoveChild);
		void update(float delta);

	private:
		cocos2d::Node* _mLable;
		cocos2d::Vector<Node*> _mNodes;
		bool _autoScroll;
};

源文件

#include "ScrollText.h"
USING_NS_CC;
#define IF_RETURN(cont,p) if ((cont)){return (p);}
#define IF_RETURN_FALSE(cont) IF_RETURN(cont,false)
bool ScrollText::init()
{
	bool ret = true;
	if (Node::init())
	{
		auto pMask = Sprite::create("text/switch-mask.png");
		_mLable = Label::createWithSystemFont("Title", "Arial-BoldMT", 16);
		_mLable->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT);
		IF_RETURN_FALSE(!initClipper(pMask,_mLable));
		scheduleUpdate();
		setAutoScroll(true);
		return ret;
	}
	return ret;
}

bool ScrollText::initClipper( cocos2d::Sprite* &pMask,cocos2d::Node* &pMoveChild)
{
	auto clipper = ClippingNode::create();
	IF_RETURN_FALSE(!clipper);
	IF_RETURN_FALSE(!pMask);
	setContentSize(pMask->getContentSize());
	IF_RETURN_FALSE(!pMask->getTexture());
	auto _clipperStencil = Sprite::createWithTexture(pMask->getTexture());
	IF_RETURN_FALSE(!_clipperStencil);
	_clipperStencil->retain();
	clipper->setAlphaThreshold(0.1f);
	clipper->setStencil(_clipperStencil);
	clipper->addChild(pMoveChild,1);
	addChild(clipper);
	for (auto child:_mNodes)
	{
		IF_RETURN_FALSE(!child);
		clipper->addChild(child);
	}
	return true;
}

ScrollText::ScrollText():_autoScroll(false)
{

}


ScrollText::~ScrollText()
{
	CC_SAFE_RELEASE(_mLable);
}

void ScrollText::update( float delta )
{
	if (!_mLable)
	{
		return;
	}
	float currentX = _mLable->getPositionX();
	float contentX = getContentSize().width*(-1.0f);
	float lableX = _mLable->getContentSize().width*(-1.0f);

	if (_autoScroll)
	{
		if(_mLable->getPositionX()>=(lableX+contentX/2))
			_mLable->setPositionX(_mLable->getPositionX()-0.25f);
		else
		{
			_mLable->setPositionX(-contentX/2);
		}
			
	}
	else
	{
		_mLable->setPositionX(contentX/2);
	}
}

void ScrollText::setAutoScroll( bool isScroll,bool byWidth/*=false*/ )
{
	if (!byWidth)
	{
		_autoScroll = isScroll;
	}
	else
	{
		_autoScroll=_mLable->getContentSize().width>getContentSize().width?true:false;
	}
}

ScrollText* ScrollText::create( cocos2d::Sprite* &pMask,cocos2d::Node* &pMoveChild,cocos2d::Node* &otherChild,... )
{
	auto *sTxt = new ScrollText(); 
	if (sTxt ) 
	{ 
		va_list lst;
		va_start(lst,otherChild);
		Node* pNow;
		pNow=otherChild;
		while(otherChild)
		{
			if (pNow)
			{
				sTxt->_mNodes.pushBack(pNow);
				pNow=va_arg(lst,Node*);
			}
			else
				break;
		}
		va_end(lst);
		if(sTxt->initWithDatas(pMask,pMoveChild))
		{
			sTxt->autorelease(); 
			return sTxt; 
		}
		else
		{
			delete sTxt; 
			sTxt = NULL; 
			return NULL; 
		}
	} 
	else 
	{ 
		delete sTxt; 
		sTxt = NULL; 
		return NULL; 
	} 
}

bool ScrollText::initWithDatas( cocos2d::Sprite* &pMask,cocos2d::Node* &pMoveChild)
{
	bool ret = false;
	if (Node::init())
	{
		IF_RETURN_FALSE(!pMask);
		_mLable = pMoveChild;
		_mLable->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT);
		initClipper(pMask,_mLable);
		scheduleUpdate();
		return true;
	}
	return ret;
}


效果如图所示:



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:80779次
    • 积分:1449
    • 等级:
    • 排名:千里之外
    • 原创:59篇
    • 转载:3篇
    • 译文:1篇
    • 评论:34条
    博客专栏
    文章分类
    最新评论