今天我们介绍最后两个类

GameOverLayer类

GameLayer类

GameLayer类是整个游戏中最重要的类,由于是整个游戏的中央系统,控制着各个类(层)之间的交互,这个类中实现了猪脚小鸟和它的敌人(管道和草地- . -)碰撞检測。说道物理引擎的碰撞检測。我也是第一次接触。也没多大难度。就直接调用了cocos2d-x的接口。这个类就是游戏的主场景,游戏就是在这里进行的。

GameOverLayer类。游戏结束后一些分数的显示。还有就是奖牌的实现(楼主写的非常easy......),这边比較有意思的就是加分效果的实现。这个楼主曾经在写AS3的时候经经常使用到。最后就是两个button。一个又一次開始button,一个排名button。排名button没有写功能,这个要跟手机的游戏中心配合。这边放一张游戏结束后的图片:

差点儿相同了。这个游戏全部的类都介绍的差点儿相同了。游戏的源代码和图片:

http://download.csdn.net/detail/u011373759/7941891

以下是这两个类的源代码分析,谢谢大家,结束

  1. //GameOverLayer.h
  2. #pragma once
  3. #include "cocos2d.h"
  4.  
  5. class GameOverLayer:public cocos2d::Layer
  6. {
  7. public:
  8. GameOverLayer();
  9. ~GameOverLayer();
  10. bool init();
  11. //回调函数
  12. void callBack();
  13. //再来一次
  14. void gameAgain();
  15. //获取排名
  16. void getRank();
  17. //显示分数
  18. void showScore(float);
  19. CREATE_FUNC(GameOverLayer);
  20. private:
  21. //计分板精灵
  22. cocos2d::Sprite * box;
  23. //终于分数label
  24. cocos2d::Label * numberLabel;
  25. int score;
  26. int highScore;
  27. };
  1. //GameOverLayer.cpp
  2. #include "GameOverLayer.h"
  3. #include "define.h"
  4. #include "GameLayer.h"
  5. #include "NumberLayer.h"
  6. #include "GetLocalScore.h"
  7. USING_NS_CC;
  8.  
  9. GameOverLayer::GameOverLayer()
  10. {
  11.  
  12. }
  13.  
  14. GameOverLayer::~GameOverLayer()
  15. {
  16. }
  17.  
  18. bool GameOverLayer::init()
  19. {
  20. if (!Layer::init())
  21. {
  22. return false;
  23. }
  24. auto origin=Director::getInstance()->getVisibleOrigin();
  25. auto visibleSize=Director::getInstance()->getVisibleSize();
  26.  
  27. //历史最高分
  28. highScore=GetLocalScore::getInstance()->getHighScore();
  29.  
  30. //计分板
  31. box=Sprite::createWithSpriteFrameName("score_panel.png");
  32. box->setPosition(Point(origin.x+visibleSize.width/2,origin.y-visibleSize.height/2));
  33. this->addChild(box);
  34.  
  35. //游戏结束后,计分板要从屏幕底部向上运动出现
  36. //动画结束后要显示分数和两个button(在回调函数里)
  37. auto moveto=MoveTo::create(SCORECARD_SHOW_TIME,Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height*0.5));
  38. auto callback=CallFuncN::create(CC_CALLBACK_0(GameOverLayer::callBack,this));
  39. auto sequence=Sequence::create(moveto,callback,NULL);
  40. box->runAction(sequence);
  41. //动画的声音
  42. CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sounds/sfx_swooshing.mp3");
  43.  
  44. //gameover 字
  45. auto gameover=Sprite::createWithSpriteFrameName("text_game_over.png");
  46. gameover->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height+gameover->getContentSize().height/2));
  47.  
  48. //gameover精灵也要运行同样的动画,只是它是从上到下运动
  49. auto moveto2=MoveTo::create(SCORECARD_SHOW_TIME,Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height*0.7));
  50.  
  51. gameover->runAction(moveto2);
  52.  
  53. this->addChild(gameover);
  54.  
  55. return true;
  56. }
  57.  
  58. void GameOverLayer::callBack()
  59. {
  60. log("callback");
  61. auto origin=Director::getInstance()->getVisibleOrigin();
  62. auto visibleSize=Director::getInstance()->getVisibleSize();
  63.  
  64. //排名和再来一次button
  65. //计分板和gameover精灵运行完动画后,出现button
  66. auto again=Sprite::createWithSpriteFrameName("button_play.png");
  67. auto menuAgain=MenuItemSprite::create(again,again,CC_CALLBACK_0(GameOverLayer::gameAgain,this));
  68.  
  69. auto rank=Sprite::createWithSpriteFrameName("button_score.png");
  70. auto menuRank=MenuItemSprite::create(rank,rank,CC_CALLBACK_0(GameOverLayer::getRank,this));
  71.  
  72. //两个button坐标的设定
  73. int l=(visibleSize.width-again->getContentSize().width*2)/3;
  74.  
  75. menuAgain->setPosition(Point(origin.x+l+again->getContentSize().width/2,origin.y+visibleSize.height*0.3));
  76. menuRank->setPosition(Point(origin.x+visibleSize.width-l-again->getContentSize().width/2,origin.y+visibleSize.height*0.3));
  77.  
  78. //把button放到菜单中去
  79. auto menu=Menu::create(menuAgain,menuRank,NULL);
  80. menu->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
  81. menu->setPosition(Point::ZERO);
  82.  
  83. this->addChild(menu);
  84.  
  85. //分数显示
  86. score=0;
  87. auto str=__String::createWithFormat("%d",score);
  88. numberLabel=Label::createWithBMFont("font2.fnt",str->getCString());
  89. numberLabel->setPosition(Point(origin.x+visibleSize.width/2+65,origin.y+visibleSize.height*0.5+10));
  90. this->addChild(numberLabel);
  91.  
  92. //当分数大于0时运行一个分数从0到n的动画
  93. if (NumberLayer::getInstance()->getScore()>0)
  94. {
  95. this->schedule(schedule_selector(GameOverLayer::showScore),ADDSCORE_FRE);
  96. }
  97.  
  98. //历史最高分
  99. auto str1=__String::createWithFormat("%d",highScore);
  100. auto highScoreLabel=Label::createWithBMFont("font2.fnt",str1->getCString());
  101. highScoreLabel->setPosition(Point(origin.x+visibleSize.width/2+65,origin.y+visibleSize.height*0.5-30));
  102. this->addChild(highScoreLabel);
  103.  
  104. //假设当前分数大于历史最高分。则会出现new的字样
  105. if (NumberLayer::getInstance()->getScore()>highScore)
  106. {
  107. GetLocalScore::getInstance()->setHighScore(NumberLayer::getInstance()->getScore());
  108. auto picNew=Sprite::createWithSpriteFrameName("new.png");
  109. picNew->setPosition(Point(origin.x+visibleSize.width/2+37,origin.y+visibleSize.height*0.5-4));
  110. this->addChild(picNew);
  111. }
  112.  
  113. //奖牌显示
  114. //这边的奖牌显示是自己定的
  115. //各个奖牌之间要达到多少分数请看define.h
  116. int l2=(visibleSize.width-box->getContentSize().width)/2;
  117. if (NumberLayer::getInstance()->getScore()<MEDALS_0)
  118. {
  119. return;
  120. }
  121. Sprite * medals;
  122. if (NumberLayer::getInstance()->getScore()>=MEDALS_0&&NumberLayer::getInstance()->getScore()<MEDALS_1)
  123. {
  124. medals=Sprite::createWithSpriteFrameName("medals_0.png");
  125.  
  126. }
  127. if (NumberLayer::getInstance()->getScore()>=MEDALS_1&&NumberLayer::getInstance()->getScore()<MEDALS_2)
  128. {
  129. medals=Sprite::createWithSpriteFrameName("medals_1.png");
  130. }
  131. if (NumberLayer::getInstance()->getScore()>=MEDALS_2&&NumberLayer::getInstance()->getScore()<MEDALS_3)
  132. {
  133. medals=Sprite::createWithSpriteFrameName("medals_2.png");
  134. }
  135. if (NumberLayer::getInstance()->getScore()>=MEDALS_3)
  136. {
  137. medals=Sprite::createWithSpriteFrameName("medals_3.png");
  138. }
  139. medals->setPosition(Point(origin.x+l2+54,origin.y+visibleSize.height*0.49));
  140. this->addChild(medals);
  141. }
  142.  
  143. //再来一次。场景切换
  144. void GameOverLayer::gameAgain()
  145. {
  146. Director::getInstance()->replaceScene(TransitionFade::create(CHANGESCENE_TIME,GameLayer::createScene()));
  147. }
  148.  
  149. //排名button的回调。这里没写,由于这里要调用的是手机游戏中心的资料
  150. void GameOverLayer::getRank()
  151. {
  152. log("get rank");
  153. }
  154.  
  155. //分数显示动画
  156. void GameOverLayer::showScore( float )
  157. {
  158. score++;
  159. auto str=__String::createWithFormat("%d",score);
  160. numberLabel->setString(str->getCString());
  161. if (score==NumberLayer::getInstance()->getScore())
  162. {
  163. this->unschedule(schedule_selector(GameOverLayer::showScore));
  164. }
  165. }
  1. //GameLayer.h
  2. #pragma once
  3. #include "cocos2d.h"
  4. #include "SpriteBird.h"
  5.  
  6. class GameLayer:public cocos2d::Layer
  7. {
  8. public:
  9. GameLayer();
  10. ~GameLayer();
  11. static cocos2d::Scene * createScene();
  12. bool init();
  13. //游戏開始
  14. void startGame();
  15. CREATE_FUNC(GameLayer);
  16. private:
  17. //猪脚层
  18. SpriteBird * bird;
  19. //物理碰撞侦听
  20. cocos2d::EventListenerPhysicsContact * contactListener;
  21. };
  1. //GameLayer.cpp
  2. #include "GameLayer.h"
  3. #include "define.h"
  4. #include "HelpLayer.h"
  5. #include "PipeLayer.h"
  6. #include "LandLayer.h"
  7. #include "NumberLayer.h"
  8. #include "GameOverLayer.h"
  9. USING_NS_CC;
  10. GameLayer::GameLayer()
  11. {
  12. }
  13.  
  14. GameLayer::~GameLayer()
  15. {
  16. }
  17.  
  18. cocos2d::Scene * GameLayer::createScene()
  19. {
  20. //注意我们这边创造的是物理场景
  21. auto scene=Scene::createWithPhysics();
  22. //增加了重力。GRAVITY的值为(0,-980)
  23. //跟我们的世界重力加速度是一样的,比較真实
  24. scene->getPhysicsWorld()->setGravity(GRAVITY);
  25. auto gameLayer=GameLayer::create();
  26. scene->addChild(gameLayer);
  27. return scene;
  28. }
  29.  
  30. bool GameLayer::init()
  31. {
  32. if (!Layer::init())
  33. {
  34. return false;
  35. }
  36.  
  37. auto origin=Director::getInstance()->getVisibleOrigin();
  38. auto visibleSize=Director::getInstance()->getVisibleSize();
  39.  
  40. //背景图片。依据时间载入晚上和白天的图片
  41. time_t t=time(NULL);
  42. tm * lt=localtime(&t);
  43. int hour=lt->tm_hour;
  44.  
  45. Sprite * bg;
  46.  
  47. if (hour>=6&&hour<=17)
  48. {
  49. bg=Sprite::createWithSpriteFrameName("bg_day.png");
  50. }
  51. else
  52. {
  53. bg=Sprite::createWithSpriteFrameName("bg_night.png");
  54. }
  55.  
  56. bg->setPosition(Point(origin.x+visibleSize.width/2,origin.y+visibleSize.height/2));
  57. this->addChild(bg);
  58.  
  59. //以下就是我们前几章讲的各个类的实例的运用了
  60. //这个游戏就像贴纸一样,一层一层叠起来,各层运行各层的逻辑
  61. //靠这个游戏层来控制各层的之间的交互
  62.  
  63. //草底层
  64. auto landLayer=LandLayer::create();
  65. landLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
  66. landLayer->setPosition(Point::ZERO);
  67. this->addChild(landLayer,2);
  68.  
  69. //帮助界面
  70. auto helpLayer=HelpLayer::create();
  71. helpLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
  72. helpLayer->setPosition(Point::ZERO);
  73. this->addChild(helpLayer);
  74.  
  75. //管子层
  76. auto pipeLayer=PipeLayer::create();
  77. pipeLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
  78. pipeLayer->setPosition(Point::ZERO);
  79. this->addChild(pipeLayer,1);
  80.  
  81. //主角
  82. bird=SpriteBird::createBird();
  83. bird->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
  84. bird->setPosition(Point::ZERO);
  85. this->addChild(bird,2);
  86.  
  87. bird->changeState(ACTION_STATE_IDLE);
  88.  
  89. //这里创建了触控侦听
  90. //当玩家点击屏幕时,游戏開始。并移除这个侦听
  91. auto listener=EventListenerTouchOneByOne::create();
  92. listener->setSwallowTouches(false);
  93. listener->onTouchBegan=[=](Touch * t,Event * e)
  94. {
  95. log("GameLayer touch begin");
  96.  
  97. return true;
  98. };
  99. listener->onTouchEnded=[=](Touch * t,Event * e)
  100. {
  101. pipeLayer->startPipe();
  102. startGame();
  103.  
  104. _eventDispatcher->removeEventListener(listener);
  105. };
  106.  
  107. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
  108.  
  109. //碰撞检測侦听
  110. contactListener=EventListenerPhysicsContact::create();
  111. contactListener->onContactBegin=[=](const PhysicsContact& contact)
  112. {
  113. log("1111111111111111111111111");
  114. //当检測到碰撞的时候,播放hit声音
  115. //小鸟要么撞到草地,要么撞到管道
  116. CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("sounds/sfx_hit.mp3");
  117. //管道停止运动
  118. pipeLayer->stopPipe();
  119. //草地停止运动
  120. landLayer->stopLand();
  121. //小鸟改变状态
  122. bird->changeState(ACTION_STATE_DIE);
  123. //移除积分器
  124. this->removeChild(NumberLayer::getInstance());
  125.  
  126. //游戏结束后计分板出现
  127. auto scorecard=GameOverLayer::create();
  128. scorecard->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
  129. scorecard->setPosition(Point::ZERO);
  130. this->addChild(scorecard,99);
  131.  
  132. _eventDispatcher->removeEventListener(contactListener);
  133. return true;
  134. };
  135.  
  136. _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,this);
  137.  
  138. return true;
  139. }
  140.  
  141. void GameLayer::startGame()
  142. {
  143. //游戏開始,小鸟转换到飞行状态
  144. bird->changeState(ACTION_STATE_FLY);
  145. //增加积分器并初始化
  146. NumberLayer::getInstance()->initScore();
  147. this->addChild(NumberLayer::getInstance(),10);
  148.  
  149. }

