我们在玩手机游戏时,常常会看到游戏分数排行榜,这些排行榜在Cocos2d-x中要怎么制作呢?本篇教程将以飞机大战为例带大家制作Cocos2D-X游戏的分数排行榜。
分数排行榜的做法和我在小塔1024中的实现原理是一样的,这里用的是3.0的引擎,所以函数的参数有些许的不同,这里说明俩处需要注意的问题,一个是扩展库的问题,在3.0中扩展的项目是没有引入到工程中的,所以需要自己手动将扩展项目引入进来,这样才能使用TableView,方法请参考3.0回调函数的新用法。另一个问题是实现TableViewDelegate和TableViewDataSource的虚函数时候index参数的类型原来是unsigned int,3.0变成了ssite_t,这里需要注意一下,因为本人就是没有注意这个参数的类型导致出现了莫名其妙的错误,好了,代码如下。
#ifndef _SCORE_SCENE_H_
#define _SCORE_SCENE_H_
#include "cocos2d.h"
//使用tableview必须包含扩展库
#include "cocos-ext.h"
USING_NS_CC;
USING_NS_CC_EXT;
//分数榜场景,使用tableview必须继承以下的类
class ScoreScene : public Layer,public TableViewDataSource,public TableViewDelegate
{
public:
ScoreScene(void);
~ScoreScene(void);
public:
static Scene * createScene();
bool init();
CREATE_FUNC(ScoreScene);
public:
//实现上述接口需要实现的虚函数如下,这里有非常重要的一点就是函数的参数index原来2.x的版本类型为
//unsigned int而现在改为了ssize_t类型,必须写这个类型,用原来的类型会出现错误,本人就是因为这个错误
//耽误了很多的时间
void tableCellTouched(TableView *table,TableViewCell * cell){}; //这里是设置当我们点击每个cell的时候触发的函数,这里我把它置为空的实现,因为我们只是需要读取分数的记录
TableViewCell * tableCellAtIndex(TableView * table,ssize_t index);
Size tableCellSizeForIndex(TableView * table,ssize_t index);
//3.0的返回值有所不同
ssize_t numberOfCellsInTableView(TableView * table);
//继承ScrollViewDelegate接口需要覆写的方法,这里把方法的实现留空
void scrollViewDidScroll(ScrollView * ){};
void scrollViewDidZoom(ScrollView *){};
//对Android返回键的响应
void onKeyReleased(EventKeyboard::KeyCode keyCode,Event * pEvent);
private:
//设备尺寸
Size size;
};
#endif
#include "ScoreScene.h"
ScoreScene::ScoreScene(void)
{
}
ScoreScene::~ScoreScene(void)
{
//在析构函数中移除监听器,这里传递的参数this就是添加监听器到事件分发器中的this
_eventDispatcher->removeEventListenersForTarget(this);
}
Scene * ScoreScene::createScene()
{
auto scene = Scene::create();
auto layer = ScoreScene::create();
scene->addChild(layer);
return scene;
}
bool ScoreScene::init()
{
if(!Layer::init())
return false;
size = Director::getInstance()->getWinSize();
//添加背景图片
auto background = Sprite::createWithSpriteFrameName("background.png");
background->setPosition(Point(size.width/2,size.height/2));
this->addChild(background);
//创建tableView并设置一些参数
auto tableView = TableView::create(this,Size(size.width,size.height*0.6));
//设置滑动方向
tableView->setDirection(ScrollView::Direction::VERTICAL);
//设置TableViewDelegate
tableView->setDelegate(this);
//index的大小是从上到下依次增大
tableView->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
//用当前的配置刷新cell
tableView->reloadData();
this->addChild(tableView);
//排行榜
//排名
auto rankNum = Label::createWithTTF("rank","font/arial.ttf",40);
rankNum->setColor(Color3B(100,100,100));
rankNum->setPosition(Point(size.width*0.4,size.height*0.7));
this->addChild(rankNum);
//得分
auto rankScore = Label::createWithTTF("score","font/arial.ttf",40);
rankScore->setPosition(Point(size.width*0.8,size.height*0.7));
rankScore->setColor(Color3B(100,100,100));
this->addChild(rankScore);
//对用户返回键的响应
auto listener = EventListenerKeyboard::create();
listener->onKeyReleased = CC_CALLBACK_2(ScoreScene::onKeyReleased,this);
_eventDispatcher->addEventListenerWithSceneGraphpriority(listener,this);
return true;
}
//对返回键的响应
void ScoreScene::onKeyReleased(EventKeyboard::KeyCode keyCode,Event * pEvent)
{
if(keyCode == EventKeyboard::KeyCode::KEY_BACKSPACE)
//将开始场景弹出
Director::getInstance()->popScene();
}
//这个函数比较关键,是用来设置每个cell的内容的
TableViewCell * ScoreScene::tableCellAtIndex(TableView * table,ssize_t index)
{
//设置每条记录前边的文本内容
auto index_text = __String::createWithFormat("%ld",index+1);
//dequeuecell这个函数是获得一个可用的cell,因为如果我们没增加一条分数记录就创建一个cell,可想而知如果
//分数记录很多的话,cell不是超级的多了吗,这个时候内存占用就会很大,而这个函数的功能是把那些没有渲染的
//cell拿过来,这样的话就减小了内存的消耗
TableViewCell * cell = table->dequeueCell();
if(cell == NULL)
{
//创建一个cell
cell = new TableViewCell();
cell->autorelease();
//创建显示排名的文本信息
auto text = Label::createWithTTF(index_text->getCString(),"font/arial.ttf",24);
text->setTag(1024);
text->setColor(Color3B(100,100,100));
//文本信息在cell的中间
text->setPosition(Point(size.width*0.4,size.height*0.025));
cell->addChild(text);
//显示用户得分的文本信息
auto index_score = __String::createWithFormat("%d",index);
//根据index值获得得分的文本,因为这个时候的score是int型,所以还需要转化一下类型,这里有点麻烦
int i_score = UserDefault::getInstance()->getIntegerForKey(index_score->getCString());
auto * str = __String::createWithFormat("%d",i_score);
auto score = Label::createWithTTF(
str->getCString(),"font/arial.ttf",24);
score->setTag(2048);
//设置坐标
score->setPosition(Point(size.width*0.8,size.height*0.025));
score->setColor(Color3B(100,100,100));
cell->addChild(score);
}
//这里获得的cell是原来的cell,所以原来cell的文本信息等还是原来的,所以要做一些改变
else
{
//通过tag值获得文本,并且改变,虽然LabelTTF调用setString函数不好,但是这里为了省事就这么用吧
auto text = (Label *)cell->getChildByTag(1024);
text->setString(index_text->getCString());
//改变分数
auto * score = (Label *)cell->getChildByTag(2048);
auto * index_score = __String::createWithFormat("%d",index);
//根据index值获得得分的文本,因为这个时候的score是int型,所以还需要转化一下类型,这里有点麻烦
int i_score = UserDefault::getInstance()->getIntegerForKey(index_score->getCString());
auto * str = __String::createWithFormat("%d",i_score);
score->setString(str->getCString());
if(cell->getChildByTag(100) != NULL)
{
Sprite * sprite = (Sprite *)cell->getChildByTag(100);
sprite->removeFromParentAndCleanup(true);
}
}
if(index == 0 || index==1 || index==2)
{
Sprite * sprite;
switch(index)
{
//代表的是冠军
case 0:
sprite = Sprite::create("gold.png");
break;
case 1:
sprite = Sprite::create("silvere.png");
break;
case 2:
sprite = Sprite::create("tong.png");
break;
}
sprite->setPosition(Point(size.width*0.15,size.height*0.025));
sprite->setTag(100);
cell->addChild(sprite);
}
return cell;
}
//这个函数是用来设置每个cell的大小的
Size ScoreScene::tableCellSizeForIndex(TableView * table,ssize_t index)
{
return Size(size.width,size.height*0.05);
}
//这个函数是用来设置cell的个数的
ssize_t ScoreScene::numberOfCellsInTableView(TableView * table)
{
//个数是从XML文件中读取到的,有多少条记录,就设置多少个cell,如果刚开始没有count这个字段,就返回0
int count = UserDefault::getInstance()->getIntegerForKey("count",0);
return count;
}
然后在开始游戏的场景中添加几个菜单用来选择进入分数榜的场景,代码如下。
//添加一个游戏开始按钮
auto playText = Label::createWithTTF(((__String *)(dictionary->objectForKey("play")))->getCString(),
"font/DFPShaoNvW5-GB.ttf",40);
playText->setColor(Color3B(100,100,100));
auto playMenu = MenuItemLabel::create(playText,CC_CALLBACK_1(StartGame::play,this));
//添加分数榜按钮
auto scoreText = Label::createWithTTF(((__String *)(dictionary->objectForKey("scoreMenu")))->getCString(),
"font/DFPShaoNvW5-GB.ttf",40);
scoreText->setColor(Color3B(100,100,100));
auto scoreMenu = MenuItemLabel::create(scoreText,CC_CALLBACK_1(StartGame::scoreScene,this));
//添加关于作者菜单
auto authorText = Label::createWithTTF(((__String *)(dictionary->objectForKey("aboutMe")))->getCString(),
"font/DFPShaoNvW5-GB.ttf",40);
authorText->setColor(Color3B(100,100,100));
auto authorMenu = MenuItemLabel::create(authorText,CC_CALLBACK_1(StartGame::aboutMe,this));
auto menu = Menu::create(playMenu,scoreMenu,authorMenu,NULL);
menu->alignItemsVerticallyWithPadding(30);
menu->setPosition(size.width/2,size.height*0.3);
this->addChild(menu);
//分数榜响应函数
void StartGame::scoreScene(Ref * ref)
{
Director::getInstance()->pushScene(ScoreScene::createScene());
}
在移植的过程中遇到了一个小问题,提示fatal error: cocos-ext.h: No such file or d irectory,这是因为3.0扩展库是没有作为工程的一部分的,在win32下我们引入了工程extensions,才编译通过的,移植android的过程中,我们需要对mk文件做下修改。如图所示,然后移植,就成功了。
本文摘自http://www.zaojiahua.com/score-rankings.html,并不代表本站立场观点。
上一篇:游戏地图设计的具体创作流程
下一篇:制作游戏教程 游戏制作实例
¥108.00
¥98.00
¥98.00
¥698.00