cocos2dx-3.10 C++实现滚动数字
本文实例为大家分享了cocos2dx-3.10 C++实现滚动数字的具体代码,供大家参考,具体内容如下
NumberScroller.h
#ifndef _NUMBERSCROLLER_H_ #define _NUMBERSCROLLER_H_ #include "cocos2d.h" USING_NS_CC; /* 这是一个数字滚动切换控件 更新方向: 1.在规定时间运动完,速度在变化 2.能指定字体表 3.增加新的更新算法,确保运动到指定数时候可以及时完成 4.添加能够指定宽和高以及数字之间的间隔 */ class NumberColumn : public Node{ private: NumberColumn(); public: static NumberColumn* create(int fontHight); void setNumber(int number,bool direction=true); void setTime(float time); private: bool init(int fontHight); void update(float delta); private: Node* m_numbers; //当前显示节点 int m_cur_num; //当前显示数字 int m_target_num; //目标显示数组 int m_fontHight; //当个字体高度 float m_time; //切换总时间 float update_moveSum; //几率在两个数字更新期间移动的距离 float update_speed; //刷新一次的时间 }; class NumberScroller : public Node{ private: NumberScroller(); public: static NumberScroller* create(int length,int fontWidth,int fontHeight,int fontSpacing); void setTime(float time); void setNumber(int number); int getNumber(); private: bool init(int length, int fontWidth, int fontHeight, int fontSpacing); private: Vector<NumberColumn*> m_columns; //存储一共的列数 int m_cur_num; //当前显示数字 int m_length; //列数 int m_time; //切换总时间 int m_fontWidth; //字体宽度 int m_fontHeight; //字体高度 int m_fontSpacing; //字体间隔 Node* m_visibleNode; //当前可视节点 }; #endif
NumberScroller.cpp
#include "NumberScroller.h" NumberColumn::NumberColumn(): m_cur_num(0), m_target_num(0), m_time(1.0f), update_moveSum(0), update_speed(0) { } NumberColumn* NumberColumn::create(int fontHight){ NumberColumn* ret = new NumberColumn(); if (ret && ret->init(fontHight)){ ret->autorelease(); return ret; } CC_SAFE_DELETE(ret); return nullptr; } bool NumberColumn::init(int fontHight){ if(!Node::init()) return false; m_numbers = Node::create(); this->addChild(m_numbers); m_fontHight = fontHight; this->scheduleUpdate(); //初始化一列0-9 共十个数字 for(int i=0;i<10;i++){ char str[2]; str[0] = i + '0'; str[1] = '\0'; auto temp = Label::createWithBMFont("fonts/test.fnt", str); temp->setAnchorPoint(Point(0,0)); temp->setPosition(Point(0, i * fontHight)); m_numbers->addChild(temp); } //为了兼容不同方向的偏转 char str[2]; str[0]='0'; str[1]='\0'; //添加字符串结束符 Label* temp = Label::createWithBMFont("fonts/test.fnt", str); temp->setAnchorPoint(Point(0,0)); temp->setPosition(Point(0, 10 * fontHight)); m_numbers->addChild(temp); return true; } void NumberColumn::setNumber(int number,bool direction){ m_target_num = number; int delta = m_target_num - m_cur_num; //计算数字间隔 update_speed = (delta * m_fontHight / m_time); //v = s / t } void NumberColumn::setTime(float time){ m_time = time; } void NumberColumn::update(float d){ if(m_cur_num != m_target_num){ //如果当前显示的数字不等于目标数字,即要开始滚动 float dis = update_speed * d; //每次调用update函数需要滚动的距离等于update_speed 乘以 d (update_speed在setNumber函数中已经算出) m_numbers->setPositionY(m_numbers->getPositionY() - dis);//每次使整条向下移动dis距离 update_moveSum += dis;//update_moveSum 用于保存现在到底移动了多少距离 if (update_moveSum >= m_fontHight){ //如果现在已经移动了一个字大小的距离 //每移动一次累加1 m_cur_num++; //对10求余是为了在每次达到10后从新开始新循环 m_numbers->setPositionY(- (m_cur_num % 10) * m_fontHight); //负数表示向下移,标准对齐位置 update_moveSum = 0; } } } /* ******************************************************************************************************************************************** ******************************************************************************************************************************************** */ NumberScroller::NumberScroller(): m_cur_num(0), m_length(0), m_time(1.0f) { } NumberScroller* NumberScroller::create(int length, int fontWidth, int fontHeight, int fontSpacing){ NumberScroller* ret = new NumberScroller(); if (ret && ret->init(length, fontWidth, fontHeight,fontSpacing)){ ret->autorelease(); return ret; } CC_SAFE_DELETE(ret); return nullptr; } bool NumberScroller::init(int length, int fontWidth, int fontHeight, int fontSpacing){ if(!Node::init()) return false; m_length = length; m_fontWidth = fontWidth; m_fontHeight = fontHeight; m_fontSpacing = fontSpacing; m_visibleNode = Node::create(); //排好length行数字 //该demo下为左对齐 for(int i=0;i<length;i++){ NumberColumn* column = NumberColumn::create(fontHeight); m_columns.pushBack(column); column->setAnchorPoint(Point(0,0)); //锚点设置为0是为了后面设置遮罩层 column->setPosition(i * (fontWidth + fontSpacing), 0); column->setTime(m_time); //设置默认运动时间1S m_visibleNode->addChild(column); } /*设置遮罩层*/ ClippingNode* cliper = ClippingNode::create(); //创建模板 DrawNode* drawNode = DrawNode::create(); Point points[] = { Point(getPosition()), Point(getPositionX(),getPositionY() + m_fontHeight), Point(getPositionX() + m_length * m_fontHeight, getPositionY() + m_fontHeight), Point(getPositionX() + m_length * m_fontHeight, getPositionY()) }; drawNode->drawPolygon(points,4,Color4F(0,0,0,1),0,Color4F(0,0,0,1)); //设置模板 cliper->setStencil(drawNode); cliper->addChild(m_visibleNode); this->addChild(cliper); //不添加遮罩层的方法 //this->addChild(m_visibleNode); } void NumberScroller::setNumber(int number){ if(number > m_cur_num){ m_cur_num = number; for(int i=0;i<m_length;i++){ m_columns.at(m_length - i -1)->setNumber(number); number /= 10; } } } int NumberScroller::getNumber(){ return m_cur_num; } //对外开放设置时间的接口 void NumberScroller::setTime(float time){ m_time = time; for(int i=0;i<m_length;i++){ m_columns.at(i)->setTime(time); } }
使用方法
auto numberScroller = NumberScroller::create(1,15,33,10);//这个字体宽度根据fnt 文件表的相关参数计算 numberScroller->setPosition(Director::getInstance()->getVisibleSize().width / 2, Director::getInstance()->getVisibleSize().height / 2); this->addChild(numberScroller); scheduleUpdate(); Director::getInstance()->getScheduler()->schedule([=](float){ CountNum = CountNum + 1; numberScroller->setNumber(CountNum); }, this, 1.0f, false, "countDown");
实现效果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
赞 (0)