cocos2d-x v3.2 FlappyBird 各个类对象详细代码分析(7)的更多相关文章

  1. cocos2d-x v3.2 FlappyBird 各个类对象详细代码分析(6)

    今天我们要讲三个类,这三个类应该算比較简单的 HelpLayer类 NumberLayer类 GetLocalScore类 HelpLayer类,主要放了两个图形精灵上去,一个是游戏的名字,一个是提示 ...

  2. C++ 类对象内存模型分析

    编译环境:Windows10 + VS2015 1.空类占用的内存空间 类占内存空间是只类实例化后占用内存空间的大小,类本身是不会占内存空间的.用sizeof计算类的大小时,实际上是计算该类实例化后对 ...

  3. Android开发之dp转像素,像素转换为dp工具类,详细代码,带有源文件下载地址。

    import android.content.Context; /** * @author 官网:http://blog.csdn.net/qq_21376985 * * David编写: 微博:ht ...

  4. C++派生类中如何初始化基类对象(五段代码)

    今天收到盛大的面试,问我一个问题,关于派生类中如何初始化基类对象,我在想派生类对于构造函数不都是先构造基类对象,然后在构造子类对象,但是如果我们在成员初始化列表先初始化派生类的私有成员,在函数内去调用 ...

  5. C++ 类对象和 指针的区别

    C++ 类对象和 指针的区别 C++ 类对象和 指针的区别 转自:http://blog.csdn.net/ym19860303/article/details/8557746 指针的情况 class ...

  6. Android 通过 Intent 传递类对象或list对象

    (转:http://www.cnblogs.com/shaocm/archive/2013/01/08/2851248.html) Android中Intent传递类对象提供了两种方式一种是 通过实现 ...

  7. NSLog(@"%@",类对象); 默认输出类名

    NSLog()函数输出Objective-c对象时,输出的是该对象的description方法的返回值.也就是说,以下两行代码作用完全一样(假设p是指向任何对象的指针变量). NSLog(@" ...

  8. WPF整理-XAML构建后台类对象

    1.XAML 接触WPF的第一眼就是XAML---XAML是用来描绘界面的.其实不然! "Actually, XAML has nothing to do with UI. It's mer ...

  9. class中new与未new的区别 类对象占用空间--转载

    转载自http://blog.sina.com.cn/shuiwuhendeboke    颗颗的博客 (1)作用域不同 不用new:作用域限制在定义类对象的方法中,当方法结束时,类对象也被系统释放了 ...

随机推荐

  1. Wcf+EF框架搭建实例

    一.最近在使用Wcf创建数据服务,但是在和EF框架搭建数据访问时遇到了许多问题 下面是目前整理的基本框架代码,经供参考使用,源代码地址:http://git.oschina.net/tiama3798 ...

  2. oracle登陆连接的问题

    一.登陆 1.使用客户端 直接在database中配置: IP:1521/orcl 其中IP为要连接的IP 其中1521为要连接的数据库的端口 其中orcl为要连接的数据库的实例名字 2.使用命令行 ...

  3. oracle 使用 ALTER 操作列

    使用 ALTER TABLE 语句追加, 修改, 或删除列的语法

  4. 武汉科技大学ACM:1003: 华科版C语言程序设计教程(第二版)例题6.6.改编

    Problem Description 小明明最喜欢学英语了,英语课从来不翘课,但是英语却一直没学好,因为上课一直在睡觉.为什么会睡觉呢,因为他觉得英文单词太长了.现在小明明有一个很长很长很长的单词, ...

  5. 如何修改WAMP中mysql默认空密码&重新登录phpmyadmin

    WAMP安装好后,mysql密码是为空的,那么要如何修改呢?其实很简单,通过几条指令就行了,下面我就一步步来操作. 首先,通过WAMP打开mysql控制台. 提示输入密码,因为现在是空,所以直接按回车 ...

  6. php cgi 与 cli 区别

    以CGI方式运行时,web server将用户请求以消息的方式转交给PHP独立进程,PHP与web服务之间无从属关系:CLI则是命令行接口,用于在操作系统命令行模式下执行PHP,比如可以直接在win的 ...

  7. vim编辑器中撤销和恢复操作

    在VIM编辑器下切换至命令行模式: 撤销: u 恢复: ctrl + r

  8. .SO 出现 undefined reference

    查看本SO文件依赖哪些其他的SO文件: readelf -d ldd undefined reference 涉及的问题是  主程序及静态库不能定位地址 undefined symbol 说的问题是动 ...

  9. Win10使用小技巧

    Win10技巧4.命令行支持Ctrl+V 这项功能使用的人不多,但绝对是跨时代的,因为你终于可以放心大胆地在命令提示符里使用Ctrl+V来粘贴剪贴板内容了.而在此之前,Ctrl+V换来的结果只是一个^ ...

  10. jQueryMobile之弹出对话框

    1:dialog-test.html <!DOCTYPE html> <html lang="en"> <head> <meta char ...