1. 程式人生 > 程式設計 >cocos2dx-3.10 C++實現滾動數字

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 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");

實現效果:

cocos2dx-3.10 C++實現滾動數字

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。