Cocos2D-X入门之制作分数排行榜

    作者:课课家教育更新于: 2016-04-15 16:23:30

      我们在玩手机游戏时,常常会看到游戏分数排行榜,这些排行榜在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());

      }

    Cocos2D-X入门之制作分数排行榜_Cocos2D-X分数_Cocos2D-X教程_Cocos2D-X游戏开发_课课家

      在移植的过程中遇到了一个小问题,提示fatal error: cocos-ext.h: No such file or d irectory,这是因为3.0扩展库是没有作为工程的一部分的,在win32下我们引入了工程extensions,才编译通过的,移植android的过程中,我们需要对mk文件做下修改。如图所示,然后移植,就成功了。

      本文摘自http://www.zaojiahua.com/score-rankings.html,并不代表本站立场观点。

课课家教育

未登录