本文部分代码来自http://blog.csdn.net/q229827701/article/details/39996171,在此基础上稍作修改,并添加了详细注释。
1、ScrollText类#ifndef __ScrollTest__ScrollText__#define __ScrollTest__ScrollText__#include "cocos2d.h"#include "ui/CocosGUI.h"USING_NS_CC;using @R_403_6889@space ui;class ScrollText : public cocos2d::Node{public: enum class Font_TYPE //类似类的创建。可以通过命名空间,访问变量,防止命名冲突 { BolD,NOMAL,SliM }; CREATE_FUNC(ScrollText); static ScrollText* create(cocos2d::Node* pMoveChild,...); static ScrollText* create(Font_TYPE mType); voID setautoScroll(bool isScroll,bool byWIDth = false); CC_CONSTRUCTOR_ACCESS://protected的宏定义 ScrollText(); virtual ~ScrollText(); virtual bool init(); virtual bool initWithDatas(cocos2d::Node* &pMoveChild); virtual bool init(Font_TYPE mType); bool initLabel(Font_TYPE mType); bool initScroll(); voID update(float dt); virtual voID onEnterTransitionDIDFinish(); //此处设计的很巧妙,_content其实是赋值给_mLabel的,我们可以通过_content传递跑马灯的内容尽量 //_mSize其实大小等于ScrollSize的size,如果忘记设置ScrollText的size,默认为构造函数里的数值 CC_SYNTHESIZE_Readonly(cocos2d::Node*,_mLabel,Label); CC_SYNTHESIZE_Readonly(cocos2d::Size,_mSize,TextSize); CC_SYNTHESIZE(std::string,_content,Content); public: voID setSize(const cocos2d::Size &size);private: cocos2d::Vector<Node*> _mNodes; bool _autoScroll; bool _byWIDth; cocos2d::ui::ScrollVIEw* _scrollVIEw;};#endif /* defined(__ScrollTest__ScrollText__) */
#include "ScrollText.h"#include <stdarg.h>//宏用来判断函数或对象是否执行或创建成功#define IF_RETURN(cont,p) if((cont)){return (p);}#define IF_RETURN_FALSE(cont) IF_RETURN(cont,false)//构造函数ScrollText::ScrollText():_autoScroll(false),_byWIDth(false),_mLabel(nullptr),_content("no content"),_scrollVIEw(nullptr),_mSize(120,40){ }//析构函数ScrollText::~ScrollText(){ CC_SAFE_RELEASE(_mLabel); CC_SAFE_RELEASE(_scrollVIEw);}//调用通过CREATE_FUNC调用init()函数bool ScrollText::init(){ //默认字体类型初始化 IF_RETURN_FALSE(!init(Font_TYPE::NOMAL)); return true;}//通过字体类型初始化bool ScrollText::init(Font_TYPE mType){ bool bRet = false; do{ CC_BREAK_IF(!Node::init()); //初始化跑马灯内容和ScrollVIEw对象 IF_RETURN_FALSE(!initLabel(mType)); IF_RETURN_FALSE(!initScroll()); bRet = true; }while(0); return bRet;}//初始化ScrollVIEw对象bool ScrollText::initScroll(){ _scrollVIEw = ui::ScrollVIEw::create(); IF_RETURN_FALSE(!_scrollVIEw); _scrollVIEw->setContentSize(_mSize); addChild(_scrollVIEw); setContentSize(_scrollVIEw->getContentSize()); //添加可变参数的子对象,前提是使用create(cocos2d::Node *pMoveChild,...)创建ScrollText对象 for(auto child:_mNodes) { IF_RETURN_FALSE(!child); _scrollVIEw->addChild(child); } IF_RETURN_FALSE(!_mLabel); _scrollVIEw->addChild(_mLabel); return true;}//帧更新函数voID ScrollText::update(float dt){ if(!_mLabel) { return ; } //获取跑马灯位置判断的相关数据 float contentX = getContentSize().wIDth*(-1.0f); float _labelX = _mLabel->getContentSize().wIDth*(-1.0f); //如果想通过跑马灯内容来确定是否循环播放 if(_byWIDth) { //执行此处,即如果跑马灯的字体内容超出了ScrollText的宽度,则设置循环tag为真 _autoScroll = _mLabel->getContentSize().wIDth>getContentSize().wIDth?true:false; } //如果循环播放为真 if(_autoScroll) { //首先判断跑马灯内容有没有完全跑出ScrollText,因为锚点是左边,所以当位置为负的_mLabel的wIDth时,完全跑出ScrollText if(_mLabel->getpositionX() >= _labelX) { _mLabel->setpositionX(_mLabel->getpositionX() - 1.0f); }else{ _mLabel->setpositionX(-contentX); } }else { _mLabel->setpositionX(0); } //设置跑马灯内容 auto label = dynamic_cast<Label*>(_mLabel); if(label && label->getString() != _content) { label->setString(_content); }}//设置是否循环播放跑马灯内容voID ScrollText::setautoScroll(bool isScroll,bool byWIDth/*=false*/){ _byWIDth = byWIDth; if(isScroll && byWIDth) { _autoScroll = _mLabel->getContentSize().wIDth>getContentSize().wIDth?true:false; }else{ _autoScroll = isScroll; }}//可变形参创建跑马灯,可以添加任意Node对象到跑马灯中ScrollText* ScrollText::create(cocos2d::Node *pMoveChild,...){ auto sTxt = new ScrollText(); if(sTxt) { //可变参数指针地址的获取 va_List lst;//va_List是char*类型,用户获取可变参数的地址 va_start(lst,pMoveChild);//从最后入栈的变量初始化指针 Node* pNow; pNow = pMoveChild; bool isFirst = true; while (pMoveChild) { if (nullptr != pNow) { if(isFirst) isFirst = false; else sTxt->_mNodes.pushBack(pNow); pNow = va_arg(lst,Node*);//依次获取可变参数的地址,第二个参数是可变形参的类型。注意传参时一定是Node的对象或子对象 }else break; } va_end(lst);//结束 //初始化跑马灯内容,真正把跑马灯内容加进去的函数是initScroll if(sTxt->initWithDatas(pMoveChild)) { sTxt->autorelease(); return sTxt; }else{//如果函数执行失败后安全释放内存,防止野指针 delete sTxt; sTxt = NulL; return NulL; } }else{ delete sTxt; sTxt = NulL; return NulL; }}ScrollText* ScrollText::create(ScrollText::Font_TYPE mType){ auto text = new ScrollText(); if(text && text->init(mType)) { text->autorelease(); return text; }else{ delete text; text = nullptr; return nullptr; }}//初始化跑马灯内容bool ScrollText::initWithDatas(cocos2d::Node *&pMoveChild){ bool bRet = false; do{ CC_BREAK_IF(!Node::init()); IF_RETURN_FALSE(!pMoveChild); _mLabel = pMoveChild; _mLabel->setAnchorPoint(Vec2::ANCHOR_BottOM_left); IF_RETURN_FALSE(!initScroll());//在initScroll真正把跑马灯内容初始化 bRet = true; }while(0); return bRet;}//设置跑马灯可见区域SizevoID ScrollText::setSize(const cocos2d::Size& size){ _mSize = size; _scrollVIEw->setContentSize(_mSize); setContentSize(_mSize);}bool ScrollText::initLabel(ScrollText::Font_TYPE mType){ _mLabel = Label::createWithSystemFont("Content","Arial Bold",40); IF_RETURN_FALSE(!_mLabel); _mLabel->setAnchorPoint(Vec2::ANCHOR_BottOM_left); return true;}//节点进入完成,执行帧更新//例如:如果我ScrollText节点执行一个进入动画的特效,如果不设置此处,可能在动画播放的同时,//跑马灯就开始走了,为了达到动画播放完毕,才执行跑马灯的播放,就是此处函数的功能啦voID ScrollText::onEnterTransitionDIDFinish(){ scheduleUpdate();}2、使用方法 在HelloWorld类的init函数中添加如下代码
auto st = ScrollText::create(); st->setautoScroll(true); st->setContent("父老乡亲们,这是ScrollText跑马灯");//设置内容 st->setSize(Size(300,40));//设置可见区域大小 st->setposition(visibleSize.wIDth/2,visibleSize.height/2); addChild(st);3、效果 总结
以上是内存溢出为你收集整理的利用ScrollView实现跑马灯效果全部内容,希望文章能够帮你解决利用ScrollView实现跑马灯效果所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)