一、制作背景

如今非常多游戏或者应用须要评分,就是一般来说满分10分,一般用星星来表示。
那么cocos2dx里面怎样制作评分这种控件呢?
我的打算是进度条组合成即可了。

二、材料准备


如上图所看到的,即2颗小星星就可以。

三、终于效果



四、代码实现

/////////////////////////////////////////////////////////////////////////////////

/***************************ScoreBar Class**************************************/

/////////////////////////////////////////////////////////////////////////////////

class ScoreBar:public cocos2d::Node
{
public:
		CREATE_FUNC(ScoreBar);
	static ScoreBar* create(float mPercentage);
CC_CONSTRUCTOR_ACCESS:
		ScoreBar();
		~ScoreBar();
	virtual	bool init();
    virtual bool initSelf();
	virtual bool initBackGround();
	virtual bool initProgress();
public:
	void setPercent(unsigned char mPercentage);
    float getPercent() const;
private:
		cocos2d::Vector<cocos2d::ProgressTimer*>* _progressBars;  
		cocos2d::Node* _backGround;                                 
};

/////////////////////////////////////////////////////////////////////////////////

/***************************ScoreBar Class**************************************/

/////////////////////////////////////////////////////////////////////////////////

ScoreBar::ScoreBar():_progressBars(nullptr),
	_backGround(nullptr)
{

}

ScoreBar::~ScoreBar()
{
	_progressBars->clear();
	CC_SAFE_DELETE(_progressBars);
	CC_SAFE_RELEASE(_backGround);
}

ScoreBar* ScoreBar::create( float mPercentage )
{
	auto bar = new ScoreBar();
	if (bar&&bar->init())
	{
		bar->setPercent(mPercentage);
		bar->autorelease();
		return bar;
	}
	CC_SAFE_DELETE(bar);
	bar = nullptr;
	return nullptr;
}

bool ScoreBar::init()
{
	bool ret = false;
	if (Node::init())
	{
		IF_RETURN_FALSE(!initSelf());
		return true;
	}
	return ret;
}

bool ScoreBar::initSelf()
{
	IF_RETURN_FALSE(!initBackGround());
	IF_RETURN_FALSE(!initProgress());
	return true;
}

bool ScoreBar::initBackGround()
{
	unsigned char elementCount = 5;
	const std::string elementBg  = "grid/star_default.png";
	_backGround = Node::create();
	IF_RETURN_FALSE(!_backGround);
	addChild(_backGround);
	for (unsigned char i=0;i<elementCount;i++)
	{
		auto elementSprite = Sprite::create(elementBg);
		IF_RETURN_FALSE(!elementSprite);
		_backGround->addChild(elementSprite);
		elementSprite->setPosition(elementSprite->getContentSize().width*i,0.0f);
	}
	return true;
}

bool ScoreBar::initProgress()
{
	unsigned char elementCount = 5;
	const std::string elementPre =  "grid/star_show.png";
	float w = 0.0f;
	float h = 0.0f;
	if (nullptr==_progressBars)
	{
		_progressBars = new cocos2d::Vector<cocos2d::ProgressTimer*>();
	}
	for (unsigned char i=0;i<elementCount;i++)
	{
		auto elemntSprite = Sprite::create(elementPre);
		IF_RETURN_FALSE(!elemntSprite);
	
		w = elemntSprite->getContentSize().width;
		h = elemntSprite->getContentSize().height;
		auto mProgressBar = ProgressTimer::create(elemntSprite);
		IF_RETURN_FALSE(!mProgressBar);
		addChild(mProgressBar);
		_progressBars->pushBack(mProgressBar);
		mProgressBar->setPosition(elemntSprite->getContentSize().width*i,0.0f);
		mProgressBar->setType(ProgressTimer::Type::BAR);
		mProgressBar->setMidpoint(Vec2(0,0));
		mProgressBar->setBarChangeRate(Vec2(1, 0));
	}	

	this->setContentSize(Size(w*elementCount,h));
	//CC_SAFE_RELEASE(baseSprite);
	return true;
}

void ScoreBar::setPercent( unsigned char mPercentage )
{
	unsigned char elementCount = 5;								//the total num of  progress' star
	unsigned char perFull = 100/elementCount;					//per star full percent
	unsigned int per = mPercentage/perFull;						// full star num
	unsigned char remain = (mPercentage%perFull)*elementCount;	//the remain percent
	for(unsigned char i=0;i<_progressBars->size();i++)
	{
		if(i<per)
		_progressBars->at(i)->setPercentage(100);
		else
		_progressBars->at(i)->setPercentage(0);
	}
	if (per<_progressBars->size())
	{
		_progressBars->at(per)->setPercentage(remain);
	}
}

float ScoreBar::getPercent() const
{
	float percent = 0;
	unsigned char elementCount = 5;
	for(auto e:*_progressBars)
	{
		percent+=e->getPercentage();
	}
	return percent/elementCount;
}