cocos2d-X 中实现滚动字幕的效果

cocos2d-X 中实现滚动字幕的效果

许多游戏中都有滚动字幕的效果,例如下图所示

我的实现方法是利用了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 中实现滚动字幕的效果_第1张图片

以上就是cocos2d-X中滚动字幕实现的具体过程。

你可能感兴趣的:(cocos2d-X,游戏,计算机图形学)