cocos2dx-3.10 C++實現滾動數字
阿新 • • 發佈:2020-09-19
本文例項為大家分享了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 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 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 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()) }; drawNode->drawPolygon(points,4,Color4F(0,1),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");
實現效果:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。