以前利用过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,... ) { 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; }
效果如图所示: