许多游戏中都有滚动字幕的效果,例如下图所示
我的实现方法是利用了TableView,读取json文件,滚动播放即可。下面是我的配置json文件格式,你也可以根据自己的实际需求进行相应的修改。
about.json
{
"contents": [
{
"title": "Game",
"text": "Thunder"
},
{
"title": "Ver",
"text": "1.0"
},
{
"title": "Client",
"text": "Cocos2d-X Cpp"
},
{
"title": "Server",
"text": "Java Netty"
},
{
"title": "主要研发人员",
"text": "CC 游戏制作组"
},
{
"title": "E-mail",
"text": "[email protected]"
},
{
"title": "GitHub",
"text": "https://github.com/Kiritoken"
},
{
"title": "Phone",
"text": "18225608806"
}
]
}
RollTextLayer.h
#include "cocos2d.h"
#include "extensions/cocos-ext.h"
USING_NS_CC;
USING_NS_CC_EXT;
/*滚动字幕*/
class RollTextLayer : public Layer, public cocos2d::extension::TableViewDataSource, public cocos2d::extension::TableViewDelegate {
public:
static RollTextLayer* createWithJsonFile(const char* fileName, Vec2 position,Size size, float rollingSpeed=50.0f);
bool init(const char* fileName, Vec2 position, Size size, float rollingSpeed);
virtual void update(float dt) override;
//table view
virtual void scrollViewDidScroll(cocos2d::extension::ScrollView* view)override {};
virtual void scrollViewDidZoom(cocos2d::extension::ScrollView* view)override {}
virtual void tableCellTouched(cocos2d::extension::TableView* table, cocos2d::extension::TableViewCell* cell)override;
virtual cocos2d::Size tableCellSizeForIndex(cocos2d::extension::TableView *table, ssize_t idx)override;
virtual cocos2d::extension::TableViewCell* tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx)override;
virtual ssize_t numberOfCellsInTableView(cocos2d::extension::TableView *table)override;
private:
bool loadJsonFile(const char* fileName);
private:
//需要播放的文字
std::vector text;
//滚动速度
float rollingSpeed = 50;
//TableView
TableView* tableView;
//total height
float totalHeight = 0.0f;
};
RollTextLayer.cpp
#include "RollTextLayer.h"
#include "json/rapidjson.h"
#include "json/document.h"
using namespace rapidjson;
USING_NS_CC_EXT;
RollTextLayer * RollTextLayer::createWithJsonFile(const char * fileName, Vec2 position, Size size, float rollingSpeed){
RollTextLayer* rollTextLayer = new RollTextLayer();
if (rollTextLayer && rollTextLayer->init(fileName, position,size, rollingSpeed)) {
rollTextLayer->autorelease();
}
else {
CC_SAFE_DELETE(rollTextLayer);
}
return rollTextLayer;
}
bool RollTextLayer::init(const char * fileName, Vec2 position, Size size, float rollingSpeed){
//载入滚动json文件
if (!loadJsonFile(fileName)) {
return false;
}
//设置tableview
tableView = TableView::create(this, size);
//垂直滚动
tableView->setDirection(ScrollView::Direction::VERTICAL);
tableView->setAnchorPoint(Vec2::ZERO);
tableView->setPosition(position);
tableView->setDelegate(this);
tableView->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
this->addChild(tableView);
tableView->reloadData();
this->rollingSpeed = rollingSpeed;
this->scheduleUpdate();
return true;
}
//点击cell
void RollTextLayer::tableCellTouched(TableView* table, TableViewCell* cell){
CCLOG("cell touched at index: %ld", static_cast(cell->getIdx()));
}
//cell大小
Size RollTextLayer::tableCellSizeForIndex(TableView *table, ssize_t idx){
return Size(60, 50);
}
TableViewCell* RollTextLayer::tableCellAtIndex(TableView *table, ssize_t idx){
TableViewCell *cell = table->dequeueCell();
//首次初始化
if (!cell) {
cell = new (std::nothrow) TableViewCell();
cell->autorelease();
float fontSize = 20.0f;
auto label = Label::createWithSystemFont(text[idx], "Helvetica",fontSize);
label->setAlignment(CCTextAlignment::CENTER);
label->setPosition(Vec2::ZERO);
label->setAnchorPoint(Vec2::ZERO);
label->setTag(123);
cell->addChild(label);
}
//重新计算
else{
auto label = (Label*)cell->getChildByTag(123);
label->setString(text[idx]);
}
return cell;
}
//cell数量
ssize_t RollTextLayer::numberOfCellsInTableView(TableView *table){
//返回字幕
return text.size();
}
//读取json 字幕文件 并保存至vector中
bool RollTextLayer::loadJsonFile(const char * fileName){
auto content = FileUtils::getInstance()->getStringFromFile(fileName);
Document doc;
doc.Parse<0>(content.c_str(), content.size());
//解析错误
if (doc.HasParseError()) {
log("ParseError");
return false;
}
else {
log("Parse correct");
}
text.clear();
if (!doc.HasMember("contents")) {
log("json格式不正确");
return false;
}
else {
rapidjson::Value& res = doc["contents"];
if (res.IsArray()) {
for (SizeType i = 0; i < res.Size(); i++) {
rapidjson::Value& d = res[i];
if (d.HasMember("title") && d.HasMember("text")) {
text.push_back(d["title"].GetString());
text.push_back(d["text"].GetString());
log("%s %s", d["title"].GetString(), d["text"].GetString());
}
}
}
}
return true;
}
//滚动
void RollTextLayer::update(float dt){
tableView->setContentOffset(tableView->getContentOffset() + Vec2(0, rollingSpeed*dt));
if (tableView->getContentOffset().y>numberOfCellsInTableView(tableView)*tableCellSizeForIndex(tableView, text.size() - 1).height) {
log("over");
tableView->reloadData();
}
}
以上就是cocos2d-X中滚动字幕实现的具体过程。